Hyper-V Sicherung mittels Powershell Script
Sicherung ist eines der meist vernachlässigsten und dennoch wichtigsten Aufgaben in der IT. Hand aufs Herz, nachdem man eine virtuelle Maschine laufen hat, kann es schon mal vorkommen das man das Sichern vergisst. Damit das in unseren Projekten nicht passiert, haben wir nach einer Lösung gesucht, die es uns mit Bordmitteln ermöglicht, ein konsistentes Backup einer Hyper-V VM zu fahren. Vorweg aber etwas das uns sehr am Herzen liegt:
Da Daten und deren Sicherungen für Unternehmen einen existenziellen Wert darstellen, möchten wir hier ausdrücklich darauf hinweisen, dass wir für die hier bereitgestellten Skripte und Methoden keinerlei Haftung übernehmen und Sie diese auf eigene Gefahr einsetzen.
Wie sieht nun unsere Methode aus? Hyper-V bringt seit der ersten Version die Möglichkeit mit sich eine VM zu exportieren. Bei diesem Vorgang werden die kompletten Daten, d. h. die Platten (VHDs), die Snapshots (falls vorhanden) und die Konfiguration, in einem Format in ein Verzeichnis kopiert, so dass diese jederzeit auf einen anderen Host kopiert und wieder importiert werden können. Daraus kann sich ein Problem ergeben: Da die Daten kopiert werden, und das nur auf einer Platte des Hosts passieren kann (keinem Netzlaufwerk), benötigt die Maschine mindestens den gleichen freien Plattenplatz, wie die gesamte VM belegt.
Weiterhin kann die VM beim Exportvorgang nicht laufen, das heißt sie ist entweder heruntergefahren (was wir präferieren) oder sie ist zumindest gespeichert. Diese Ausfallzeit der VM kann, je nach Größe der VHDs und Snapshots, schon einige Minuten dauern. Als Beispiel dauert der Export unseres Exchange Server mit ca. 80 GB um die 30 Minuten. Natürlich möchten wir den Exportvorgang nicht von Hand anstoßen, sondern automatisieren. Deswegen haben wir uns ein PowerShell Script geschrieben, das mittels Aufgabenplaner in regelmäßigen Interwallen diesen Exportvorgang durchführt. Wenn Sie möchten kopiert dann dieses Script, nach Abschluss des Exportvorgangs, die Daten auf einen beliebigen Netzwerkpfad, damit die Daten nicht nur auf dem Host liegen.
Hier der grobe Ablauf des Scripts:
- Maschine herunterfahren oder schlafen legen
- Exportvorgang auf lokalen Datenträger
- Maschine starten oder aufwecken
- Gegebenenfalls den Export auf Netzwerkfreigabe kopieren
Damit unser PowerShell Script funktioniert, benötigen wir die PSHyperv Library die James O’Neill entwickelt und unter CodePlex (Download unter http://www.codeplex.com/psHyperV) frei zur Verfügung stellt. Achtung: die aktuelle Version funktioniert nur mit der PowerShell V2, allerdings auf beiden Hyper-V Varianten. Zum reibungslosen Installieren der Library sind folgende Schritte vorab durchzuführen:
- Sie laden das ZIP-Archive in ein Verzeichnis (z.B. C:\Temp) herunter
Sie wenden das Sysinternal Tool “streams” an, um die Kenzeichnung, dass die Datei aus dem Internet geladen wurde (“Zone.Identifier”), zu entfernen - Sie entpacken das Archive in einem temporären Verzeichnis (z.B. c:\Temp)
Danach führen Sie die Installation des Library durch: Rechtsklick auf das “install.cmd” Script und auswählen “Als Administrator ausführen”. Jetzt werden Sie gefragt, ob Sie “.Net Framework 2” und “PowerShell” installiert haben. Ist das nicht der Fall, dann brechen Sie bitte die Installation ab und holen dieses nach.
Erfüllen Sie alle Voraussetzungen, dann drücken Sie “Enter” und das Script kopiert die Library und nimmt alle erforderlichen Einstellungen vor. In dem Screenshot sehen Sie zwei Fehler, die auf einer nicht Core Installation auftreten. Diese Fehler können Sie ignorieren und bestätigen einige weitere Male die Installationsschritte.
Nach erfolgreicher Installation sollte ein Powershell-Fenster aufgehen, indem Sie die Installation mit dem PowerShell Befehl:
get-command –module HyperV
überprüfen können.
Nach der erfolgreichen Installation der PsHyperV Bibliothek laden Sie unser PowerShell Script “HyperV-Backup.ps1” herunter (die aktuelle Version finden Sie am Ende des Artikels). Das ZIP Archive entpacken Sie in einem Verzeichnis z.B. “C:\Tools”. Auch hier sollten Sie das Sysinternal Tool “streams” anwenden, damit Powershell das Script ausführen kann.
Einen ersten Überblick über die Scriptoptionen erhalten Sie, wenn sie das Script nun aus einer Powershell (Achtung Administratoren Rechten erforderlich) mit dem Argument “-?” oder “-help” aufrufen z.B.: “C:\Tools\HyperV-Backup.ps1 –?”. Als Hilfestellung für den Einsatz gebe ich im folgenden einige Beispiele, wie Sie dieses Script benutzen können:
1. lokaler Export eines VMs:
C:\Tools\HyperV-Backup.ps1 –VM W2K8-VM –ExportPath D:\Exports
Schritte die das Script ausführt:
- die VM "W2K8-VM” wird heruntergefahren
- Sie wird in das Verzeichnis C:\Exports\W2K8-VM exportiert und ein dort gegebenenfalls vorhandener alter Export gelöscht
- die VM wird wieder gestartet
2. lokaler Export einer VM mit Kopie auf Sicherungsserver:
C:\Tools\HyperV-Backup.ps1 –VM W2K8-VM –ExportPath
D:\Exports -RemotePath \\Storage\Sicherung$ –verbose
Schritte die das Script ausführt:
- die VM "W2K8-VM” wird heruntergefahren
- Sie wird in das Verzeichnis C:\Exports\W2K8-VM exportiert und ein dort gegebenenfalls vorhandener alter Export gelöscht
- die VM “W2K8-VM” wird wieder gestartet
- Der Export wird in die Netzwerkfreigabe “\\Storage\Hyper-V-Sicherungen$\W2K8-VM” kopiert und ein dort gegebenenfalls vorhandener alter Export gelöscht
- Die Export unter “D:\Exports\W2K8-VM” wird gelöscht
Zusätzlich gibt das Script, wegen des Schalters –verbose einige Informationen auf der Konsole aus.
3. remote Export mit Kopie auf Sicherungsserver:
C:\Tools\HyperV-Backup.ps1 –VM Debian1-VM –Server Hyperv5
–ExportPath D:\Exports -SaveState -RemotePath
\\Storage\Sicherung$ –verbose
Schritte die das Script ausführt:
- die VM "Debian1-VM” wird gespeichert (Option –SaveState)
- Sie wird in das Verzeichnis D:\Exports\Debian1-VM exportiert und ein dort gegebenenfalls vorhandener alter Export gelöscht
- die VM “Debian1-VM” wird wieder aufgeweckt
- Der Export wird in die Netzwerkfreigabe “\\Storage\Hyper-V-Sicherungen$\Debian1-VM” kopiert und ein dort gegebenenfalls vorhandener alter Export gelöscht
- Die Export unter “D:\Exports\W2K8-VM” wird gelöscht
Zusätzlich gibt das Script wegen des Schalters –verbose einige Informationen auf der Konsole aus.
Nun sollte es ein leichtes sein, mit Hilfe der Windows Aufgabenplanung lokale und auch remote HyperV VMs zu exportieren.
Wenn Sie Anregungen, Kritik oder Verbesserungsvorschläge zu diesem Script haben, dann mailen Sie uns diese doch unter:
Falls diese Script sehr nützlich für Sie ist, dann würden wir uns über eine positive Beurteilung unser Hyper-V PinPoint Lösung sehr freuen.
Download-Link:
Version 0.91: HyperV-Backup-V0.91.zip
Update 14. Juli 2010: Fix beim Export eines Remote Systems. Es wurde beim Export einer Remote VM nicht der entfernte Export Pfad geprüft sondern fälschlicherweise der Lokale Pfad.
Version 0.9: HyperV-Backup-V0.9.zip
Erste Version





Gute Anleitung,
werde das mal ausprobieren ! Danke !
Funktioniert gut und ist gar nicht so langsam ! Danke !!!!!
Hmm… warum nicht mit Windows Backup?
Weil wir eine Lösung haben wollten, bei der wir einen kompletten Export in der Hand halten…
Ist nun auch bei uns im Einsatz. Vielen Dank für das Script und die Anleitung! :)
Gibt es auch eine Doku was genau das Script in welchen Bereichen macht ?
Würde eigentlich nur ein Scrip für Beenden brauchen und dann ein Script fürs Starten.
Dazwischen würde Acronis die Hyper-V sichern.
Leider ist für mich diese Out of the Box Lösung nicht ganz ersichtlich was von dem script gebraucht wird oder nicht.
Hallo ProjektC,
für deinen Fall (nur Herunterfahren und Hochfahren) gibt es in der Hyper-V Library (Link im Artikel) die PowerShell CmtLets:
- Shutdown-VM (Herunterfahren mit installierten ICs)
- Suspend-VM (Pausieren auch ohne ICs)
- Start-VM (Hochfahren)
Du musst aber trotzdem wie beschrieben die Hyper-V Library installieren.
Gruss Carsten Rachfahl
Das klinkt alles sehr lecker nur leider gibt es einen fehler beim Download des Scripte.
404 – Datei oder Verzeichnis wurde nicht gefunden.
MFG
Hallo Rico,
wir haben alle Links überprüft -> gehen alle. Vieleicht unterbindet etwas (Virenscanner etc.) den Download einer ZIP-Datei aus dem Internet?
Gruß
Carsten Rachfahl
Hallo. Gibt es ein skrip, oder wie ist der Befehl, mit dem ich einfach eine VM in Hyper-V starten oder herunterfahren kann?
BEsten Dank
Hallo Michael,
sie mal weiter oben meine Antwort vom 11. August in den Komentaren.
Gruß Carsten
Hallo Carsten,
vielen Dank für die sehr gute Anleitung und das Skript.
Vorab: ich bin Novize was Powershell betrifft und auch noch relativ unerfahren mit W2K8 Server (R2). Vielleicht deshalb auch meine dämliche Fragerei. Ich habe W2K8 Server R2 installiert in der Standard-Version (180-Tage-Eval). Die Hyper-V Bibliotheken sind installiert. PowerShell 2.0 ist installiert (geprüft: $psVersionTable)
Wenn ich das Skript in einer PS aufrufe (die PS mit Adminrechten gestartet), dann funktioniert es.
Wegen Automatisierung des Backups: Das *.ps1 per Doppelklick ausgeführt, öffnet den Notepad … ?!?
Eine Steuerungs-BAT geschrieben,
cd C:\Windows\system32
powershell C:\Skripte\Hyper-V\HyperV-Backup.ps1 VM MyVM ExportPath F:\Save
und mit Admin-Rechten gestartet liefert das hier:
powershell C:\Skripte\Hyper-V\HyperV-Backup.ps1 ûVM MyVM ûExportPath F:\Save
WARNUNG:
Falscher Parameter: Auf den ExportPath ûExportPath kann nicht zugegriffen
werden.
û …
Es greifen auch die von Microsoft vorgeschlagenen Tipps mit vorangestelltem & und einschließen des Dateinamens in ‘ ‘ leider nicht (fehlende Parameterübergabe?)
Ach so, eine Info noch .. ich arbeite in einer Remotesession auf dem Hyper-V Server.
Kannst Du oder ein anderer bitte mit einem Tipp weiter helfen?
Vielen Dank,
Thomas
Hallo,
schon wieder ich … ich habe die Lösung gefunden. Beim nochmaligen Lesen meines Posts habe ich gesehen, dass im Aufruf die – Zeichen fehlen.
Die Zeichen stehen in meinem Batch-Skript aber definitiv drin, werden aber bei der Abarbeitung falsch interpretiert als û.
Nun war es so, dass ich das Batch nicht im Notepad geschrieben habe, sondern den Aufruf kopiert und in Notepad eingefügt hatte. Ich meine usrprünglich aus Eurer Website, die ich aber auf meinem XP-Notebook in Firefox betrachtet habe, dort also Copy und in die Remotesession per Paste eingefügt – womöglich war der “Übergang” zu hart.
Nach dem erneuten Editieren und Speichern des Batch-Skriptes funktioniert es nun.
Gruß,
Thomas
PS: Warum ein Steuerungs-Batch? Ich teste immer ganz gerne vorab und möchte Ergebnisse/Meldungen sehen, bevor ich automatisiere. Schließlich sollen keine hängenden Prozesse einen Server ausbremsen (wie in meinen Anfangstagen beim Skripting mal geschehen).
Danke.
Ich habe die “Hyper-V Library” installiert. Nach der Installation öffnet sich der PowerShell Fenster.
In diesem funktionieren die Befehle “shutdown-vm” und start-vm”.
Öffne ich aber manuel ein neues Powershell Fenster, kennt dieses die Befehle nicht. (“start-vm” wurde nicht als Name eined Cmdlet, einer Funktion, einer Skriptdatei oder eines ausführbaren Programms erkannt…)
woran kann das liegen?
besten Dank für die Unterstützung
Hallo,
ich habe wieder eine Frage zum Skript bzw. besser gesagt zum Zurückspielen.
Nach dem Importieren der zuvor gesicherten (exportierten) und für Testzwecke gelöschten VM (HyperV-Manager und im Explorer die Verzeichnisse) fiel mir dann auf, dass Hyper-V sich scheinbar nicht mehr um die ursprünglichen Pfade kümmert.
Die importierte VM startet problemlos – aber die Pfade sind Default wie bei einer neuen VM. Bei der Erstellung der VMs wähle ich die Option “Virtuellen Computer an einem anderen Speicherort speichern”. Somit kommt alles, was die VM betrifft in 1 Verzeichnis: dies der Übersichtlichkeit halber, mir sind flache Mülleimer-Strukturen zuwider.
Nun wollte ich die importierte VM anpassen:
a) XML-File editieren: Speicherpfade zu den VHDs
b) XML-File verschieben: an den Ort, wo sie vorher war (die VM fliegt raus aus dem HyperV-Manager) und
c) Verknüpfung anpassen (C:\Users\All Users\Microsoft\Windows\Hyper-V\Virtual Machines) oder
Tja: beim Schritt c) gibt’s Probleme: Anpassen der Verknüpfung geht nicht, neue Verknüpfung wird im Hyper-V Manager V2 nicht erkannt.
Man könnte alternativ eine neue VM erstellen und die VHDs kopieren und auswählen. Aber werden dabei auch
- Snapshots (wir habe nicht vor welche zu erstellen, aber wer weiß)
- RAM-Inhalte, die beim Suspend hergestellt wurden
berücksichtigt?
Hat jemand einen Tipp, wie ich die Konfiguration anpasen kann? Das Skript ist nämlich klasse!
Mache ich etwas falsch?
Wäre das Herunterfahren der gewünschten VM und die Sicherung des Verzeichnisses eine Option, v.a. bei DB-Server-VMs (wenn auch zeitlich aufwändiger)?
Danke und Gruß,
Thomas
Hallo Michael,
im Backup-Skript wird die Bibliothek angeladen, ab Zeile 147 (das Nachfolgende aus dem Skript wurde von mir gekürzt).
# Fuktion lädt PSHyperV Library (aber nur wenn sie nicht schon geladen ist)
#
function LoadPSHyperV
{
…
}
Gruß,
Thomas
Hallo Michael,
ich hab’s eben getestet: Ableitung der Eingaben aus dem Skript … funktioniert Bestens.
Annahmen: Die VM heißt HyperV-G01 und liegt auf lokalem Server.
1. PS mit Admin-Rechten starten. Prompt der PS
PS C:\Windows\system32>
2. Library laden:
PS C:\Windows\system32> import-module hyperv
3. Deine VM (HyperV-G01) starten auf lokalem Server (.)
PS C:\Windows\system32> start-vm hyperv-g01 -Server . -Force -Wait
4. Startprozess der VM: in der PS am türkis-farbenen Hintergrund und
den Kringeln zu sehen oder auch im HyperV-Manager beobachten
5. Meldung nach dem Start der VM
OK
6. Prompt der PS
PS C:\Windows\system32>exit
Ich hoffe, das hilft Dir weiter.
Gruß,
Thomas
sehr gute erklärung so klappt das tip top. zum herunterfahren der VM muss ich den befehl noch mit “j” bestätigen. kann ich das auch gleich hinzufügen?
shutdown-vm hyperv-g01 /j hat nicht funktioniert
Besten Dank
und das ganze funktioniert ja nur, wenn mann die PS als administrator ausführt.
Wie kann ich ein Skript als Administrator ausführen lassen?
Will für jede meiner VM in Hyper-V ein Skript zum hochfahren und zum runterfahren machen.
Hallo Michael,
im Skript in Zeile 200 steht das Cmdlet “Invoke-VMShutdown”
Invoke-VMShutdown $myVm -Server $Server -Force -ShutdownTimeOut $timeout
Das leite ich auf unser Beispiel ab (er arbeitet hier mit Variablenwerten, die ganz am Anfang gesetzt werden – wobei ich nicht weiß, wofür die 600 stehen (Sekunden), ich habe eben 2x erfolgreich mit den Werten 5 und 60 getestet – die VM fuhr jedesmal sofort herunter):
Invoke-VMShutdown HyperV-G01 -Server . -Force -ShutdownTimeOut 600
Die Cmdlets der Library können noch viel mehr:
http://pshyperv.codeplex.com/
Da werde ich mich mal umtun :-)
Dort auch ein Diskussionsforum, usw.
Als Suchbegriff Invoke-VMShutdown: in einem Post wird erklaert von jamesone (=Autor der Library?), dass der shutdownparameter mit dem Dienste Stop und dem erneuten Start zu tun hat. Der Wert muss in Sekunden sein –> 600 s = 10 Minuten
Gruß,
Thomas
Hi Michael,
zum zweiten Post:
Wenn die VM beim Start des Hyper-V Servers gestartet werden soll bzw. heruntergefahren werden soll beim Herunterfahren des Servers: Einstellungen der VM > Ziemlich weit unten (ist aber hier u.U. Off Topic)
Ansonsten PS-Skripte schreiben für Start und Stop, die die Endung .ps1 haben (die Lib anladen, Kommandos zum Starten/ Stoppen ausführen … so wie das Backup-Skript), evt. noch ein Steuerungsbatch (siehe mein 1. Posting, weil sich bei mir der Notepad geöffnet hat, wenn ich beim Aufruf des PS-Skriptes nicht powershell starte) und dann via Aufgabenplanung (Start > Programme> Verwaltung > Aufgabenplanung) eine neue Aufgabe planen. Dabei Optionen “Mit erhöhten Rechten ausführen” und “Auch dann ausführen, wenn Benutzer nicht angemeldet ist”, OS-Benutzer mit entsprechenden Rechten verwenden. Evt. andere Trigger (Auslöse-Ereignisse) statt des Zeitpunkts wählen.
Lies Dich bitte in das Backup-Skript von Carsten Rachfahl ein – das erscheint zunächst kopmplex, ist sehr hilfreich. Denn vor dem Stoppen / Starten sollte man Stati der VM abfragen. Und das macht das Backup-Skript.
Gruß,
Thomas
Hallo,
Nach kurzen durcharbeiten der Anleitung ging es dann auch ziemlich schnell zum Ziel.
Meine Frage nun nach den erfolgreichen exportieren: Gibt es auch eine Variante die es zulässt während des laufenden Betriebes zu exportieren?
gruß Sandro
Hallo Sandro,
leider Nein. Der Export kann nur mit einer Heruntergefahrenen oder Gespeicherten VM gemacht werden. Für Laufzeit Kopie müsste mit dem SnapShot Provider gearbeitet werden und das bringt entliche andrer Hürden mit sich. Ich habe da ein Video von der TechED 2010 NA gesehen in dem einiges zu SnapShot gezeigt wird. Schau doch mal in meinem Artikel zu den Videos von der TechED 2010.
Gruß Carsten
Hallo Thomas
Dein Vorschlag hat zwar Grundsätzlich funktioniert, hilft mir aber leider nicht wirklich weiter.
Mit einem Steuerungs.bat in der Aufgabenplanung (wegen den Administratorenrechte), welches das PS Skript ausführt hat es funktioneirt, die VM zu starten oder herunterzufahren.
Situation: ich habe ein HTML File, auf welches jeder Mitarbeiter zugriff hat, darin sind alle VM die ich in HyperV habe aufgelistet und ein Link auf RemoteDesktop Files für die verbindung auf die VM ist gleich dabei. Im selben File wäre jetzt noch ein Link benötigt, welcher die VM starten oder herunterfahren würde. Und die Aufgabe kann ich wohl kaum verlinken?
Gibt es keine eifnachere möglichkeit, wie das PowerShell Skript als Administrator ausgeführt werden kann?
Besten Dank
Hallo Michael,
ein Vorschlag, wird Dir aber nach Deinen Vorschlag wohl nicht unbedingt weiterhelfen: in der Aufgabenplanung versuchen, einen anderen Trigger zu verwenden, z.B. “Anmeldung”. Eine zusätzliche RDP Session gegen den hyper-V Server führt dann nur Aktion ein Skript aus, das eine Abfrage enthält: Was möchten Sie tun? 1) Start 2) Stopp
3) gar nichts :-))))
Nach Abarbeitung des Skriptes wird der User wieder abgemeldet vom Hyper-V Server.
Abfrage in Batch
rem Bildschirmausgabe
echo VM starten oder Stoppen
echo =======================
echo .
echo 1 Start
echo 2 Stopp
echo 3 Nichts wie weg hier
echo .
set /p Antwort=”Bitte waehlen Sie (1-3): ”
rem Sprung, wird Nonsens eingegeben –> Abbruch
goto :Sprung_%Antwort%
:Sprung_1
powershell.exe [Dein-Startskript]
:Sprung_2
powershell.exe [Dein-Stoppskript]
:Sprung_3
exit
Oder als Trigger ein Ereignis a la Eventlog-Eintrag (Sicherheit, Überwachung der Remoteanmeldung .. oder irgendein Ereignis, welches Deine HTML-Seite generiert), welches dann ein Powershellskript (Steuerungs-Batch) mit erhöhten Rechten eines Stellvertreter-Users ausführt.
Inwiefern aber Eure Sicherheitsrichtlinen unterlaufen werden …?
Gruß,
Thomas
Hallo Carsten,
schönes Script!
Ich werde es nach einigen Tests auch produktiv einsetzen.
Das Kopieren mache ich allerdings per Robocopy, aber der Export ist eh das Wichtigste.
Ist eine Hilfe in Umgebungen, die keine Cluster betreiben können.
Mit Protokollierung über >> log.log ist das eine saubere Sicherung.
Danke
Jens