Thursday, February 21, 2008

Backup Exec 11d and VSS Writer for Virtual Server: Putting it all together

There have been a lot of questions on how to successfully backup a running virtual machine on Microsoft Virtual Server using Backup Exec 11d. Thanks to Chris Wolf's script (built off of Jeff Trumbill's script) which uses the VSS Writer, a big piece of the puzzle has been connected. Here's how I put it all together with Backup Exec 11d:

1. Download and install the VSS Software Development Kid (SDK) to your computer (recommended not on the server)
2. Browse to C:\Program Files\Microsoft\VSSSDK72\TestApps\vshadow\bin\release-server
3. Copy vshadow.exe and vshadow.pdb to your Virtual Server at C:\Scripts
4. On the Virtual Server, browse to C:\Scripts (where the vshadow.exe and vshadow.pdb files are)
5. Create a new file called: ShadowCopy_Delete-Create.vbs (or whatever you want)
6. Paste this script into the file:


'Script deletes all shadow copy instances,
'then creates one for drive with VHD files.

Set objShell = CreateObject ("WScript.Shell")

'Drive containing Virtual Machines
strVMdrive = "D:"
'available drive letter used to mount shadow copy
strTempDrive = "V:"

'Prepare shadow copy commands for shadow copy deletions
ExCmd = "CreateVSS.cmd"
'next variable "ofilesys" also used for log file entry below
Set oFileSys = CreateObject("Scripting.FileSystemObject")
if oFileSys.FileExists(sExCmd) then oFileSys.DeleteFile(sExCmd)
set oExCmd = oFileSys.CreateTextFile(sExCmd, CopyOverwrite)

'Delete all existing shadow copy instances
oExCmd.WriteLine "Echo y vshadow.exe -da"
oExCmd.Close Result = objShell.run(sExCmd,vbMinimized, TRUE)

'Prepare shadow copy commands for shadow copy creations
ExCmd = "CreateVSS.cmd"
Set oFileSys = CreateObject("Scripting.FileSystemObject")
if oFileSys.FileExists(sExCmd) then oFileSys.DeleteFile(sExCmd)
set oExCmd = oFileSys.CreateTextFile(sExCmd, CopyOverwrite)

'Write entry to log file, which is copied into shadow copy to identify date
Set objOutFile = oFileSys.OpenTextFile(strVMdrive & "\ShadowCopyLog.txt", &_

2, True)
'Load current date (formatted as mm-dd-yyyy)
'into variable strToday
strTime = Month(Now) & "-" & Day(Now) & "-" & Year(Now) &_
"__" & hour(now) & "-" & minute(now)
strLine = "Shadow Copy Created " & strTime
objOutFile.WriteLine strLine

'Create Shadow copy of VM drive
oExCmd.WriteLine "vshadow.exe -script=setvar1.cmd -p " &_
strVMdrive
oExCmd.WriteLine "call setvar1.cmd"
oExCmd.WriteLine "vshadow.exe -el=%SHADOW_ID_1%," &_
strTempDrive
oExCmd.Close
Result = objShell.run(sExCmd,vbMinimized, TRUE)


If necessary, change strVMdrive = "D:" to the drive containing the server's VHD files.
Also, change strTempDrive = "V:" to the letter you want the volume shadow copy drive to be called.
Chris called his "X:", but I like "V:".

In Chris' original script, he copied the directory containing the VHD files to another location, and then he deleted the volume shadow copy. I changed the script so that it leaves the volume shadow copy (so a VHD can be quickly retrieved instead of going to backups), and only deleted the next time the script is run to create a new volume shadow copy. Just make sure you have enough free space on your system to handle the shadow copy if you leave it on. I also made a change so it creates a logfile on the root of the directory so I can see when the volume shadow copy was created. I did not copy the contents from the volume shadow copy to another location because Backup Exec can retrieve the files right from that volume shadow copy, eliminating the need for a copy. You can run the script to test, and a new volume shadow copy drive should eventually appear.

Let's go on to the Backup Exec component:

7. In Backup Exec 11d, create a new job, designated for backing up the VHD and VMC files
8. Go to the selection List, and insert
\\SERVER\V:\VirtualMachineDirectory
(VHD and VMC file location) for each virtual server
*Notice I'm selecting the volume shadow copy drive, not the actual drive
9. Go to Pre/Post Commands and enter: CSCRIPT.EXE D:\SCRIPTS\ShadowCopy_Delete-Create.vbs //B (or whatever you named your vbs file)
*I did not check "run job only if pre-command is successful"
*I set "cancel command if not completed within 15 minutes"
10. Set the rest of the job with your configurations, and that should be it.

If you want to delete the volume shadow copy after the backup job completes, you can enter a post command in Backup Exec to point to this script which deletes all volume shadow copies on the server:


Set objShell = CreateObject("WScript.Shell")

'Prepare shadow copy commands
sExCmd = "CreateVSS.cmd"
Set oFileSys = CreateObject("Scripting.FileSystemObject")
if oFileSys.FileExists(sExCmd) then oFileSys.DeleteFile(sExCmd)
set oExCmd = oFileSys.CreateTextFile(sExCmd, CopyOverwrite)

'Delete created shadow copy instance
oExCmd.WriteLine "Echo y vshadow.exe -da"
oExCmd.Close
Result = objShell.run(sExCmd,vbMinimized, TRUE)

We've been backing up VHD files using this method, and it has been working well. Restore tests have shown no problems. I would recommend that you store your VHD and VMC files in the same directory on the Virtual Server.
Backup Exec 12 may have built-in support for backing up running virtual machines using volume shadow copy, so be sure to check that out.


Also, be aware that Backup Exec 11d may give an error if your selection only includes the shadow copy of the virtual server, and a shadow with that same drive letter does not yet exist when the backup job starts (because BUEX has not yet run the script on the virtual server to create the shadow copy). If there's another selection from the server, it should be okay, and the script will run. But just look into that if there are problems.

Hope this helps some people out there!

- Steve Klapper