Syndicated

PowerCLI: A Simple VMware Backup Script

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:

  1. Send myself an email telling me that the backup process has started
  2. Import the name of the VM to be backed up and the destination datastore from a CSV file
  3. Create a Snapshot of the VM I want to backup
  4. 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
  5. Remove the Snapshot from the master VM
  6. 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:

About the author

Simon Long

13 Comments

    • 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.”

  • 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

  • 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.

Leave a Comment