Function Clone-VMFromSnapshot { <# .SYNOPSIS Clones a VM from a Specified Snapshot .DESCRIPTION Clones a VM from a Specified Snapshot, if no snapshot is specified then it will clone from the current snapshot .NOTES Author: Ryan McLean Website: http://ninet.org .PARAMETER srcName Mandatory - VM to clone .PARAMETER dstName Mandatory - Name for the clone .PARAMETER Snapshot Optional - Snapshot on VM to clone .PARAMETER VMHost Optional - Host to register the clone on, If not specified then the same host as the machine to be cloned is used .PARAMETER Pool Optional - Resource Pool to place the clone in, If not specified then the same resource pool as the machine to be cloned is used .PARAMETER Datastore Optional - Name of the Datastore to create the clone on, If not specified then the same datastore as the machine to be cloned is used .PARAMETER CustomSpec Optional - If specified then will run the named customisation on the clone. .EXAMPLE PS> Clone-VMFromSnapshot -srcName "MyVM" -dstName "NewVM" Will clone the currentstate of "MyVM" to "NewVM" .EXAMPLE PS> Clone-VMFromSnapshot -srcName "MyVM" -dstName "NewVM" -Snapshot "Snap1" Will clone the state of "MyVM" at snapshot Snap1 to "NewVM" .EXAMPLE PS> Clone-VMFromSnapshot -srcName "MyVM" -dstName "NewVM" -Snapshot "Snap1" -VMHost "Host1" -Pool "Pool1" Will clone the state of "MyVM" at snapshot Snap1 to "NewVM" registering "NewVM" on Host1 in "Pool1" .EXAMPLE PS> Clone-VMFromSnapshot -srcName "MyVM" -dstName "NewVM" -Snapshot "Snap1" -DataStore "DS1" Will clone the state of "MyVM" at snapshot Snap1 to "NewVM" and creating it in the Datastore DS1 .EXAMPLE PS> Clone-VMFromSnapshot -srcName "MyVM" -dstName "NewVM" -Snapshot "Snap1" -CustomSpec "WinServer" Will clone the state of "MyVM" at snapshot Snap1 to "NewVM" applying the Customisation Specification "WinServer" #> [CmdletBinding()] param ( [Parameter(Mandatory=$true)][String] $srcName, [Parameter(Mandatory=$true)][String] $dstName, [String] $Snapshot, [String] $VMHost, [String] $Pool, [String] $DataStore, [String] $CustomSpec ) Process { $vm = Get-View -ViewType VirtualMachine -Property Name,Parent,Snapshot -Filter @{"Name"=$srcName} $cloneFolder = $vm.parent # Just use the same folder as the original VM for simplicity $cloneName = $dstName $cloneSpec = new-object Vmware.Vim.VirtualMachineCloneSpec $cloneSpec.Location = new-object Vmware.Vim.VirtualMachineRelocateSpec if ($VMHost) { $VMHost = Get-View -ViewType HostSystem -Property Name,Parent -Filter @{"Name"=$VMHost} $cloneSpec.Location.Host = $VMHost.MoRef $pfilter = @{"Name"=$Pool; "Owner"=$VMHost.Parent.Value} } else { $pfilter = @{"Name"=$Pool;} } if ($Pool) { $Pool = Get-View -ViewType Resource -Property Name -Filter $pfilter if (($Pool).count -gt 1) { Write-Host "Resource Pool is ambiguous, ignoring." } else { $cloneSpec.Location.Pool = $Pool.MoRef } } if ($Datastore) { $cloneSpec.Location.Datastore = (Get-View -ViewType Datastore -Property Name -Filter @{"Name"=$DataStore}).MoRef } if ($Snapshot) { $cloneSpec.Snapshot = (Get-Snapshot -Name $Snapshot -VM $vm.Name).ExtensionData.Snapshot } else { $cloneSpec.Snapshot = $vm.Snapshot.CurrentSnapshot } if($CustomSpec) { $cloneSpec.Customization = (Get-OSCustomizationSpec -Name $CustomSpec).ExtensionData.Spec } $vm.CloneVM_Task( $cloneFolder, $cloneName, $cloneSpec ) } }