Automatisches Backup mit 7-Zip (Passwortschutz)

Datum

Was man braucht ist eine Festplatte, auf der Backups abgelegt werden sollen. Diese muss für den Benutzer, welcher die Backups starten soll, sichtbar und beschreibbar sein. Wichtig ist auch, dass man sich vorher Gedanken macht, wie viel Speicherkapazität man wohl brauchen wird.

Schauen wir uns also zunächst per Powershell an, wie viele virtuelle Maschinen der Hyper-V-Host fährt und wie groß die Festplatten zusammengerechnet sind:

Get-VM | Foreach-Object -Begin {
	$sum=0
	$maxsum=0
} -Process {
	$vm=$_.vmname
	Get-VMHardDiskDrive -vmname $vm | foreach-object {
		$vhd=Get-VHD -Path $_.Path
		$len=$vhd.FileSize
		$maxlen=$vhd.Size
		write-host "$vm (" -nonewline
		write-host $vhd.Path -nonewline
		write-host "): " -nonewline
		write-host ($len/1GB) -nonewline
		write-host " GB (" -nonewline
		write-host ($maxlen/1GB) -nonewline
		write-host " GB max)"
		$sum+=$len
		$maxsum+=$maxlen
	}
} -End {
	write-host "Summary: " -nonewline
	write-host ($sum/1GB) -nonewline
	write-host " GB (" -nonewline
	write-host ($maxsum/1GB) -nonewline
	write-host " GB max)"
}

Die Ausgabe sieht dann in etwa so aus:

Adam (c:\hyperv\vhd\adam.vhdx): 19,72265625 GB (20 GB max)
ADC (c:\hyperv\vhd\adc.vhdx): 37,03515625 GB (40 GB max)
Blog (c:\hyperv\vhd\blog.vhdx): 4,28515625 GB (50 GB max)
Code01 (c:\hyperv\vhd\code01.vhdx): 5,44140625 GB (10 GB max)
Code01 (c:\hyperv\vhd\code01_data.vhdx): 165,50390625 GB (300 GB max)
DHCP (c:\hyperv\vhd\dhcp.vhdx): 2,12890625 GB (4 GB max)
FTP (c:\hyperv\vhd\ftp.vhdx): 1,97265625 GB (2 GB max)
Hosting (c:\hyperv\vhd\hosting.vhdx): 3,28515625 GB (8 GB max)
Hosting (c:\hyperv\vhd\hosting_data.vhdx): 3,25390625 GB (100 GB max)
OTRS (c:\hyperv\vhd\otrs.vhdx): 4,91015625 GB (20 GB max)
Radio (c:\hyperv\vhd\radio.vhdx): 1,94140625 GB (2 GB max)
RDP (c:\hyperv\vhd\rdp.vhdx): 51,66015625 GB (100 GB max)
SDC (c:\hyperv\vhd\sdc.vhdx): 39,59765625 GB (40 GB max)
SSH (c:\hyperv\vhd\ssh.vhdx): 2,94140625 GB (8 GB max)
Teamspeak (c:\hyperv\vhd\teamspeak.vhdx): 2,03515625 GB (4 GB max)
Tor (c:\hyperv\vhd\tor.vhdx): 1,75390625 GB (2 GB max)
Unreal (c:\hyperv\vhd\unreal.vhdx): 3,41015625 GB (8 GB max)
Web (c:\hyperv\vhd\web.vhdx): 5,72265625 GB (8 GB max)
Web (c:\hyperv\vhd\web_data.vhdx): 7,09765625 GB (8 GB max)
WebRDP (c:\hyperv\vhd\webrdp.vhdx): 2,00390625 GB (2 GB max)
WebRDP (c:\hyperv\vhd\webrdp_data.vhdx): 0,37890625 GB (4 GB max)
WebSSH (c:\hyperv\vhd\webssh.vhdx): 1,62890625 GB (2 GB max)
Summary: 367,7109375 GB (742 GB max)

Wie man sieht sind die VHDs allesamt dynamisch. Wir sollten allerdings beim Thema Backup immer vom Maximum ausgehen. Also brauchen wir max. 742 GB freien Speicherplatz.

Gehen wir davon aus, dass eine externe Festplatte als E:\ gemountet ist und diese über ausreichend Speicherkapazität verfügt. Die Vorgehensweise ist wie folgt:

  • Für jede VM für den Backup-Prozess einen Snapshot erstellen. (Das ist notwendig, weil man ansonsten die virtuelle Festplatte einer laufenden VM nicht kopieren kann.)
  • Die VHD per 7-Zip passwortgeschützt zum Backup-Archiv hinzufügen. (Wird eine Weile dauern – je nachdem, wie groß die VHDs sind.)

Ich gehe in meinem Beispiel davon aus, dass man die 64-Bit-Version von 7-Zip installiert hat. Nun zum eigentlichen Skript:

# Wir definieren das Ziel:
$target="E:\Backup\HyperV.7z"
# Löschen des Ziels, sofern vorhanden
if(Test-Path $target) {
	del $target
}
# Wir scrollen durch alle VMs:
Get-VM | ForEach-Object {
	# Alle VHDs der VM auflisten:
	[string[]] $hddpath = @()
	Get-VMHardDiskDrive -VMName $_.VMName | Where-Object { $_.DiskNumber -lt 0 } | ForEach-Object {
		$hddpath = $hddpath + $_.Path
	}
	# Evtl. vorhandenen Snapshot für ein evtl. vorheriges Backup löschen
	Get-VMSnapshot -VMName $_.VMName -Name "Backup" | Remove-VMSnapshot
	# Wenn die VHD physikalische Platten angebunden hat, dann herunterfahren:
	if((Get-VMHardDiskDrive -VMName $_.VMName | Where-Object { $_.DiskNumber -ge 0 }).count -gt 0) {
		$b=$true
		if($_.State -eq "Running") {
			$r=$true
			write-host "Shutting down"$_.VMName
			Stop-VM -VMName $_.VMName
		}
		else {
			$r=$false
		}
	}
	# Andererseits Checkpoint erstellen, sofern die VM läuft:
	else {
		$b=$false
		if($_.State -eq "Running") {
			$r=$true
			write-host "Creating Snapshot for"$_.VMName
			Checkpoint-VM -VMName $_.VMName -SnapshotName "Backup"
		}
		else {
			$r=$false
		}
	}
	# Und nun die VHDs sichern:
	$hddpath | ForEach-Object {
		write-host "Backing up"$_
		& "C:\Program Files\7-Zip\7z.exe" a -p"GeheimesPasswort" $target $_
	}
	# Sofern VM heruntergefahren worden ist, wieder starten:
	if($b -and $r) {
		write-host "Starting"$_.VMName
		Start-VM -VMName $_.VMName
	}
	# Sonst Snapshot wieder entfernen:
	elseif($r) {
		write-host "Removing Snapshot for"$_.VMName
		Get-VMSnapshot -VMName $_.VMName -Name "Backup" | Remove-VMSnapshot
	}
}
# Eine Besonderheit: Die Berechtigungen aller VHDs zusätzlich sichern:
& icacls C:\HyperV\VHD\*.vhdx /save C:\HyperV\VHD\permissions.txt >nul 2>nul
& "C:\Program Files\7-Zip\7z.exe" a -p"GeheimesPasswort" $target C:\HyperV\VHD\permissions.txt

Das Ganze sollte dann als Scheduled Task eingestellt werden:

Wichtig ist noch, dass der Task mit höchsten Rechten ausgeführt wird:

Das war’s auch schon. Das erste Mal muss man den Task manuell anstoßen. Sofern er ohne Fehler durchläuft, wird der Trigger aktiviert.

Autor
Kategorien Backup, Hyper-V

PRTG Map