NOTE: This is an old post, and I have since purchased Veeam Backup & Replication for Hyper-V. It is so much more effective, reliable, and feature filled than the process below that I would strongly recommend not wasting your time on scripting and invest the time in evaluating Hyper-V backup solutions.
Here is my evaluation of two Hyper-V backup solutions:
http://dynamicsgpland.blogspot.com/2015/02/how-do-you-backup-your-hyper-v-virtual.html
/////////////////////////////////////
Backups are one of the least glamorous IT tasks, but fortunately improvements in technology, software, and the abundance of inexpensive disk space has made them a lot easier.
I currently use SugarSync to backup all of my frequently used files, such as client files and zipped source code, which also syncs those files between my laptop, desktop, and iPhone. I also use Carbonite as an additional measure to back up all of those same files, plus all of my large files, such as Outlook PST files, database backups, and MP3 files, etc.
But those backups seem trivial and quaint compared to the challenge of backing up virtual machines. Despite my occasional effort to shrink the VHD files, a quick glance tells me that most of my VHD files are in the 20GB - 30GB range. While I have enough disk space for those files, backing up such large files is still a time consuming and space hogging endeavor. Copying such a large file to a backup drive or server takes quite a long time, and if you want to maintain multiple backups, the copies take up a lot of disk space.
I'm assuming there are some fancy backup solutions that can backup HyperV VMs (I've never bothered to check), but when it comes to backups, I avoid fancy, and prefer instead to stick with simple, basic, trusted tools.
In the past, I've manually saved or shut down my VMs and then manually used WinRAR to create a RAR backup file on my NAS storage device. This worked, but was manual and took forever. I would try and do the backups in the evening before going to bed, but never did them consistently or on any set schedule. I've heard that Volume Shadow Copy Service (VSS) and even Windows Backup can supposedly backup running HyperVs, but I'm not a fan of any of the versions of Windows Backup, and am fine taking the additional step of saving my VMs prior to backup to be on the safe side.
After switching over to 7Zip and seeing how much better the compression could be, I finally wrote some batch files to automatically zip the VHDs to 7z files with a date time stamp. You can use WinRAR or WinZip if you prefer, but given how rarely I need to recover a VHD backup, I want the best compression I can get. While this 7z batch file worked well, I still had to manually save or shutdown the virtual machine.
Only recently did I finally take the time to track down the VBS scripts that would automatically save my VMs. With this final piece, I have automated the backups of my virtual machines. It's not glamorous, and I am sure that there "better" approaches, but this is my first pass, is simple, and was fairly easy to do. I know that PowerShell offers alot of promise for this type of task, but seriously, have you seen PowerShell scripts? It may look like C, but the last thing I have time to do is learn yet another proprietary scripting language and yet another object model that I won't use regularly, so I've ruled out PowerShell for the time being.
So here are my current backup scripts and steps, likely subject to change as I use it more and perhaps learn of other techniques. I'm interested in hearing how others deal with this challenge. At the moment, I speculate that many businesses do not have any backup strategy or solution for regularly backing up their virtual machines.
Step 1: Use a VBS script to save the VM. Unfortunately, it seems that VBS only has the ability to Stop, Start, or Save HyperV VMs, and does not have the ability to "Shut down" the guest OS like PowerShell does. But from my experience, Save is adequate for backing up HyperV vhd files. I found this script on some web site and modified it slightly to meet my needs--I just use a fixed VM name rather than accepting a command line parameter like the original script. In these examples, I'm backing up my VM called "GPDEV1".
Option Explicit
Dim arg, targetVM, WMIService, VMs, InputKey
targetVM = "GPDEV1"
If Right((LCase(WScript.FullName)),11) <> "cscript.exe" then
WScript.Echo "Use cscript.exe"
WScript.Quit
End if
Set WMIService = GetObject("winmgmts:\\.\root\virtualization")
Set VMs = WMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" & targetVM & "'")
Select Case VMs.ItemIndex(0).EnabledState
Case 2
WScript.StdOut.Write targetVM & " is saving."
VMs.ItemIndex(0).RequestStateChange(32769)
Do while VMs.ItemIndex(0).EnabledState <> 32769
Set VMs = WMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" & targetVM & "'")
WScript.StdOut.Write(".")
WScript.sleep 1000
Loop
WScript.Echo "Completed."
Case Else
WScript.Echo targetVM & " is not running."
End Select
Dim arg, targetVM, WMIService, VMs, InputKey
targetVM = "GPDEV1"
If Right((LCase(WScript.FullName)),11) <> "cscript.exe" then
WScript.Echo "Use cscript.exe"
WScript.Quit
End if
Set WMIService = GetObject("winmgmts:\\.\root\virtualization")
Set VMs = WMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" & targetVM & "'")
Select Case VMs.ItemIndex(0).EnabledState
Case 2
WScript.StdOut.Write targetVM & " is saving."
VMs.ItemIndex(0).RequestStateChange(32769)
Do while VMs.ItemIndex(0).EnabledState <> 32769
Set VMs = WMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" & targetVM & "'")
WScript.StdOut.Write(".")
WScript.sleep 1000
Loop
WScript.Echo "Completed."
Case Else
WScript.Echo targetVM & " is not running."
End Select
Step 2: Once the VM is saved, it can be backed up. To save space on my backup drive, I prefer to zip the VHD files. My NAS device is relatively slow, so the time difference of copy vs. zip + copy is negligible for me.
This script will save the 7z file with a date prefix. If you want to keep multiple backups, such as several monthly backups, this one is handy. The "V:" drive is my mapped NAS drive.
FOR /F "TOKENS=1* DELIMS= " %%A IN ('DATE/T') DO SET XDate=%%B
For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set XDate=%%c-%%a-%%b)
7z a -t7z "V:\GPDEV1\%XDate% GPDEV1.7z" "E:\HyperVServers\GPDEV1\GPDEV1.vhd"
This script just saves the 7z file with the same name every time. I currently use this for my weekly backups.
7z a -t7z "V:\GPDEV1\GPDEV1 Weekly Backup.7z" "E:\HyperVServers\GPDEV1\GPDEV1.vhd"
Step 3: Create a Windows Task Scheduler task to save the VMs. Note that Task Scheduler does not appear to run VBS files directly, so you will need to create a batch file that calls the CScript engine. SaveGPDEV1.vbs is the file containing the VBS script listed above.
cscript C:\Scripts\SaveGPDEV1.vbs
Note that you must include the full path to your VBS file in your batch file, otherwise the command will fail if run by Task Scheduler (since it will assume a path of C:\Windows\System32\ for the vbs).
Step 4: As a second step in your new task, call the backup batch file that zips and/or copies the VHD file to your backup drive.
I currently have a weekly backup job that backs up a few VMs on Wednesday night at 11pm, and then another job that backs up a few more VMs on Friday night at 11pm. Those 7z files retain the same name and are updated each week.
I'll probably add a few more tasks that perform monthly backups with a date stamp in the file name.
This backup approach won't win any awards for cutting edge technology, but it was simple enough for me to pull together with minimal time investment, and I'm pretty confident in its reliability.
Steve Endow is a Dynamics GP Certified Trainer and Dynamics GP Certified Professional. He is also the owner of Precipio Services, which provides Dynamics GP integrations, customizations, and automation solutions.
http://www.precipioservices.com
No comments:
Post a Comment