Batch file to Suspend, Backup and Start a VM under VMWare workstation

To backup a VM running under VMware Workstation, you have to manually shutdown or suspend the VM, manually run a backup and then manually restart the VM.

I hate manual labor! So I set out to fix the problem the best way I know how. Back to the Command Line!

Below is the code for a batch file I wrote (with the help of some folks kind enough to share their code also). I’ve added logging so you can troubleshoot if you need to.

This batch file can be launched using task scheduler and requires local administrator rights to execute properly.

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: This batch file must be run as a local administrator. ::
:: Do not use a domain account with admin priveledges, the VM will not start.::
:: Quotes are required around variables because they may contain spaces. ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:: Localize environment changes, this will cleanup variables after batch completes
setlocal

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Create variables for VM. Don't forget the trailing slashes in your paths! ::
:: ::
:: Because Robocopy treats the \ as an escape character at the end an ::
:: additional trailing \ must be added to the paths used in the robocopy ::
:: command. ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

set VMWarePath=C:\Program Files (x86)\VMware\VMware Workstation\
set VMName=FM-PC.vmx
set VMPath=C:\Virtual Machines\FM-PC\\
set DestPath=E:\VM_Backups\FM-PC\\

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Setup Log ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set LogPath=C:\Batch\FM-PC2_Logs\
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: YOU SHOULD NOT NEED TO EDIT ANYTHING BELOW THIS LINE ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set LogFileExt=.log
set LogFileName=%VMName_%Daily Backup%LogFileExt%
::use set LogFile=%date:~4% instead to remove the day of the week
set LogFile=%date%
set LogFile=%LogFile:/=-%
set LogFile=%LogPath%%LogFile%_%LogFileName%

If NOT Exist "%LogFile%" goto:noseparator
Echo.>>"%LogFile%"
Echo.===================>>"%LogFile%"
:noseparator
echo.%Date% >>"%LogFile%"
echo.%Time% >>"%LogFile%"

:startwork

:: Suspend VM
"%VMWarePath%vmrun" -T ws suspend "%VMPath%%VMName%"
echo.%VMName% Suspended >>"%LogFile%"
echo. >>"%LogFile%"

:: Give the system time to release file locks
ping 127.0.0.1 -n 30 >Nul

::Take a Snapshot
"%VMWarePath%vmrun" -T ws snapshot "%VMPath%%VMName%"

:: Copy VM to Backup Drive
robocopy "%VMPath%" "%DestPath%" /MIR /LOG+:"%LogFile%" /NP /TEE
echo. >>"%LogFile%"
echo.%VMName% Back up complete. Details will be logged >>"%LogFile%"
echo. >>"%LogFile%"
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Log Robocopy exit code and reason - thanks to s64.com for base code! ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
if errorlevel 16 echo ***FATAL ERROR*** >>"%LogFile%"
if errorlevel 15 echo OKCOPY + FAIL + MISMATCHES + XTRA >>"%LogFile%"
if errorlevel 14 echo FAIL + MISMATCHES + XTRA >>"%LogFile%"
if errorlevel 13 echo OKCOPY + FAIL + MISMATCHES >>"%LogFile%"
if errorlevel 12 echo FAIL + MISMATCHES >>"%LogFile%"
if errorlevel 11 echo OKCOPY + FAIL + XTRA >>"%LogFile%"
if errorlevel 10 echo FAIL + XTRA >>"%LogFile%"
if errorlevel 9 echo OKCOPY + FAIL >>"%LogFile%"
if errorlevel 8 echo FAIL >>"%LogFile%"
if errorlevel 7 echo OKCOPY + MISMATCHES + XTRA >>"%LogFile%"
if errorlevel 6 echo MISMATCHES + XTRA >>"%LogFile%"
if errorlevel 5 echo OKCOPY + MISMATCHES >>"%LogFile%"
if errorlevel 4 echo MISMATCHES >>"%LogFile%"
if errorlevel 3 echo OKCOPY + XTRA >>"%LogFile%"
if errorlevel 2 echo XTRA >>"%LogFile%"
if errorlevel 1 echo OKCOPY >>"%LogFile%"
if errorlevel 0 echo No Change >>"%LogFile%"
echo. >>"%LogFile%"

:: Start VM
::Remove extra trailing slash from VMPath - VMware does not like this.
SET VMpath=%VMpath:~0,-1%

:: Give the system more time to release file locks
ping 127.0.0.1 -n 40 >Nul

"%VMWarePath%vmrun" -T ws start "%VMPath%%VMName%">>"%LogFile%"
echo.%VMName% Started >>"%LogFile%"

:end</pre>

2 Replies to “Batch file to Suspend, Backup and Start a VM under VMWare workstation”

  1. Hi, this doesn’t seem to work when the VM is shared in WS9. What would need to be edited for a shared vm to use this awesome script?

    • I’m using it under WS9. Are you getting any error messages or indications in the log as to why it’s failing?

      You indicated that this is a shared VM. This is not something we do in our environment. I would imagine that you need drop all of the connections to this VM. There is no vmrun command to do this.