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. | $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-VIServer "<vc server>" foreach ($customer in $backupinfo) $vm = Get-VM $customer.MasterVM C:\scripts\backupstartedemail.ps1 # Create new snapshot for clone $cloneSnap = $vm | New-Snapshot -Name "Clone Snapshot" # Get managed object 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 $vmView.CloneVM( $cloneFolder, $cloneName, $cloneSpec ) # Write newly created VM to stdout as confirmation # Remove Snapshot created for clone Get-Snapshot -VM (Get-VM -Name $customer.MasterVM) -Name $cloneSnap | Remove-Snapshot -confirm:$False C:\scripts\backupcompletedemail.ps1 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]" 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]" 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) |
The content of the csv file is very simple. This is what mine looks like: MasterVM,BackupDS
VM1,BackupDataStore
VM2,BackupDataStore So as you can see, it's simple, but very effective. Let me know your thoughts/Idea's on this could be improved. |