Let’s celebrate the holiday season with a quick PowerShell script to backup a Hyper-V server…or maybe you just need a quick and dirty, belt and braces backup script for your Hyper-V based VMs.
It’s a small, quick script leveraging Hyper-V’s PowerShell module and some traditional command line utilities, like robocopy.
Get-VM | Stop-VM TIMEOUT /T 20 ROBOCOPY /MIR /R:0 /W:0 /LOG:F:\vs11.log /NP /NDL F:\Hyper-V \\nas2\VM_Backups\vs11\Hyper-V Start-VM wsus01 TIMEOUT /T 30 Start-VM mdt01
Let’s walk through the script.
Get-VM | Stop-VM
The first command gets a list of all the VMs on the host and then gracefully shuts them down, one after the other.
TIMEOUT /T 20
The script then waits for 20 seconds. This is for safety before it begins copying the VM files, and may not be necessary for you.
ROBOCOPY /MIR /R:0 /W:0 /LOG:F:\vs11.log /NP /NDL F:\Hyper-V \\nas2\VM_Backups\vs11\Hyper-V
Now we use Robocopy to copy the contents of the Hyper-V folder to the backup location, which in this example is on a networked attached storage box called nas2. Robocopy logs it’s actions to a log file in the root of the F:\ drive on the Hyper-V host.
Start-VM wsus01 TIMEOUT /T 30 Start-VM mdt01
The final section of the script starts the VMs up in a specified order with a time out in between each one. We do this instead of
Get-VM | Start-VM
because the “Start-VM” command won’t wait for each VM to boot before booting the next one, and with all the VMs on the host starting simultaneously the storage array will become overworked. The disadvantage of starting the VMs this way is that you’ll have to edit this script when adding new VMs. Another way of starting the VMs would be to restart the Hyper-V host after the backup and in the settings for each VM, set them to start automatically with a gradually increasing wait time for each one. See screenshot for an example.
As usual, I recommend scheduling this script via Task Scheduler and having it run once a week. When scheduling a PowerShell script in Task Scheduler remember to use the following command line as the action:
PowerShell.exe -ExecutionPolicy Bypass F:\scripts\hyperv-backup.ps1
The script is designed to be run on each Hyper-V host locally, so you’ll want to space out the schedules to prevent each host from copying all it’s Hyper-V data to the one location at the same time and saturating the network and/or storage bandwidth.
I wrote this script with my small collection of Hyper-V hosts in mind. They all have the Hyper-V VM configuration and VHD files in the location F:\Hyper-V and have the relevant data backed up daily via the network-wide backup solution. This script runs once a week and is a belt and braces, extra backup for the VMs themselves. It does mean that there is some downtime for each of the VMs however. The advantage of having a copy of both the VHDs as well as the configuration files is that the VMs can be easily imported to another Hyper-V host and up and running very quickly.
I hope this has helped you in some way. If you have any questions or comments, let me know!