Posted by Simon Long May 5, 2010
PowerCLI: A Simple VM Backup Script
Just 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/Idea's on this could be improved.
Sources: