VMware Communities
TScalzott
Enthusiast
Enthusiast

Windows CMD Script to Aid Backups

Here is a quick and dirty Windows CMD file that will backup all of the VMware WS virtual machines on your local system.

All currently running VMs are suspended first, the backup is started, and the previously running VMs are resumed.

It is fairly self explanatory, but look at the WSPath, VMPath, and BackupCommand variable settings within. If anything, it may serve as a good shell.

\---- BackupVMs.CMD -


@ECHO OFF

REM

REM Backup all virtual machines, first suspending those that are

REM currently running. Any suspended systems will be resumed

REM when complete.

REM

REM This script requires VMRUN.EXE from VMWare and SLEEP.EXE

REM from a Windows Resource Kit. SLEEP should be on your PATH

REM and the location of VMRUN is to be specified below.

REM

REM As an example, ROBOCOPY is used to make a backup of the

REM virtual machines. You'll need ROBOCOPY to be on your

REM PATH if you keep the script with the backup example

REM below.

REM

REM Author: Todd Scalzott, todd.scalzott@gmail.com.

REM

REM Use freely.

REM

SETLOCAL

REM

REM Specify where vmrun.exe can be located

SET WSPath="C:\Program Files\VMware\VMware Workstation"

REM

REM Specify where the virtual machine images are located

SET VMPath="%USERPROFILE%\My Documents\My Virtual Machines"

REM

REM Specify the command for backing up our VMs

SET BackupCommand=robocopy.exe %VMPath% "C:\My Virtual Machine Backups" /S /E /LOG:%VMPath%\backup.log

REM Get the list of currently running VMs

%WSPath%\vmrun.exe list | FIND /V "Total running VMs:" > %temp%\vmlist.txt

REM Suspend them

FOR /F "delims=*" %%v IN (%temp%\vmlist.txt) DO CALL :SuspendVM "%%v"

:waitloop

ECHO Waiting for the VMs to suspend...

REM Pause until no more VMs are running

%WSPath%\vmrun.exe list | FIND "Total running VMs: 0"

IF NOT ERRORLEVEL 1 GOTO backup

sleep 10

GOTO waitloop

:backup

REM Do the backup

ECHO.

ECHO Starting the backup...

%BackupCommand%

REM Resume the previously running VMs

FOR /F "delims=*" %%v IN (%temp%\vmlist.txt) DO CALL :ResumeVM "%%v"

ECHO.

ECHO Done.

ENDLOCAL

GOTO :EOF

:SuspendVM

REM Suspend any running VM. Workaround a "vmrun list" quirk that outputs

REM a blank line, by not trying to suspend a blank VM

IF %1x==x GOTO :EOF

ECHO.

ECHO Suspending VM "%1"

%WSPath%\vmrun.exe suspend %1

:ResumeVM

REM Resume any suspended VM. Workaround a "vmrun list" quirk that outputs

REM a blank line, by not trying to start a blank VM

IF %1x==x GOTO :EOF

ECHO.

ECHO Starting VM "%1"

%WSPath%\vmrun.exe start %1

2 Replies
CraigSlack
Contributor
Contributor

Thanks to Todd for posting this original script as I found it very useful when helping out a client of mine. However, I did encounter some syntax errors that prevented the script from running properly. I took the opportunity to upgrade the script to support VMWare Server and fixed the errors that I found. Please share and enjoy the update.

--- UpdatedBackupVMs.CMD ---

@ECHO OFF

REM

REM Backup all virtual machines, first suspending those that are

REM currently running. Any suspended systems will be resumed

REM when complete.

REM

REM This script requires VMRUN.EXE from VMWare and SLEEP.EXE

REM from a Windows Resource Kit. SLEEP should be on your PATH

REM and the location of VMRUN is to be specified below.

REM

REM As an example, ROBOCOPY is used to make a backup of the

REM virtual machines. You'll need ROBOCOPY to be on your

REM PATH if you keep the script with the backup example

REM below.

REM

REM Original Author: Todd Scalzott, todd.scalzott@gmail.com.

REM Modified for VMWare Server by: Craig Slack, dcslack@yahoo.com

REM

REM Use freely.

REM

SETLOCAL

REM

REM Specify where vmrun.exe can be located

SET WSPath="C:\Program Files (x86)\VMware\VMware Server"

REM

REM Specify where the virtual machine images are located

SET VMPath="E:\Virtual Machines"

REM

REM Specify the command for backing up our VMs

SET BackupCommand=robocopy.exe %VMPath% "B:\Virtual Machines" /S /E /LOG:%VMPath%\backup.log

REM Get the list of currently running VMs

%WSPath%\vmrun.exe -h https://192.168.0.61:8333/sdk -u USERNAME -p PASSWORD list | FIND /V "Total running VMs:" > %temp%\vmlist.txt

REM Suspend them

FOR /F "delims=*" %%v IN (%temp%\vmlist.txt) DO CALL :SuspendVM "%%v"

:waitloop

ECHO Waiting for the VMs to suspend...

REM Pause until no more VMs are running.

%WSPath%\vmrun.exe -h https://192.168.0.61:8333/sdk -u USERNAME -p PASSWORD list | FIND "Total running VMs: 0"

IF NOT ERRORLEVEL 1 GOTO backup

sleep 10

GOTO waitloop

:backup

REM Do the backup

ECHO.

ECHO Starting the backup...

%BackupCommand%

REM Resume the previously running VMs

FOR /F "delims=*" %%v IN (%temp%\vmlist.txt) DO CALL :ResumeVM "%%v"

ECHO.

ECHO Done.

ENDLOCAL

GOTO :EOF

:SuspendVM

REM Suspend any running VM. Workaround a "vmrun list" quirk that outputs

REM a blank line, by not trying to suspend a blank VM

IF %1x==x GOTO :EOF

ECHO.

ECHO Suspending VM "%1"

%WSPath%\vmrun.exe -h https://192.168.0.61:8333/sdk -u USERNAME -p PASSWORD suspend %1

GOTO :EOF

:ResumeVM

REM Resume any suspended VM. Workaround a "vmrun list" quirk that outputs

REM a blank line, by not trying to start a blank VM

IF %1x==x GOTO :EOF

ECHO.

ECHO Starting VM "%1"

%WSPath%\vmrun.exe -h https://192.168.0.61:8333/sdk -u USERNAME -p PASSWORD start %1

GOTO :EOF

:EOF

0 Kudos
0WayneH0
Hot Shot
Hot Shot

Good stuff; I was looking for something like this before and didn't  find this post. I am back again though after someone is claiming that  hibernation of the host is causing problem with VMs on start up, so I  needed to write a script to suspend all running VMs before shutting  down (instead of hibernating).

Previously I had a script that needed to modified for each new VM,  but this time I wanted to do it generically (for reasons obvious) and found this post.

So  just to share the love this is my adaptation of the scripts above,  except just for suspending VMs in a batch file called  "SuspendRunningVMs" that can be called from other batch files that may do other things before/after.

Instead of sleep it uses timeout (shouldn't need any resource kit for that) and is quite generous with those timeouts just to allow virtual memory the time to be committed to disk, plus a couple of other minor tweaks.

I didn't include the original author names in the script below, but if you feel compelled grab them from this thread.

Tested on multiple Windows 7 x64 hosts. Probably won't help anyone, but I tried at least. Smiley Wink

@echo off

echo SuspendRunningVMs Command (x64)...

SETLOCAL

REM Specify where vmrun.exe can be located
SET WSPath="C:\Program Files (x86)\VMware\VMware Workstation"

REM Get the list of currently running VMs
%WSPath%\vmrun.exe list | FIND /V "Total running VMs:" > %temp%\vmlist.txt

REM Suspend all running VMs
FOR /F "delims=*" %%v IN (%temp%\vmlist.txt) DO CALL :SuspendVM "%%v"

:WaitLoop
echo Waiting for the VMs to suspend...
REM Pause until no more VMs are running
%WSPath%\vmrun.exe list | FIND "Total running VMs: 0"
IF NOT ERRORLEVEL 1 GOTO End
timeout /t 10 /nobreak
GOTO WaitLoop

:End
echo End of script; all VMs suspended.

ENDLOCAL
GOTO :EOF

REM Suspend a VM
:SuspendVM
REM Suspend any running VM.  Workaround a "vmrun list" quirk that outputs
REM a blank line, by not trying to suspend a blank VM
IF %1x==x GOTO :EOF
echo Suspending VM %1
%WSPath%\vmrun.exe suspend %1
REM Allow some time after suspend call (allow disk to write vmem).
echo Wait a little bit for the VM to commit...
timeout /t 30 /nobreak
GOTO :EOF

REM Resume a VM (not used now, but may have use in future)
:ResumeVM
REM Resume any suspended VM.  Workaround a "vmrun list" quirk that outputs
REM a blank line, by not trying to start a blank VM
IF %1x==x GOTO :EOF
echo Starting VM %1
%WSPath%\vmrun.exe start %1
GOTO :EOF

:EOF