In-Depth

Backing Up Live Virtual Server VM Files

Here's how you can back up files inside running Virtual Server VMs.

After reading my article "Backing Up Live Virtual Server VMs," a couple of administrators asked me if it was possible to back up individual files or folders inside a running Virtual Server 2005 R2 SP1 VM. In other words, if the entire VM image is not needed, why back it up?

You will always want to back up entire VM images (their .vhd virtual disks and .vmc configuration files) for disaster recovery (DR) preparedness. But for frequent backups of VMs with a consistent set of data files that change, I can understand the need to limit the scope of a particular backup. Of course, the easiest way to back up a subset of files is to run a backup agent inside a VM's guest OS.

Running a local backup inside the VM guest is always the preferred method, especially if the locally installed backup agent supports VSS. However, if you're looking to back up files inside a VM from the physical host system, there is a way to do it.

Basically, backing up files inside a running VM from the physical host requires a script to do the following:

  • Create a snapshot of server's volume that stores the virtual machines.
  • Mount the snapshot to a temporary drive letter.
  • Use VHDMount to mount a given VM's VHD hard disk image file located inside the snapshot to a temporary drive letter.
  • Copy the virtual machine files to your preferred backup location, which can either be a locally mounted drive or a UNC path.

I know ... it's almost enough to make your head spin. VHDMount is a handy little tool that's included with Virtual Server 2005 R2 SP1 that allows you to locally mount a VHD image file. So to back up files inside a running VM, all we need to do is take a snapshot of the VM's VHD file, mount the VHD as a new local drive, and then back up whatever we want. For additional information on VHDMount, take a look at Ben Armstrong's blog.

Steps 1-3 require two additional tools: 1) Vshadow.exe (included in the VSS Software Development Kit (SDK)), and 2) VHDMount.exe (included with Virtual Server 2005 R2 SP1). Steps for installing the VSS SDK on the Virtual Server physical host are documented in my article "Backing Up Live Virtual Server VMs," so they are not covered here.

Once the VSS SDK is installed, you will need to create a folder on the Virtual Server system to store the backup script and its dependent vshadow.exe file. For example, in my lab I created a folder on the C drive named "scripts." Once the C:\scripts folder is created, copy the vshadow.exe and vshadow.pdb files from the "C:\Program Files (x86)\Microsoft\VSSSDK72\TestApps\vshadow\bin\release-server" folder to the "C:\scripts" folder.  Note that I deployed the VSS SDK on an x64 server. If your Virtual Server system is 32-bit, then the required vshadow files will be in the "C:\Program Files\Microsoft\VSSSDK72\TestApps\vshadow\bin\release-server" folder by default.

Next, you need to copy vhdmount.exe and its dependent files to the "scripts" folder. Vhdmount.exe is located in the "vhdmount:" subfolder of the Virtual Server installation directory. By default, you'll find all the vhdmount files in the "C:\Program Files\Microsoft Virtual Server\Vhdmount" folder. Once you navigate to the Vhdmount folder in Windows Explorer, copy all of the files in the folder to the "scripts" folder.

With all of the script dependencies in place, you have one last task - download and copy the vsfilebackup.vbs script to the C:\scripts folder. The vsfilebackup.vbs script is shown below.


'vsfilebackup.vbs
Set objShell = CreateObject ("WScript.Shell") 'Drive containing Virtual Machines strVMdrive = "D:" 'VHD file path -- start path after drive letter strVHDFilePath = "Vs\w2k3\w2k3.vhd" 'Folder inside VM to back up strVMfolder = "FS Data" 'name of VM to back up strVMname = "w2k3" 'Load current date (formatted as mm-dd-yyyy) 'into variable strToday strTime = Month(Now) & "-" & Day(Now) & "-" & Year(Now) &_   "_" & hour(now) & "-" &  minute(now) 'Backup target folder or UNC path strBackupLoc = "E:\Backup\VS\" 'available drive letter used to mount shadow copy strTempDrive = "X:" 'available drive letter used to mount vhd image file strVHDMountDrive = "Y" 'Format backup folder path to include VM name 'and a date/time stamp strBackupDir = strBackupLoc & strVMname & "-" &_    strTime & "\"

'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)

'create backup folder Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFolder = objFSO.CreateFolder(strBackupDir)

' 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)

'mount VHD file from snapshot strVHDMountcmd = "vhdmount /m " & chr(34) & strTempDrive &_    "\" & strVHDFilePath & chr(34) & " " & strVHDMountDrive Result = objshell.run(strVHDMountcmd, vbminimized, TRUE)

'Copy the virtual machine files from the shadow copy strSource = strVHDMountDrive & ":\"  & strVMfolder objFSO.CopyFolder strSource, strBackupDir, TRUE

'Unmount VHD File strVHDMountcmd = "vhdmount /u /d " & chr(34) & strTempDrive &_    "\" & strVHDFilePath & chr(34) Result = objshell.run(strVHDMountcmd, vbminimized, TRUE)

' Delete created shadow copy instance if oFileSys.FileExists(sExCmd) then oFileSys.DeleteFile(sExCmd) set oExCmd = oFileSys.CreateTextFile(sExCmd, CopyOverwrite) oExCmd.WriteLine "Echo y | vshadow.exe -da" oExCmd.Close Result = objShell.run(sExCmd,vbMinimized, TRUE)

'Backup complete! wscript.echo("Backup complete!")

Note that the script uses the shadow copy logic from Jeff Trumbull's backup script. Jeff's vshadow.exe scripting logic was spot-on, so I decided not to reinvent the wheel. The script leverages VS Writer, allowing it to back up contents of open VHD files and maintain consistency. Without VS Writer involved in the snapshot creation process, file recoverability could not be guaranteed and the VM would have to be suspended prior to backup. VS Writer only works for VMs that support VSS (such as Windows 2003) and for VMs that have the most recent version of the VM additions installed.

To use the script in your environment, you will need to modify the following variables:

  • strVMdrive
  • strVHDFilePath
  • strVMfolder
  • strVMname
  • strBackupLoc
  • strTempDrive
  • strVHDMountDrive

strVMdrive is the drive letter of the drive that stores the VM files. Since shadow copies occur at the volume level, it's most economical to back up all Virtual Server VMs on a given drive at the same time. Since the script in this article is used to back up files inside a single VM, ideally the VM would be stored on a dedicated drive. Any VMs on the same drive as the VM you are backing up would be included in the snapshot. VMs with guest operating systems that do not support VSS backups would be automatically suspended during the snapshot creation process and resumed once the snapshot is created.

strVHDFilePath indicates the path to the VHD file containing the files you need to back up. Note that the strVHDFilePath value does not include the drive letter. So if VHD file whose contents you wanted to back up was stored in the "D:\vs\w2k3\w2k3.vhd" file, you would set the strVMDrive variable to "D:" and the strVHDFilePath variable to "vs\w2k3\w2k3.vhd."

strVMfolder points to the folder located inside the VM's associated VHD file that you wish to back up. Note that the drive letter is not indicated in the variable. So to back up the "C:\FS Data" you would set the variable to "FS Data."

strVMname identifies the host name of the VM you are backing up. This variable is used to define the backup folder name so that it is easy to locate a backup for a particular VM.

strBackupLoc should be set to the target location for the backup files. This could be a local mount such as "E:\Backup\VS" or a UNC path such as "\\fs1.redmondmag.com\vs1\backup."

strVHDMountDrive defines the temporary drive letter assigned to the VM's VHD file once it is mounted as a local drive. Note that the script assumes a single partition per virtual hard disk. If multiple partitions exist, the strVHDMountDrive variable would need to be redefined after it is used to mount the VHD file. The VHDMount drive variable defines the first letter assigned to a mounted VHD file. If multiple partitions exist in the file, then each subsequent partition would get a drive letter assigned as well, with the first partition receiving the letter defined by the strVHDMountDrive variable. For example, if strVHDMountDrive was set to "R," the first partition on the VHD file would be mounted as the local R drive, the second partition would be mounted as the S drive, and so on. For example, if you defined strVHDMountDrive to "R" and needed to back up files on the second partition of the drive, you would do the following:

  • Add a line after the "'Copy the virtual machine files from the shadow copy" line in the script.
  • Redefine the strVHDMount drive variable so that it points to drive letter S by using the following syntax:

strVHDMountDrive = "S"

strTempDrive is used to designate an available drive letter that will be used to mount the shadow copy during the backup. By default, the drive letter X is used.

The script creates a backup folder named after the VM being backed up, along with the date and time of the backup. The folder's contents will include the folder identified in the strVMFolder variable, and any of its subfolders.

I wrote this script to solve a specific inquiry that I had from two readers. Again, the easiest way to back up a specific folder inside a VM's guest OS is by running a backup agent (or using Windows Backup) inside the VM. As you can see, backing up individual files externally is a bit of a challenge, yet is still possible. You may find that such a backup is not needed, but the ability to capture a snapshot of a running VHD file and locally mount the VHD file copy may be something you could use. For example, you could use the script to independently capture a copy of server files for test or auditing purposes. If an external file backup is not be exactly what you need, hopefully you'll be able to put the script logic described in this article to other uses.

About the Author

Chris Wolf is VMware's CTO, Global Field and Industry.

Featured

Subscribe on YouTube