Hyper-V VMs automatisiert sichern: PowerShell-Export als kostenloses Backup
Hyper-V VMs automatisch exportieren und sichern: PowerShell, Export-VM, HyperV-Backup.ps1, ExportPath, Aufgabenplanung, Netzwerkpfade, Generationen und Restore-Tests.
<#
.SYNOPSIS
Automatisierter Hyper-V VM-Export mit optionaler Kopie auf ein Remote-Ziel.
.DESCRIPTION
Moderne, native Variante des klassischen HyperV-Backup-Ansatzes.
Verwendet ausschließlich das Hyper-V PowerShell-Modul und Export-VM.
Unterstützt:
- lokale Exporte
- optionales Herunterfahren (-TurnOff) oder Speichern (-SaveState)
- optionalen Neustart / Resume
- Kopie des fertigen Exports auf eine UNC-Freigabe
- optionalen StartDelay
- vorhandenes Ziel wird vor dem Export entfernt
- Exit-Codes für die Aufgabenplanung
Nur auf Hyper-V-Systemen verwenden und ausschließlich VMs sichern,
für deren Betrieb und Sicherung eine Berechtigung besteht.
.EXAMPLE
powershell.exe -NoProfile -File .\HyperV-Backup-Sille.ps1 `
-VM "FILESERVER01" `
-ExportPath "D:\HyperV-Exports"
.EXAMPLE
powershell.exe -NoProfile -File .\HyperV-Backup-Sille.ps1 `
-VM "FILESERVER01" `
-ExportPath "D:\HyperV-Exports" `
-RemotePath "\\BACKUP01\HyperV$" `
-TurnOff `
-StartDelay 60 `
-Verbose
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$VM,
[Parameter(Mandatory=$true)]
[string]$ExportPath,
[Parameter(Mandatory=$false)]
[string]$RemotePath,
[Parameter(Mandatory=$false)]
[int]$StartDelay = 0,
[Parameter(Mandatory=$false)]
[switch]$TurnOff,
[Parameter(Mandatory=$false)]
[switch]$SaveState
)
$ErrorActionPreference = 'Stop'
function Write-Step {
param([string]$Message)
Write-Host ("[{0}] {1}" -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $Message)
}
$vmObject = $null
$wasRunning = $false
$wasSaved = $false
$localExport = Join-Path -Path $ExportPath -ChildPath $VM
$remoteExport = $null
try {
if (-not (Get-Command Export-VM -ErrorAction SilentlyContinue)) {
throw "Das Hyper-V PowerShell-Modul bzw. Export-VM ist nicht verfügbar."
}
$vmObject = Get-VM -Name $VM -ErrorAction Stop
$wasRunning = ($vmObject.State -eq 'Running')
$wasSaved = ($vmObject.State -eq 'Saved')
if (-not (Test-Path -LiteralPath $ExportPath)) {
Write-Step "Erstelle lokales Exportverzeichnis: $ExportPath"
New-Item -ItemType Directory -Path $ExportPath -Force | Out-Null
}
if (Test-Path -LiteralPath $localExport) {
Write-Step "Entferne vorhandenen lokalen Export: $localExport"
Remove-Item -LiteralPath $localExport -Recurse -Force
}
if ($wasRunning) {
if ($TurnOff -and $SaveState) {
throw "-TurnOff und -SaveState dürfen nicht gleichzeitig verwendet werden."
}
if ($TurnOff) {
Write-Step "Fahre VM '$VM' kontrolliert herunter."
Stop-VM -Name $VM -Force -ErrorAction Stop
}
elseif ($SaveState) {
Write-Step "Speichere Zustand der VM '$VM'."
Save-VM -Name $VM -ErrorAction Stop
}
else {
Write-Step "VM '$VM' läuft. Export-VM wird mit dem aktuellen Hyper-V-Live-State-Verfahren ausgeführt."
}
}
Write-Step "Starte Export nach: $localExport"
if ($wasRunning -and -not $TurnOff -and -not $SaveState) {
Export-VM -Name $VM -Path $ExportPath -CaptureLiveState CaptureDataConsistentState -ErrorAction Stop
}
else {
Export-VM -Name $VM -Path $ExportPath -ErrorAction Stop
}
if ($StartDelay -gt 0) {
Write-Step "Warte $StartDelay Sekunden."
Start-Sleep -Seconds $StartDelay
}
if ($wasRunning -and ($TurnOff -or $SaveState)) {
if ($SaveState) {
Write-Step "Setze gespeicherten Zustand der VM fort."
Start-VM -Name $VM -ErrorAction Stop | Out-Null
}
else {
Write-Step "Starte VM '$VM' wieder."
Start-VM -Name $VM -ErrorAction Stop | Out-Null
}
}
if ($RemotePath) {
if (-not (Test-Path -LiteralPath $RemotePath)) {
throw "Remote-Ziel ist nicht erreichbar: $RemotePath"
}
$remoteExport = Join-Path -Path $RemotePath -ChildPath $VM
if (Test-Path -LiteralPath $remoteExport) {
Write-Step "Entferne vorhandenen Remote-Export: $remoteExport"
Remove-Item -LiteralPath $remoteExport -Recurse -Force
}
Write-Step "Kopiere Export nach: $remoteExport"
Copy-Item -LiteralPath $localExport -Destination $remotePath -Recurse -Force -ErrorAction Stop
Write-Step "Entferne lokalen Zwischenexport."
Remove-Item -LiteralPath $localExport -Recurse -Force
}
Write-Step "Hyper-V-Backup erfolgreich abgeschlossen."
exit 0
}
catch {
Write-Error ("Backup fehlgeschlagen: {0}" -f $_.Exception.Message)
# Falls die VM durch das Script angehalten wurde, versuchen wir sie
# wieder verfügbar zu machen.
if ($vmObject -and $wasRunning) {
try {
$current = Get-VM -Name $VM -ErrorAction Stop
if ($current.State -ne 'Running') {
Write-Step "Versuche, VM '$VM' nach dem Fehler wieder zu starten."
Start-VM -Name $VM -ErrorAction Stop | Out-Null
}
}
catch {
Write-Error ("VM konnte nach dem Fehler nicht automatisch gestartet werden: {0}" -f $_.Exception.Message)
}
}
exit 1
}
Hinweis zur Version: Dieses Skript ist eine moderne, native Umsetzung des im Artikel beschriebenen Hyper-V-Backup-Prinzips. Es benötigt keine historische PSHyperV-Bibliothek. Die Parameter orientieren sich bewusst am bekannten Muster mit -VM, -ExportPath, -RemotePath, -TurnOff und -StartDelay.
Warum Hyper-V-Exporte als Backup so interessant sind
Hyper-V kann eine virtuelle Maschine als vollständigen Export zusammenstellen. Microsoft beschreibt den Export als Sammlung der benötigten virtuellen Festplatten, Konfigurationsdateien und Checkpoint-Dateien in einer Einheit. Der Export kann laut Microsoft bei laufenden oder gestoppten VMs erfolgen; die konkrete Konsistenz und die verwendete Capture-Strategie hängen dabei von der Hyper-V-Konfiguration und der verwendeten Exportmethode ab.
Die Idee hinter dem kostenlosen Backup
Wer einen Hyper-V-Host betreibt, braucht nicht zwingend sofort eine große Backup-Suite, um eine einfache zusätzliche Sicherung aufzubauen. Mit PowerShell, dem Hyper-V-Modul, der Windows-Aufgabenplanung und ausreichend Speicherplatz lässt sich ein wiederverwendbarer Export-Workflow automatisieren. Das ist kein Ersatz für jede professionelle Backup-Infrastruktur, aber als zusätzliche Sicherung oder für kleinere Umgebungen ausgesprochen praktisch.
Was beim Export tatsächlich gesichert wird
Ein Hyper-V-Export enthält nicht nur die VHDX-Datei. Microsoft beschreibt die Exportstruktur mit virtuellen Festplatten, VM-Konfiguration und Checkpoint-Dateien. Dadurch entsteht ein Paket, das später wieder importiert werden kann. Genau das unterscheidet einen VM-Export von einem simplen Kopieren einzelner VHDX-Dateien.
Export-VM: das Herzstück
Das native PowerShell-Cmdlet heißt `Export-VM`. Der einfachste Aufruf lautet `Export-VM -Name TestVM -Path D:\HyperV-Exports`. Microsoft dokumentiert außerdem `Get-VM | Export-VM -Path D:\`, womit alle VMs exportiert werden können. Der Parameter `-Path` bezeichnet den Zielordner.
Export-VM -Name "SERVER01" -Path "D:\HyperV-Export\SERVER01"
Das klassische HyperV-Backup-Skript mit -ExportPath
Im Internet findet sich ein älteres PowerShell-Skript namens `HyperV-Backup.ps1`, das genau für diesen Anwendungsfall entwickelt wurde. Ein typischer Aufruf sieht aus wie `powershell.exe -File C:\Tools\HyperV-Backup.ps1 -VM "W2K8-VM" -ExportPath "D:\Exports"`. Das Skript übernimmt dabei mehr als nur den Export: Je nach Parametern kann es die VM herunterfahren, exportieren, wieder starten und den Export anschließend auf einen Netzwerkpfad kopieren.
powershell.exe -File "C:\Tools\HyperV-Backup.ps1" -VM "SERVER01" -ExportPath "D:\HyperV-Exports"
Was -ExportPath bei diesem Skript bedeutet
`-ExportPath` bezeichnet beim klassischen HyperV-Backup-Skript den lokalen Arbeitsbereich, in dem der VM-Export erzeugt wird. Das ist wichtig: Der Parameter ist eine Option des Skripts, nicht ein Parameter des nativen `Export-VM`-Cmdlets. Beim nativen Cmdlet heißt der entsprechende Parameter schlicht `-Path`. Diese Unterscheidung verhindert viele Missverständnisse beim Nachbauen der Befehle.
Der automatisierte Ablauf
Ein sinnvoller Workflow ist: VM in einen geeigneten Zustand bringen, lokalen Export erzeugen, Ergebnis prüfen, VM wieder verfügbar machen und anschließend den Export auf ein separates Backup-Ziel kopieren. Das lokale Zwischenziel ist besonders praktisch, weil der Hyper-V-Export zunächst auf dem Host erzeugt wird und anschließend unabhängig weiterverarbeitet werden kann.
Warum ein lokales Zwischenziel sinnvoll ist
Ein Export direkt auf eine Netzwerkfreigabe klingt zunächst attraktiv, ist aber nicht immer die beste Idee. Ein lokaler Arbeitsbereich reduziert Abhängigkeiten während des eigentlichen Hyper-V-Exports. Erst wenn der Export erfolgreich abgeschlossen ist, kann die fertige Struktur auf NAS, Fileserver oder ein anderes Backup-Ziel kopiert werden.
Beispiel: manueller Export mit PowerShell
Für einen modernen Hyper-V-Host reicht bereits ein nativer Befehl: `Export-VM -Name "SERVER01" -Path "D:\HyperV-Export\SERVER01"`. Vor dem ersten automatisierten Einsatz sollte dieser manuelle Export erfolgreich getestet und anschließend auch wieder importiert werden.
Beispiel: klassisches Skript über powershell.exe
Der von vielen Administratoren verwendete Aufbau für die Aufgabenplanung lautet beispielsweise: `powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Tools\HyperV-Backup.ps1" -VM "SERVER01" -ExportPath "D:\HyperV-Exports"`. Bei einem Skript aus dem Internet sollten die tatsächlich unterstützten Parameter vorher mit `-?` beziehungsweise `-Help` geprüft werden.
Warum -File wichtig ist
Wenn `powershell.exe` aus der Aufgabenplanung gestartet wird, muss eindeutig festgelegt werden, welches Skript ausgeführt werden soll. `-File` ist dafür die klare und gut nachvollziehbare Variante. Pfade und Parameter mit Leerzeichen gehören in Anführungszeichen.
Aufgabenplanung: der entscheidende Teil
In der Windows-Aufgabenplanung wird als Programm `C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe` verwendet. In das Feld für Argumente kommen `-NoProfile`, gegebenenfalls die gewünschte Execution Policy, `-File` und anschließend der vollständige Skriptaufruf mit seinen Parametern. Die Aufgabe sollte mit den für Hyper-V erforderlichen Rechten ausgeführt werden.
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
-NoProfile -File "C:\Tools\HyperV-Backup.ps1" -VM "SERVER01" -ExportPath "D:\HyperV-Exports"
Mit höchsten Privilegien und ohne Anmeldung
Für einen unbeaufsichtigten Backup-Job sind in der Aufgabenplanung typischerweise `Unabhängig von der Benutzeranmeldung ausführen` und `Mit höchsten Privilegien ausführen` relevant. Der Task muss außerdem unter einem Konto laufen, das auf Hyper-V, die lokalen Exportpfade und – bei einem Netzwerkziel – die entsprechende Freigabe zugreifen darf.
Netzwerkfreigaben: der klassische Stolperstein
Ein Backup kann interaktiv funktionieren und als geplanter Task trotzdem scheitern. Der Grund ist häufig das verwendete Benutzerkonto oder die fehlende Berechtigung auf einer SMB-Freigabe. Ein Laufwerk wie `Z:` ist für geplante Tasks ebenfalls problematisch, weil gemappte Laufwerke an eine interaktive Benutzersitzung gebunden sein können. Für automatisierte Jobs ist ein UNC-Pfad wie `\\Backupserver\HyperV$` wesentlich robuster.
VM ausschalten oder laufend exportieren?
Hier muss man zwischen dem alten Skript und modernen Hyper-V-Funktionen unterscheiden. Das historische Skript arbeitet je nach Parameter mit Herunterfahren oder Saved State. Das aktuelle `Export-VM` bietet zusätzlich `-CaptureLiveState` und damit Optionen für die Erfassung des Zustands einer laufenden VM. Microsoft dokumentiert unter anderem `CaptureSavedState`, `CaptureDataConsistentState` und `CaptureCrashConsistentState`. Für produktive Systeme sollte die gewählte Strategie bewusst anhand der jeweiligen Anwendung und Wiederherstellungsanforderung festgelegt werden.
Backup ist nicht gleich Backup
Ein Export ist eine hervorragende zusätzliche Sicherung, aber kein vollständiges Backup-Konzept. Ohne mehrere Generationen, getrennte Speicherorte und idealerweise eine Offsite-Kopie kann ein Defekt, Ransomware-Angriff oder Bedienfehler auch das Backup zerstören. Besonders wichtig ist die 3-2-1-Regel als grundlegendes Ziel: mehrere Kopien, unterschiedliche Medien und mindestens eine Kopie außerhalb des primären Systems.
Aufbewahrung und Generationen
Ein automatisierter Export sollte nicht einfach jeden Tag denselben Ordner überschreiben und anschließend die einzige Kopie behalten. Sinnvoller sind zeitgestempelte Exportverzeichnisse oder eine definierte Anzahl von Generationen. Das Skript beziehungsweise ein nachgelagerter Cleanup-Job kann alte Exporte nach einer Aufbewahrungsfrist entfernen.
Speicherbedarf nicht unterschätzen
Ein VM-Export kann sehr groß werden, weil virtuelle Festplatten mit exportiert werden. Vor dem Aufbau sollte der verfügbare Speicherplatz geprüft werden. Bei mehreren Generationen muss der Platz für mehrere vollständige Exporte kalkuliert werden. Ein kleiner Host mit mehreren großen VHDX-Dateien kann den Backup-Datenträger überraschend schnell füllen.
Restore-Test: der Teil, den viele vergessen
Ein Backup ist erst dann wirklich wertvoll, wenn eine Wiederherstellung funktioniert. Deshalb sollte regelmäßig ein Export auf einem Testhost oder in einer geeigneten Testumgebung importiert und gestartet werden. Für einen Import stehen unter anderem `Import-VM` und die Hyper-V-Importfunktionen zur Verfügung. Ein erfolgreicher Export allein beweist noch nicht, dass die Anwendung nach einem Desaster wieder läuft.
Praktische Restore-Prüfung
Eine einfache Prüfung besteht aus: Export auswählen, `Import-VM` verwenden, gegebenenfalls eine neue VM-ID erzeugen, VM starten, Dienste prüfen und die Anwendung testen. Besonders bei Datenbanken, Domain Controllern, Exchange, Fileservern und anderen zustandsbehafteten Diensten sollte die Wiederherstellung nicht nur auf der Ebene „VM bootet“ geprüft werden.
Logging und Fehlererkennung
Ein geplanter Task sollte nicht stillschweigend scheitern. PowerShell kann Ausgaben in eine Logdatei schreiben, und der Aufgabenplaner protokolliert den Task-Status. Für eine produktive Umgebung lohnt sich zusätzlich eine Benachrichtigung bei Fehlern oder eine Überwachung des Backup-Verzeichnisses.
Mein bevorzugter Aufbau für kleine Hyper-V-Umgebungen
Für eine kleine Umgebung würde ich den Export lokal auf dem Hyper-V-Host erzeugen, anschließend auf ein separates Storage-Ziel kopieren, mehrere Generationen vorhalten und regelmäßig einen Restore testen. Das ist überschaubar, transparent und ohne zusätzliche Backup-Lizenz realisierbar.
Praxisbeispiel für eine tägliche Sicherung
Angenommen, die VM heißt `FILESERVER01`, das lokale Arbeitsverzeichnis ist `D:\HyperV-Exports` und der Backupserver stellt `\\BACKUP01\HyperV$` bereit. Der geplante Task startet das Skript nachts. Das Skript erzeugt den Export lokal, wartet auf den erfolgreichen Abschluss, startet die VM gegebenenfalls wieder und kopiert den fertigen Export auf den Backupserver. Danach kann ein Cleanup-Job ältere Generationen entfernen.
VM: FILESERVER01
Local staging: D:\HyperV-Exports
Remote backup: \\BACKUP01\HyperV$
Schedule: nightly
Retention: multiple generations
Wichtiger Hinweis zu alten Skripten
Das im Internet verbreitete `HyperV-Backup.ps1` stammt aus einer deutlich älteren Hyper-V-/PowerShell-Generation und wurde ursprünglich mit einer externen PSHyperV-Bibliothek beschrieben. Moderne Windows-Server verfügen dagegen über das native Hyper-V-PowerShell-Modul. Deshalb sollte ein altes Skript nicht ungeprüft auf einen aktuellen Server kopiert werden. Die grundlegende Idee ist weiterhin sinnvoll; die konkrete Implementierung sollte zur installierten Windows-/Hyper-V-Version passen.
Warum ich die Lösung trotzdem interessant finde
Gerade weil die Grundidee so simpel ist, eignet sie sich hervorragend als zusätzliche Sicherung: Hyper-V exportiert die VM, PowerShell automatisiert den Ablauf und die Aufgabenplanung übernimmt die zeitliche Ausführung. Es gibt keinen Agenten pro VM und keine zusätzliche Backup-Lizenz. Für viele kleine Umgebungen ist das eine erstaunlich leistungsfähige Ergänzung.
Fazit
Automatisierte Hyper-V-Exporte sind kein vollwertiger Ersatz für jede professionelle Backup-Plattform. Als kostenlose, transparente und mit Windows-Bordmitteln realisierbare Zusatzsicherung sind sie jedoch ausgesprochen interessant. Wer den Export automatisiert, mehrere Generationen auf getrenntem Storage aufbewahrt und regelmäßig einen Restore testet, erhält aus einem simplen Hyper-V-Feature einen sehr brauchbaren Backup-Baustein.