Well, on Friday I had a short chat with someone from one of our application departments, stating he wanted a backup copy of a VM (ain’t to hard), but a) they don’t want any downtime and b) it has to be identical to the original.

So I sat down today, googled for a bit and actually found something that pretty much does what I want, though I had to fix it up a bit … So find attached a script, which creates a hot-clone from a snapshot and then only if the latest clone was successful deletes the old one.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
param( [string] $vCenter )

# Add the VI-Snapin if it isn't loaded already
if ( (Get-PSSnapin -Name "VMware.VimAutomation.Core" -ErrorAction SilentlyContinue) -eq $null )
{
	Add-PSSnapin -Name "VMware.VimAutomation.Core"
}

if ( !($vCenter) ) {
	Write-Host ""
	Write-Host "vm-create-snapshot-clone: <vcenter> <VM-Name> <Target Datastore>"
	Write-Host "    <vcenter>          - Hostname of the vCenter Server instance for this script"
	Write-Host "                         to work on."
	Write-Host ""
	exit 1
}
# Based on http://www.simonlong.co.uk/blog/2010/05/05/powercli-a-simple-vm-backup-script/

# Import Backup CSV
$backupinfo =  Import-Csv C:ScriptsTEMPbackupvms.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 $vCenter

foreach ($customer in $backupinfo)
{
    $vm = Get-VM $customer.MasterVM
	$SCRIPTS = "C:ScriptsTEMP$( $customer.MasterVM ).txt"

    # Create new snapshot for clone
    $vm | New-Snapshot -Name "Clone Snapshot" -Description (get-date -format "'Created: 'yyyy-MM-dd HH:mm")

    # 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 )

	if (( Test-Path -Path $SCRIPTS) -ne $true ) {
		$cloneName | Out-File $SCRIPTS
	} else {
		$old_vm = Get-Content $SCRIPTS
		$cloneName | Out-File $SCRIPTS

		Get-VM $old_vm | Remove-VM -DeletePermanently -Confirm:$false
	}

    # Remove Snapshot created for clone
    Get-Snapshot -VM $vm -Name "Clone Snapshot" | Remove-Snapshot -confirm:$False
}
#Disconnect from vCenter
Disconnect-VIServer -Server $vCenter -Confirm:$false

The backupvms.csv looks pretty simple:

1
2
3
MasterVM,BackupDS
sles11-sp1,datastore2-nfs
sles10-sp4,datastore1-nfs