Quantcast
Channel: VMware Communities : Popular Discussions - VMware Server 1
Viewing all articles
Browse latest Browse all 74849

Advanced VB script for backup of VMs on Windows hosts

$
0
0

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.

 

' 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


Viewing all articles
Browse latest Browse all 74849

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>