PowerShell-Skript für Systemadministratoren zum regelmäßigen Herunterladen von Backups vom Server auf den Computer

Kürzlich stieß eine Freundin von mir auf das Problem, dass der VPS-Anbieter plötzlich und ohne Vorwarnung den Geschäftsbetrieb einstellte. Leider wählte sie aus Kostengründen einen Nischenanbieter – einen, der nicht einmal das Herunterladen von Daten anbot. Schlimmer noch, sie hat nicht die Gewohnheit, regelmäßig Backups herunterzuladen. Über Nacht verschwand ihre Website zusammen mit allen darauf befindlichen Daten.

Schockiert darüber schrieb ich ein Powershell-Skript, das automatisch regelmäßig Backups von Ihrem Server auf Ihren lokalen Computer herunterlädt, ohne dass Sie zusätzliche Objektspeicher-Dienste kaufen oder einen Cent für andere Dinge ausgeben müssen. Alles, was Sie brauchen, ist ein Windows-Computer, den Sie regelmäßig benutzen (und der über viel Festplattenspeicher verfügt) und der mit dem Internet verbunden ist.

Das Skript bereinigt automatisch Backups, die älter als 5 Tage sind. Sie können das automatische Backup-Intervall und die älteste lokal gespeicherte Backup-Zeit nach Ihren Bedürfnissen einstellen.


$ssh_port = 22
$ssh_address = "username@your.site"


Write-Output "Starte Discourse-Backup-Download-Aufgabe..."
Write-Output "------------------------"
Write-Output "Rufe die neueste Backup-Datei ab..."
Write-Output ""

while ($true) {

    $filename = ''

    while ($true) {
        try {
            Write-Output "> ssh -p $ssh_port $ssh_address 'cd /var/discourse/shared/standalone/backups/default/ && ls -t | head -n 1'"
            Write-Output ""
            $filename = ssh -p $ssh_port "$ssh_address" 'cd /var/discourse/shared/standalone/backups/default/ && ls -t | head -n 1'
            break
        }
        catch {
            $filename = ''

            Write-Output "Fehler beim Abrufen... Hier ist das Protokoll:"
            Write-Output "-------------"
            Write-Output $_

            $answer = Read-Host "Möchten Sie es erneut abrufen? (j/N)"
            if ($answer -ne 'j') {
                break
            }
            Write-Output ""
        }
    }


    if ([String]::IsNullOrEmpty($filename)) {
        Write-Output "Fehler: Konnte Dateiname $filename nicht abrufen"
        Write-Output ""
        $answer = Read-Host 'Erneut versuchen? (j/N)'

        if ($answer -eq 'j') {

        }
        else {

            exit 1
        }

    }
    else {

        Write-Output "Neuestes Backup: $filename"
        Write-Output ""

        $need_download = $true
        if (Test-Path ".\backups\$filename") {
            $answer = Read-Host ".\backups\$filename existiert bereits. Möchten Sie es erneut herunterladen? (j/N)"
            Write-Output ""
            if ($answer -ne 'j') {
                $need_download = $false
            }
        }
        if ($need_download) {
            Write-Output "Starte Download..."
            Write-Output ""

            while ($true) {
                try {
                    Write-Output "scp -p $ssh_port ${ssh_address}:/var/discourse/shared/standalone/backups/default/$filename .\\backups\\"
                    Write-Output ""

                    scp -p $ssh_port "${ssh_address}:/var/discourse/shared/standalone/backups/default/$filename" .\\backups\

                    Write-Output "Download abgeschlossen"
                    Write-Output ""

                    break
                }
                catch {

                    Write-Output "Download fehlgeschlagen >_<... Das Folgende ist das Protokoll:"
                    Write-Output ""

                    Write-Output $_

                    $answer = Read-Host "Nochmal herunterladen? (j/N)"
                    Write-Output ""
                    if ($answer -ne 'j') {
                        break
                    }
                }
            }

        }

        Write-Output "Starte Versuch, alte Backup-Dateien zu bereinigen..."
        Write-Output ""

        $count = 0
        $backupfiles = Get-ChildItem -Path .\\backups\

        foreach ($file in $backupfiles) {
            if ($file.CreationTime -le (Get-Date).AddDays(-5)) {
                try {
                    Write-Output "Lösche alte Backup-Datei $file ..."
                    Write-Output ""
                    $file.Delete()
                    $count = $count + 1
                } catch {
                    Write-Output "Ein Fehler ist beim Löschen der alten Backup-Datei $file aufgetreten >_<"
                    Write-Output "-------------------"
                    Write-Output $_
                    Write-Output "-------------------"
                }
            }
        }

        if ($count -ge 0) {
            Write-Output "$count alte Backup-Dateien bereinigt"
            Write-Output ""
        }
        else {
            Write-Output "Keine alten Backup-Dateien müssen bereinigt werden"
            Write-Output ""
        }

        Pause

        exit 0


    }


}


Speichern Sie das obige Skript als scriptname.ps1 an dem Ort, an dem Sie das Backup herunterladen möchten. Versuchen Sie es mit “Mit Powershell ausführen”. Wenn erfolgreich, können Sie mit dem nächsten Schritt fortfahren.

Aufgabenplanung

  1. Suchen Sie nach “Geplante Tasks”.
  2. Doppelklicken Sie auf Geplanten Task hinzufügen. Der Assistent für geplante Tasks wird angezeigt.
  3. Klicken Sie auf Weiter und dann auf Durchsuchen. Das Dialogfeld Programm zur Planung auswählen wird angezeigt.
  4. Navigieren Sie zu dem von Ihnen erstellten Skript, klicken Sie darauf und dann auf Öffnen. Sie kehren zum Assistenten für geplante Tasks zurück.
  5. Geben Sie einen Namen für den Task ein oder behalten Sie den Standardnamen, der der Dateiname ist, und geben Sie an, wie oft das Skript ausgeführt werden soll, und klicken Sie dann auf Weiter.
  6. Geben Sie die Startzeit und das Startdatum (wenn Sie Täglich, Wöchentlich oder Monatlich usw. angegeben haben) und die Wiederholung an und klicken Sie dann auf Weiter. Dieser Punkt sollte dem automatischen Backup-Zyklus Ihres Discourse entsprechen
  7. Geben Sie den Benutzernamen und das Kennwort für das Konto ein, das das Skript ausführen wird, und klicken Sie dann auf Weiter.
  8. Wenn Sie erweiterte Eigenschaften konfigurieren möchten, wählen Sie das Kontrollkästchen aus und klicken Sie dann auf Fertig stellen.
15 „Gefällt mir“

Eine gute Erinnerung daran, wie wichtig Remote-Backups sind. Ein anderer Meta-Benutzer hatte vor einigen Monaten dasselbe Problem.

Eine meiner Instanzen nutzt die integrierte S3-Backup-Funktion, die anderen nutzen Rclone und eine CRON-Aufgabe, um Backups auf Google Drive zu senden. Hierfür gibt es eine Anleitung: Use rclone to sync backups to Dropbox or Google Drive

Danke fürs Teilen deines Skripts, Linca :+1:

3 „Gefällt mir“

In der Tat eine sehr gute Erinnerung. Ich habe vorgeschlagen (hier), dass die Update-Funktion prüfen und warnen könnte, wenn die Sicherungsdateien last-accessed-times haben, die zu weit in der Vergangenheit liegen. Wir aktualisieren alle zwei bis drei Monate, sodass diese Prüfung nicht zu oft ausgeführt würde, und die Zeit eines Updates ist ein guter Zeitpunkt, um sicherzustellen, dass eine sichere Sicherung vorhanden ist. Jede Methode zum Kopieren einer Sicherungsdatei an einen anderen Ort sollte den last-accessed-Zeitstempel aktualisieren.

3 „Gefällt mir“

Guter Punkt, danke für das Skript. Lassen Sie mich die rsync-Version teilen :slight_smile: .

Im folgenden Beispiel werden SQL und Anhänge separat synchronisiert. Es ist nicht notwendig, Anhänge in die Sicherungsdatei aufzunehmen. Alte Sicherungen müssen ebenfalls nicht gelöscht werden.

Ich verwende Chocolatey, um cwrsync zu installieren. Nach der Installation müssen nur noch einige Zeilen am Ende der CMD-Datei hinzugefügt und ein Zeitplan erstellt werden:

C:\ProgramData\chocolatey\lib\rsync\tools\cwrsync.cmd

Zum Beispiel:

rsync -rvm --delete --ignore-errors --ignore-existing --size-only --chmod=ugo=rwX -e "ssh -i /cygdrive/c/Users/user1/.ssh/id_rsa" login@host:/var/discourse/shared/standalone/backups/default/ /cygdrive/d/backup/forum/db/

rsync -rvm --delete --ignore-errors --ignore-existing --size-only --chmod=ugo=rwX -e "ssh -i /cygdrive/c/Users/user1/.ssh/id_rsa" login@host:/var/discourse/shared/standalone/uploads/ /cygdrive/d/backup/forum/uploads/

Hinweis 1: Verwenden Sie /cygdrive/c/ anstelle von C:, lesen Sie die CMD-Datei als Referenz und für die Syntax.

Hinweis 2: Sie können den Befehl ändern, um ein Passwort anstelle eines SSH-Schlüssels (PEM-Format) zu verwenden.

Hinweis 3: Wenn Sie nach dem Dump-Ordner keinen Schrägstrich setzen, kopiert rsync den Ordner. Wenn Sie ihn jedoch setzen, kopiert er nur den Inhalt des Ordners.

Hinweis 4: Wenn Chocolatey cwrsync aktualisiert, erstellt es eine Sicherung der vorherigen CMD-Datei im selben Ordner. Sie müssen Ihre Befehle manuell in die neue CMD kopieren, um die Sicherungen fortzusetzen.

Wichtig: Legen Sie dieselbe Regel im Scheduler fest, wie der OP geschrieben hat. Die Scheduler-Zeile lautet:

C:\ProgramData\chocolatey\lib\rsync\tools\cwrsync.cmd >> d:\backup\cwrsync.txt 2>&1

Dadurch wird die Ausgabe an die Datei cwrsync.txt angehängt. Das ist alles.

3 „Gefällt mir“

Ich habe die Angewohnheit, rclone so einzurichten, dass die Backups automatisch auf ein Remote-Ziel (ein selbst gehostetes NAS zu Hause) kopiert werden, gerade wegen dieser Art von Dingen, die unerwartet passieren können. Dieser Beitrag dient sehr gut als Erinnerung daran, dass wir nicht alle Eier in einen Korb legen sollten.

5 „Gefällt mir“

Während Sie dabei sind, sollten Sie auch eine Kopie von allem in /var/discourse/containers erhalten.

4 „Gefällt mir“

Gute Idee! Werde ein Update bereitstellen

3 „Gefällt mir“

Wo soll ich nach „Geplante Tasks“ suchen? (Neuling bittet um Hilfe, danke)

„Geplante Tasks“ ist der Taskplaner, ab Windows 10 können Sie ihn direkt durch Drücken der Windows-Taste und Eingabe suchen.

2 „Gefällt mir“

Hallo. Wie kommt es, dass ich diese Fehlermeldung erhalte?

Für alle, die dies lesen: Hier sind bessere/aktuellere Anweisungen, da ich mit den Anweisungen des OP leicht zu kämpfen hatte:

  1. Erstellen/verwenden Sie einen Ordner, in dem dieses Skript gespeichert wird. Erstellen Sie dann innerhalb dieses Ordners einen Ordner namens backup.

  2. Kopieren/fügen Sie das Skript in Notepad ein. HINWEIS: Wenn Sie einen VPS verwenden, verwenden Sie den Benutzernamen Ihres VPS und die öffentliche IP-Adresse für die Zeile $ssh_address = \"username@your.site\". Speichern Sie als anyname.ps1 und vergessen Sie nicht, die Dropdown-Box auf “Alle Dateien” zu setzen, wie unten gezeigt.
    hhhh

  3. Drücken Sie die Windows-Taste ⊞ und geben Sie “Aufgaben” ein, dann klicken Sie auf “Aufgabenplanung”.

  4. Klicken Sie auf der rechten Seite auf “Einfache Aufgabe erstellen”.

  5. Geben Sie einen beliebigen Namen/eine beliebige Beschreibung ein.

  6. Wählen Sie, ob Sie täglich/wöchentlich/jährlich usw. möchten. Ich empfehle täglich.

  7. Stellen Sie das Datum und die Uhrzeit ein, zu der Sie dies tun möchten. Behalten Sie “Wiederholen” bei 1. Stellen Sie sicher, dass Sie zu den Admin-Einstellungen Ihrer Discourse-Site gehen > Backups. Aktivieren Sie das Kontrollkästchen neben automatische Backups aktiviert.
    Stellen Sie dann Backup-Häufigkeit auf das gewünschte Intervall ein. Ich empfehle 1, aber der Schlüssel hier ist, dass es mit Ihren Aufgabenplaner-Einstellungen übereinstimmt. Lassen Sie die Backup-Daten übereinstimmen. Beispiel: Wenn Sie den Aufgabenplaner so eingestellt haben, dass er täglich ein Backup erstellt, stellen Sie Ihre Admin-Backup-Backup-Häufigkeit-Einstellungen auf 1.

  8. Lassen Sie die Standardeinstellung “Ein Programm starten” und klicken Sie auf Weiter.

  9. Klicken Sie auf Durchsuchen und finden Sie das gespeicherte Skript. Klicken Sie auf Weiter.

  10. Klicken Sie auf Fertig stellen.
    Wenn Sie es testen möchten, klicken Sie mit der rechten Maustaste auf das Skript und wählen Sie “Mit PowerShell ausführen”.

Hinweis: Wenn Sie die Meldung “Die angegebene Datei wurde nicht gefunden” erhalten, geben Sie Ihr Passwort wie in PowerShell angezeigt ein, und es wird trotzdem gefunden.

1 „Gefällt mir“

Wenn ich das PS-Skript speichere (habe nur meinen Benutzernamen und meine IP-Adresse in die 2. Zeile editiert) und dann Rechtsklick > Mit PowerShell ausführen mache, passiert nichts.
Ein Blitz geschieht. Und wenn ich bereits ein Terminal in meinem Win11 geöffnet habe, dann wird dieses Terminal nach vorne gebracht. Sonst nichts. Nur ein Blitz.

Ich habe mich gefragt, obwohl ich meinen Benutzernamen und meine IP-Adresse dem Skript gegeben habe, wie es meinen SSH-Schlüssel verwenden würde, um sich anzumelden und das Backup abzurufen?

Danke.!

Ich habe sowohl die Lösung von OP als auch die von 45thj5ej ausprobiert, und keine davon funktioniert für mich. Beim Ausführen des Skripts mit Powershell findet es “/backups/” und das untergeordnete Element nicht. Außerdem kann ich nicht finden, wo OP meint, wo man seinen Benutzernamen und sein Passwort eingeben soll. Ich betreibe Discourse auf einem VPS.