Lately I’ve been doing a lot of work in a lab environment. Some of the work I’m doing is quite important to me so I decided to workout a way I can backup my VM’s onto a backup device. To my surprise this was pretty simple to do.
Here is how I decided the script should function:
- Send myself an email telling me that the backup process has started
- Import the name of the VM to be backed up and the destination datastore from a CSV file
- Create a Snapshot of the VM I want to backup
- Create a Clone’d VM from the Snapshot
- Place the backup onto my Backup Datastore
- Name the backup <master VM name>-<date stamp>
- Thin provision the backup
- Remove the Snapshot from the master VM
- Send myself an email telling me that the backup process has completed
So that’s what I wanted to do, this is what I ended up with.
Backup Script
# Import Backup CSV $backupinfo = Import-Csv C:\scripts\mybackups.csv #Set Date format for clone names $date = Get-Date -Format "yyyyMMdd" #Set Date format for emails $time = (Get-Date -f "HH:MM") #Connect to vCenter Connect-VIServer "<vc server>" foreach ($customer in $backupinfo) { $vm = Get-VM $customer.MasterVM #Send Start Email C:\scripts\backupstartedemail.ps1 # Create new snapshot for clone $cloneSnap = $vm | New-Snapshot -Name "Clone Snapshot" # Get managed object view $vmView = $vm | Get-View # Get folder managed object reference $cloneFolder = $vmView.parent # Build clone specification $cloneSpec = new-object Vmware.Vim.VirtualMachineCloneSpec $cloneSpec.Snapshot = $vmView.Snapshot.CurrentSnapshot # Make linked disk specification $cloneSpec.Location = new-object Vmware.Vim.VirtualMachineRelocateSpec $cloneSpec.Location.Datastore = (Get-Datastore -Name $customer.BackupDS | Get-View).MoRef $cloneSpec.Location.Transform = [Vmware.Vim.VirtualMachineRelocateTransformation]::sparse $cloneName = "$vm-$date" # Create clone $vmView.CloneVM( $cloneFolder, $cloneName, $cloneSpec ) # Write newly created VM to stdout as confirmation Get-VM $cloneName # Remove Snapshot created for clone Get-Snapshot -VM (Get-VM -Name $customer.MasterVM) -Name $cloneSnap | Remove-Snapshot -confirm:$False #Send Complete Email C:\scripts\backupcompletedemail.ps1 } #Disconnect from vCentre Disconnect-VIServer -Confirm:$false
Send Started Email Script
#Set Date format for emails $timestart = (Get-Date -f "HH:MM") $emailFrom = "<senders address>" $emailTo = "<recipients address>" $subject = "[$vm - Backup Started]" $body = "Backup Details ------------- VM Name:",$vm," Clone Name:","$vm-$date"," Target Datastore:", $customer.BackupDS," Time Started:", $timestart $smtpServer = "<smtp server>" $smtp = new-object Net.Mail.SmtpClient($smtpServer) $smtp.Send($emailFrom,$emailTo,$subject,$body)
Send Completed Email Script
#Set Date format for emails $timecomplete = (Get-Date -f "HH:MM") $emailFrom = "<senders address>" $emailTo = "<recipients address>" $subject = "[$vm - Backup Complete]" $body = "Backup Details ------------- VM Name:",$vm," Clone Name:","$vm-$date"," Target Datastore:", $customer.BackupDS," Time Started:", $timestart," Time Completed:", $timecomplete $smtpServer = "<smtp server>" $smtp = new-object Net.Mail.SmtpClient($smtpServer) $smtp.Send($emailFrom,$emailTo,$subject,$body)
Content of CSV
The content of the csv file is very simple. This is what mine looks like:
MasterVM,BackupDS
VM1,BackupDataStore
VM2,BackupDataStore
Summary
So as you can see, it’s simple, but very effective. Let me know your thoughts/ideas on this could be improved.
Sources:
[…] A friend on the Danish VMUG pointed me towards this simple backup script, from GestaltIT.com. http://gestaltit.com/all/tech/virtualization/simon/vmware-backup-powercli-script/ […]
Nice, does this work with the read-only remote CLI of free ESXi too?
No, it will not work with the Free ESXi. I tested this script with ESXi 5.1 free. An error was returned creating the snapshot that indicated “Current license or ESXi version prohibits executionÂ
of the requested operation.”
please post a example of the csv file
please post a example of the csv file
The emails aren’t quite right — MM is Month, mm is minute – so should be $time = (Get-Date -f “HH:mm”)
Is it possible to implement new-snapshot “-Quiesce $true” into this script??
Have problems using this script with ESXi 3.5 free version.
Found posts on fix for this that involve activating the SSH service which has been applied and works but this has not fixed my RestrictedVersion errors with line 23, char 33, the first instance of trying to write to the host.
Getting error with clone creation as below that I cannot get through.
Any ideas welcome!
Exception calling “CloneVM” with “3” argument(s): “The operation is not supported on the object.”At C:ScriptsBackupVMs.ps1:43 char:17+   $vmView.CloneVM <<<< ( $cloneFolder, $cloneName, $cloneSpec )  + CategoryInfo      : NotSpecified: (:) [], MethodInvocationException  + FullyQualifiedErrorId : DotNetMethodException
[…] Searching for way’s to create easy backup’s of a few virtual machines, i came on the website gestalt it (http://gestaltit.com/all/tech/virtualization/simon/vmware-backup-powercli-script/). […]
It looks like your theme is currently clipping off code:
# Make linked disk specification
$cloneSpec.Location = new-object Vmware.Vim.VirtualMachineRelocateSpec
$cloneSpec.Location.Datastore = (Get-Datastore -Name $customer.BackupDS | Get-View).MoRef
$cloneSpec.Location.Transform = [Vmware.Vim.Virtualfor example. Could you re-post the missing stuff? Thanks!
Thank you so much! it works fine to me. I have just few questions. i Would like to remove my Vm’s clone from my inventary, ’cause i only want to make a backup and put it in a safe DataSource. Also, i think to make it automatically, creating a weekly task. So do i need to remove the date from VM’s clone name? or there’s another way to make an incremental clone. Thank you so much! You did a great job scripting this! We saved our company to spend a lot of money with Vsphere backup solution. Just fast, easy and simple.
You saved our company. Sorry for my bad english. i’m just a poor brazilian IT guy.