VMware Communities > VMTN > VMware Server > VMware Server 1 > Discussions
1 2 3 ... 24 Previous Next
356 Replies Last post: Jun 24, 2009 8:21 AM by saxa
Reply

Advanced VB script for backup of VMs on Windows hosts

Oct 16, 2006 11:41 AM

Click to view saxa's profile Master saxa 1,336 posts since
Jun 2, 2006
Please advice. I worked about 5 days on it, and it's awesome, IMHO.

Read the leading comment attentively. Save the code as vm-backup.vbs. Enjoy. Share your comments.

[code]
' Copyleft saxa aka Alexander Kaufmann, 2006
'
' Written just for fun; total Open Source.
' Use it at your own risk.
'
' The script uses the VmCOM API for the virtual machine operations.
'
' The virtual machine *must* have the VMware Tools installed, in order to perform the
' shutdown and heartbeat operations correctly.
'
' DON'T APPLY THIS SCRIPT ON RUNNING VIRTUAL MACHINES WHICH DON'T HAVE THE VMWARE TOOLS INSTALLED.
'
' It works on Windows 2000 SP4 and newer; it doesn't use the NTBackup utility.
'
' The script runs on the local host only; it cannot be used to connect to a remote VMware Server.
' The script *can* backup to the network share, if you have the appropriate permissions to do it.
'
' For the backup jobs it uses the command line version of 7zip: get it on http://7zip.org/download.html.
' You need the "7-Zip Command Line Version". Or, just download the full install - there is also a 64 bit
' version available.
'
' We assume that the 7zip executable is included in your %PATH% variable.
' Most probably you already have a folder with your tools, where you will also save this script.
' We have on each of our servers the folder C:\Program files\myTools created and it is added to %PATH%.
'
' Please see Windows Help on how to add a folder to %PATH%.
'
' Here I go again (c) ;))
'
' To use the command line version of this script (non-interactive mode):
' We assuming that all of our .vmx files are named vm.vmx.
' The name itself doesn't matter, but it must be the same for every virtual machine.
' If you don't like vm.vmx, please change the following variable correspondingly.

vmfile = "vm.vmx"

' We also assume that all of your virtual machines are located in the appropriate subdirectories
' of *one* directory; in other words, we need a flat structure.
' See the variable "vmpath" and change it to your needs.
' Here is a sample of correct directory layout:
'
' D:\Virtual Machines\
' Virtual Machine 1\
' vm.vmx
' hdd1.vmdk
' hdd1-flat.vmdk
' hdd2.vmdk
' hdd2-flat.vmdk
' other_file.ext
' Virtual Machine 2\
' vm.vmx
' disks\
' some weird disk 1.vmdk
' some weird diskette.flp
'
' As you can see, subdirectories are also allowed. It's only important that your .vmx file is placed
' on the (in this sample) second level, say, the full path to .vmx must be
' D:\Virtual Machines\Virtual Machine X\vm.vmx for every virtual machine.
'
' The subdirectory where the virtual machine is located is very important for this script:
' it's the virtual machine's identifier.
' In our sample these are "Virtual Machine 1" and "Virtual Machine 2" respectively.
'
' You will start the script as follows:
'
' vm-backup.vbs "Virtual Machine 1"
'
' or
'
' vm-backup.vbs "Virtual Machine 2"
'
' to backup the Virtual Machine 1 or Virtual Machine 2.
'
' If you want to use the script in a sheduled task, you must use the following command line:
'
' wscript.exe vm-backup.vbs "Virtual Machine 1"
'
' to backup the Virtual Machine 1.
'
' The script does the following:
'
' The virtual machine gets the command to shut down it's operating system.
' The script waits 30 seconds and than checks the state of the virtual machine.
' If the vm still runs, the script waits 30 seconds more and so on.
' As soon as the vm is off, the script copies the vm's folder into the backup location
' (see the "bkpath" variable and change it if you would like to; UNC paths are accepted).
'
' If the vm couldn't be shut down, the mail is sent to the admin,
' the error is written in the Windows application log.
'
' After the copying is done, the vm receives the command to start, if it was running before the operation has begun.
' 30 seconds later, and then every 30 seconds, the script checks the heatbeat of the vm.
' As soon as the vm at 300 or more units of heartbeat, the script starts to create
' a compressed archive from a previously copied vm directory.
' At that point of time is the vm already up and running.
' A .zip archive receives the following name: YYYY-MM-DD-HHMMSS-Virtual Machine 1.zip
' The creation of the .zip file takes it's time: on Pentium 4 (with Hyperthreading, single core)
' 2.8 GHz machine with 3 GB RAM is the duration of compress operation on a virtual machine
' having 2 virtual HDDs at 16 and 36 GB was about 2 hours. Though it is worth the effort:
' the resulting file has the size of 3.6 GB: compare it to 52 GB uncompressed .
' So, after the .zip file is ready, the script checks if there were any errors produced by 7zip.
' If there are some, the Windows Application log is misused for the registration of them.
' If not, then we can safely delete the copy of the vm used as a source for compression
' and create the record of successful backup operation in the Application log.

' The interactive mode (if you start the script without any parameters) does the same.
' You can manually name your zip file.

' Added on 2006-10-16; now is in Beta-Testing

' It's also possible to run a script as following (quite interesting for "scripting of this script"):

' vm-backup.vbs "X:\Full Path To vmx File\My vmx file.vmx" "Y:\Full Path To Some zip File\bla\Any name.zip"

' The script will backup the directory "X:\Full Path To vmx File\" including all subdirectories.

' Why it's Beta:
' The script will *not* create the directory ""Y:\Full Path To Some zip File\bla\"

vmpath = "D:\Virtual Machines\"

' Please don't forget the ending backslash!
' vm -> Directory where the VM files are located: the machine name is received from the argument.

' bkpath -> Destination directory; here are temporary backups created,
' and here you will find your .zip files.
' The user who runs the script must have the write permissions on directory / network share.

bkpath = "E:\backups\"

' In the variable seven_zip_switch you can provide the additional switches for the command line of 7zip.
' The most thinkfully switch is " -v4g" (don't forget the leading space!). It causes the splitting of your
' archive into volumes at 4 GB. Please read the 7zip's manual about the -v switch.

seven_zip_switch = ""

adminmail = "mail@domain.com" 'Here you'll receive mail messages.

smtp = "smtp.domain.com" 'Your SMTP server must be able to relay the mails for your mail address. IP address is also OK.


On Error Resume Next

' Common definitions...

Set wshShell = CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
Set cp = CreateObject("VmCOM.VmConnectParams")
Set server = CreateObject("VmCOM.VmServerCtl")
Set thevm = CreateObject("VmCOM.VmCtl")
Set wshNet = CreateObject("WScript.Network")
Set mailing = CreateObject("CDO.Message")

mailing.From = lcase(wshNet.UserName & "@" & wshNet.ComputerName & "." & wshNet.UserDomain)
mailing.To = adminmail
mailing.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
mailing.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = smtp
mailing.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25

header = "Backup Script for VMware Virtual Machines" 'Just the title for message boxes...

Function iso_date(byval dt)

' The function does nothing interesting...

dim y: y=year(dt)
dim m: m=month(dt)
dim d: d=day(dt)
dim h: h=hour(dt)
dim n: n=minute(dt)
dim s: s=second(dt)

if m < 10 then m="0" & m
if d < 10 then d="0" & d
if h < 10 then h="0" & h
if n < 10 then n="0" & m
if s < 10 then s="0" & s

iso_date = y & "-" & m & "-" & d & "-" & h & n & s

end Function

' Here we are getting the name of the VM delivered by the script argument; it must one or two.
' If there are two, it means, user want to define the VM and backup location manually.
' If there are more than two, it's an incorrect call.

Set args = WScript.Arguments

If args.Count=1 Then 'We are in the mode with predefined vm by parameter, way = "a(utomatic)"
vm = args(0)
vmfolder = vmpath & vm
vmfile = vmfolder & "\" & vmfile

zipfile = bkpath & vm & "-" & iso_date(now) & ".zip"

tmpfolder = bkpath & vm

way = "a"

ElseIf args.Count=0 Then 'We are in the interactive mode, way = "i(nteractive)"

vmfile = inputBox("Please enter the full path to the .vmx file of the virtual machine you want to backup:",header,vmpath)

' Quit if cancel

if vmfile = "" then

WScript.Quit

end if

vmfolder = fso.GetParentFolderName(vmfile)

vmparent = fso.GetParentFolderName(vmfolder)

vm = Replace(Replace(vmfolder, vmparent, ""),"\","")

bkfile = bkpath & vm & "-" & iso_date(now) & ".zip"

zipfile = inputBox("Now, please enter the full path to the .zip file the script will create:",header,bkfile)

' Quit if cancel

if zipfile = "" then

WScript.Quit

end if

tmpfolder = fso.GetParentFolderName(zipfile) & "\" & vm

way = "i"

' New Section: for working with 2 args

ElseIf args.Count=2 Then 'We are in the automatic mode with 2 Arguments: VM and backup location

vmfile = args(0)

vmfolder = fso.GetParentFolderName(vmfile)

vmparent = fso.GetParentFolderName(vmfolder)

vm = Replace(Replace(vmfolder, vmparent, ""),"\","")

' bkfile = bkpath & vm & "-" & iso_date(now) & ".zip"

zipfile = args(1)

tmpfolder = fso.GetParentFolderName(zipfile)

' Here we should check if the tmpfolder exists: dunno if it will be automatically created...
' If not, it should be created on this place programmatically...

way = "a"

' /New Section

Else

' There is more than one argument provided: write the error message into the application log and bye.
' There is no message box / email here.

errNoVMfile = "Incorrect Input." & VbCrLf & "The directory where the Virtual Machine files" & VbCrLf & "are resided must be provided as argument." & VbCrLf & "If the directory name contains spaces," & VbCrLf & "please add the " & Chr(34) & " sign at the beginning" & VbCrLf & "and at the end of the Virtual Machine's name." & VbCrLf & "The reading of the source code" & VbCrLf & "of the vm-backup.vbs script may help ;)"

wshShell.LogEvent 1, errNoVMfile

WScript.Quit

End If

' Try to connect to server 10 times

connected = False
For tries_srv = 1 To 10
server.Connect cp
If Err.number = 0 Then
connected = True
Exit For
End If
WScript.Sleep 10000
Err.clear
Next

If Not connected Then

'Connection to server couldn't be established; we write something into the application log or/and send a message...

errNoConnectSRV = "The Backup Script for VMware Server couldn't create an appropriate connection." & VbCrLf & "Please check if all of the VMWare Services are up and running." & VbCrLf & "Please keep in mind, you can run this script on the local host only."

wshShell.LogEvent 1, errNoConnectSRV

mailing.Subject = header & ": Critical Error"
mailing.TextBody = errNoConnectSRV
mailing.Configuration.Fields.Update
mailing.Send

if way = "i" Then
crySRV = msgBox(errNoConnectSRV,vbCritical,header)
end if

WScript.Quit

End If


' Connect to the virtual machine. You remember, what the "vmfile" is?

' Try to connect to vm 10 times

connected_m = False
For tries_vm = 1 To 10
thevm.Connect cp, vmfile
If Err.number = 0 Then
connected_m = True
Exit For
End If
WScript.Sleep 1000
Err.clear
Next

If Not connected_m Then

'Connection to vm couldn't be established; we write something into the application log or/and send a message...

errNoConnectVM = "The Backup Script for VMware Server couldn't connect to the virtual machine " & vmfile & "." & VbCrLf & "Please check if the path to .vmx file correct is and if the virtual machine is registered on your server." & VbCrLf & "Please keep in mind, you can run this script on the local host only."

wshShell.LogEvent 1, errNoConnectVM

mailing.Subject = header & ": Critical Error"
mailing.TextBody = errNoConnectVM
mailing.Configuration.Fields.Update
mailing.Send

if way = "i" Then
cryVM = msgBox(errNoConnectVM,vbCritical,header)
end if

WScript.Quit

End If

' Enough with checking
' Get the ExecutionState of the vm to know if it must be started after backup complete

' Const vmExecutionState_Off = 2
' Const vmExecutionState_On = 1
' Const vmExecutionState_Stuck = 4
' Const vmExecutionState_Suspended = 3
' Const vmExecutionState_Unknown = 5

' now we need only 2 states

ps = thevm.ExecutionState

if ps = 1 then

was_on = true ' It must be powered on after backup

elseIf ps = 2 then

was_on = false ' After backup do nothing

else

' If vm stucks, suspended or in unknown state... Who needs such backups? We create some errors.

errState = "The Backup Script for VMware Server couldn't get the correct state of the virtual machine " & vmfile & "." & VbCrLf & "Correct states are on and off only." & VbCrLf & "A vm with pending question, such as new SID after copying or moving, cannot be backed up, too."

wshShell.LogEvent 1, errState

mailing.Subject = header & ": Critical Error"
mailing.TextBody = errState
mailing.Configuration.Fields.Update
mailing.Send

if way = "i" Then
cryVM = msgBox(errState,vbCritical,header)
end if

WScript.Quit

end If

' Heartbeat. It's the approximate number of seconds from the start of VMWare Tools inside the vm.

hb = thevm.Heartbeat

if was_on = true then

if hb < 1 then ' VMWare Tools not installed or cannnot be contacted...

' VM without VMWare Tools can only be backed up if it was off...

errTools = "The Backup Script for VMware Server couldn't contact the VMWare Tools on the virtual machine " & vmfile & "." & VbCrLf & "Therefore it cannot be shut down correctly." & VbCrLf & "Please shut down the vm manually. Afterwards it can be backed up."

wshShell.LogEvent 1, errTools

mailing.Subject = header & ": Critical Error"
mailing.TextBody = errTools
mailing.Configuration.Fields.Update
mailing.Send

if way = "i" Then
cryTools = msgBox(errTools,vbCritical,header)
end if

WScript.Quit

end if

end if

' start/stop
' Const vmPowerOpMode_Hard = 1
' Const vmPowerOpMode_Soft = 2
' Const vmPowerOpMode_TrySoft = 3

' Now stopping...

getoff = thevm.stop(2)

isoff = False

For tries_off = 1 To 10
ps = thevm.ExecutionState
If ps = 2 Then
isoff = True
Exit For
End If
WScript.Sleep 60 * 1000
ps = 0

Next

If Not isoff Then

'The vm couldn't be shut down: very critical...

errNoShutDown = "The Backup Script for VMware Server couldn't shut down the virtual machine " & vmfile & "." & VbCrLf & " in a reasonable time." & VbCrLf & "Please check it's state."

wshShell.LogEvent 1, errNoShutDown

mailing.Subject = header & ": Critical Error"
mailing.TextBody = errNoShutDown
mailing.Configuration.Fields.Update
mailing.Send

if way = "i" Then
cryNoShutDown = msgBox(errNoShutDown,vbCritical,header)
end if

WScript.Quit

end if

' Machine is shut down and can be copied

copyVM = fso.CopyFolder(vmfolder,tmpfolder) 'checked

' Machine copied!

if was_on = true then 'Power on the vm if it was on

geton = thevm.start(2)

' Wait until the heartbeat becomes more than 300

ison = False

For tries_on = 1 To 20
hbs = thevm.Heartbeat
If hbs > 300 Then
ison = True
Exit For
End If
WScript.Sleep 30 * 1000
hbs = 0

Next

If Not ison Then

'The vm couldn't be start up: very critical...

errNoStart = "The Backup Script for VMware Server couldn't power on the virtual machine " & vmfile & "." & VbCrLf & " in a reasonable time. Maybe the machine could not start the VMWare Tools." & VbCrLf & "Please check it's state and / oder configuration."

wshShell.LogEvent 1, errNoStart

mailing.Subject = header & ": Critical Error"
mailing.TextBody = errNoStart
mailing.Configuration.Fields.Update
mailing.Send

if way = "i" Then
cryNoStart = msgBox(errNoStart,vbCritical,header)
end if

WScript.Quit

end if

end if

' Now the vm is up and running. It is copied and ready to be compressed

backup_string = "7za a -tzip " & chr(34) & zipfile & chr(34) & " " & chr(34) & tmpfolder & "\*" & chr(34) & seven_zip_switch

' Now create the archive...

backup_vm = wshshell.Run(backup_string,0,true)

if backup_vm > 0 then

' The zip file wasn't created

errNozip = "The Backup Script for VMware Server couldn't create a zip file." & VbCrLf & "Please check if you have enough disk space on " & tmpfolder & " and run / shedule the backup script again."

wshShell.LogEvent 1, errNozip

mailing.Subject = header & ": Critical Error"
mailing.TextBody = errNozip
mailing.Configuration.Fields.Update
mailing.Send

if way = "i" Then
cryNoZip = msgBox(errNozip,vbCritical,header)
end if

WScript.Quit

end if

' Now delete the temporary backup folder...

deltmp = fso.deleteFolder(tmpfolder) 'should be ok

' And send some messages.

success_message = "The Backup Script for VMware Server backed up the virtual machine " & vmfile & " successfully." & VbCrLf & "Backup is saved as " & zipfile & "."

wshShell.LogEvent 0, success_message

mailing.Subject = header & ": Operation Successfully Completed"
mailing.TextBody = success_message
mailing.Configuration.Fields.Update
mailing.Send

if way = "i" Then
cryS = msgBox(success_message,vbExclamation,header)
end if

WScript.Quit [/code]

Message was edited by:
RDPetruska
Updated Script by Saxa

Reply Re: Advanced VB script for backup of VMs on Windows hosts Sep 13, 2006 9:57 AM
Click to view saxa's profile Master saxa 1,336 posts since
Jun 2, 2006
Found a minor error: the "fso" object is declared twice...
Reply Re: Advanced VB script for backup of VMs on Windows hosts Sep 14, 2006 12:11 AM
Click to view 20thCB's profile Novice 20thCB 13 posts since
Sep 14, 2006
I'm trying this now :-)
Reply Re: Advanced VB script for backup of VMs on Windows hosts Sep 14, 2006 12:42 AM
in response to: 20thCB
Click to view 20thCB's profile Novice 20thCB 13 posts since
Sep 14, 2006
Well I tried it in interactive mode and it worked perfectly! This could be a real lifesaver for me, thanks for writing it.

I may have some trouble in command-line mode as my naming convention for disks is:

<servername>_c-drive.vmdk
<servername>_d-drive.vmdk

but I guess I can hack your script to work around this.

Thanks again for writing this.

Martin
Reply Re: Advanced VB script for backup of VMs on Windows hosts Sep 14, 2006 12:58 AM
in response to: 20thCB
Click to view 20thCB's profile Novice 20thCB 13 posts since
Sep 14, 2006
One thing I noticed - when the VM came back up and I logged on, I got a "windows previous shutdown was unexpected" dialog. Does the script do a clean guest shutdown?
Reply Re: Advanced VB script for backup of VMs on Windows hosts Sep 14, 2006 1:33 AM
in response to: 20thCB
Click to view saxa's profile Master saxa 1,336 posts since
Jun 2, 2006
Naming convention for disks doesn't matter.

Interesting is the naming of your .vmx files
Reply Re: Advanced VB script for backup of VMs on Windows hosts Sep 14, 2006 1:37 AM
in response to: 20thCB
Click to view saxa's profile Master saxa 1,336 posts since
Jun 2, 2006
Does the script do a clean guest shutdown?

Sure!

If it was impossible for the script to shut down the VM gracefully, it raises an error - via mail and in the application log - but it doesn't do a brutal power off.

Could you describe what did you see while the script was running, step by step?
Reply Re: Advanced VB script for backup of VMs on Windows hosts Sep 14, 2006 5:49 AM
Click to view kwest's profile Lurker kwest 5 posts since
Sep 12, 2006
Hello,
I used your script! It works great but I think I am missing something.
I am having a problem with the script.
The script shuts down my virtual machine.
and it creates a folder in the backup path.
and it copies the files to the folder.
it then restarts the virtual machine and then instead of zipping the files
it seems to delete the folder.
could you show me what change I need to make to the script.

Thank you very much,

Ken
Reply Re: Advanced VB script for backup of VMs on Windows hosts Sep 14, 2006 10:07 AM
in response to: kwest
Click to view saxa's profile Master saxa 1,336 posts since
Jun 2, 2006
Hello Ken,

have you read the leading comment?

[code]
' For the backup jobs it uses the command line version of 7zip: get it on http://7zip.org/download.html.
' You need the "7-Zip Command Line Version". Or, just download the full install - there is also a 64 bit
' version available.
'
' We assume that the 7zip executable is included in your %PATH% variable.
' Most probably you already have a folder with your tools, where you will also save this script.
' We have on each of our servers the folder C:\Program files\myTools created and it is added to %PATH%.
'
[/code]

The 7zip executable 7za.exe couldn't be found in your %PATH%.

Some errors in Application Log?
Reply Re: Advanced VB script for backup of VMs on Windows hosts Sep 14, 2006 10:13 AM
Click to view kwest's profile Lurker kwest 5 posts since
Sep 12, 2006
Yes indeed.
I also downloaded 7zip and installed it.
and I made sure it was in my path.

thanks
Reply Re: Advanced VB script for backup of VMs on Windows hosts Sep 14, 2006 10:20 AM
Click to view saxa's profile Master saxa 1,336 posts since
Jun 2, 2006
What I'm really missing:

there is no "disconnect" method, nor for VmCOM.VmServerCtl neither for VmCOM.VmCtl.

So, the script stays connected to the server and to the vm all the time. I would close both connections after the Line 476 :)
Reply Re: Advanced VB script for backup of VMs on Windows hosts Sep 14, 2006 10:22 AM
in response to: kwest
Click to view saxa's profile Master saxa 1,336 posts since
Jun 2, 2006
I also downloaded 7zip and installed it.

Have you got the 7za.exe?

Open the command prompt and type in "7za" without quotation marks. What are you getting?

7za doesn't need to be installed, it's a plain executable.

Message was edited by:
saxa
Reply Re: Advanced VB script for backup of VMs on Windows hosts Sep 14, 2006 10:23 AM
Click to view kwest's profile Lurker kwest 5 posts since
Sep 12, 2006
I down loaded the windows 7z442.msi.
but that does not installed 7z.exe.
should i uninstall and install the command line version?

thanks
Reply Re: Advanced VB script for backup of VMs on Windows hosts Sep 14, 2006 10:28 AM
in response to: kwest
Click to view saxa's profile Master saxa 1,336 posts since
Jun 2, 2006
should i uninstall

No need for it. If you added "C:\Program files\7zip" to path, just copy the 7za.exe into this directory.

Or, just copy it into %WINDIR%\System32...
Reply Re: Advanced VB script for backup of VMs on Windows hosts Sep 14, 2006 10:29 AM
in response to: kwest
Click to view saxa's profile Master saxa 1,336 posts since
Jun 2, 2006
but that does not installed 7z.exe.

Sure it did. But you need 7za.exe
1 2 3 ... 24 Previous Next
Actions