Essentially I have a base VM with an OS disk and a workload disk, each on separate datastores, and I'd like to clone this VM out many times, with each cloned VM also having its disks on two separate datastores.
Is this possible to do in PowerCLI 6.5, and if so, how?
Thanks!
Yes and no, not with the regular cmdlets, I'm afraid.
But you could do this with the CloneVM method.
With the Spec.Location.DeviceChange one can specify for each device where it should go.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
But wait a minute, you mention VHD, not VMDK.
You are talking about a VM in vSphere?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I meant VMDK, sorry about that! I'll look into the method you mentioned, thanks!
If you can get it working, let me know.
I can cook up a sample script
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
A sample script would be really helpful if you don't mind, thanks!
Sure, this is a very simple version.
You provide a datastorename for each harddisk in your master VM.
$masterName = 'MasterVM'
$cloneName = 'CloneVM'
$tgtFolder = 'Clones'
$tgtDatastores = 'DS1','DS2'
$tgtFolder = Get-Folder -Name $tgtFolder
$vm = Get-VM -Name $masterName
$hd = Get-HardDisk -VM $vm
if($hd.Count -ne $tgtDatastores.Count){
Write-Output "You have to provide a datastore for each harddisk in the master VM"
return
}
$spec = New-Object VMware.Vim.VirtualMachineCloneSpec
$location = New-Object VMware.Vim.VirtualMachineRelocateSpec
$i = 0
foreach($ds in (Get-Datastore -Name $tgtDatastores | Sort-Object -Property Name)){
$disk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$disk.Datastore = $ds.ExtensionData.MoRef
$disk.DiskId = $hd[$i].ExtensionData.Key
$location.Disk += $disk
$i++
}
$spec.Location = $location
$spec.PowerOn = $false
$spec.Template = $false
$vm.ExtensionData.CloneVM($tgtFolder.Id,$cloneName,$spec)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Just realised, in this version it follows the order in which you specified the datastores.
So Hard Disk 1 to the first datastore, Hard Disk 2 to the second....
$masterName = 'MasterVM'
$cloneName = 'CloneVM'
$tgtFolder = 'Clones'
$tgtDatastores = 'DS1','DS2'
$tgtFolder = Get-Folder -Name $tgtFolder
$vm = Get-VM -Name $masterName
$hd = Get-HardDisk -VM $vm
if($hd.Count -ne $tgtDatastores.Count){
Write-Output "You have to provide a datastore for each harddisk in the master VM"
return
}
$spec = New-Object VMware.Vim.VirtualMachineCloneSpec
$location = New-Object VMware.Vim.VirtualMachineRelocateSpec
$i = 0
foreach($dsName in $tgtDatastores){
$ds = Get-Datastore -Name $dsName
$disk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$disk.Datastore = $ds.ExtensionData.MoRef
$disk.DiskId = $hd[$i].ExtensionData.Key
$location.Disk += $disk
$i++
}
$spec.Location = $location
$spec.PowerOn = $false
$spec.Template = $false
$vm.ExtensionData.CloneVM($tgtFolder.Id,$cloneName,$spec)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD I'm getting this error when I try to run the clone operation: 'Exception calling "CloneVM" with "3" argument(s): "The operation is not supported on the object."'
any ideas what's wrong here?
Not really.
Can you provide the configuration of the master VM (how many VMDK), and the values you used in the script (the variable assignments at the start of the script).
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Here's the script I'm using, and the master VM has two hard disks:
Import-Module VMware.PowerCLI
$hdd_or_ssd = 'ssd'
for ($hostnum=1; $hostnum -lt 15; $hostnum++) {
for ($vmnum=1; $vmnum -lt 2; $vmnum++){
if ($hdd_or_ssd -eq 'ssd') {
$osdatatstore = Get-Datastore OS_SSD
}
elseif ($hdd_or_ssd -eq 'hdd') {
$osdatatstore = Get-Datastore OS_HDD
}
$testdatastore = Get-Datastore host$("$hostnum")_test_$($hdd_or_ssd)$("$vmnum")
Write-host "OS Datastore - $($osdatatstore)"
Write-host "Test Datastore - $($testdatastore)"
$masterName = "DISKSPD_TEMPLATE_$($hdd_or_ssd.ToUpper())"
$cloneName = "DISKSPD_host$($hostnum)_vm$($vmnum)"
$tgtFolder = "Clones_$($hdd_or_ssd.ToUpper())"
$tgtDatastores = $osdatatstore, $testdatastore
write-host $cloneName
write-host $tgtFolder
write-host $tgtDatastores
$tgtFolder = Get-Folder -Name $tgtFolder
$vm = Get-VM -Name $masterName
$hd = Get-HardDisk -VM $vm
write-host $tgtFolder
write-host $vm
write-host $hd
if($hd.Count -ne $tgtDatastores.Count){
Write-Output "You have to provide a datastore for each harddisk in the master VM"
return
}
$spec = New-Object VMware.Vim.VirtualMachineCloneSpec
$location = New-Object VMware.Vim.VirtualMachineRelocateSpec
$i = 0
foreach($dsName in $tgtDatastores){
$ds = Get-Datastore -Name $dsName
$disk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$disk.Datastore = $ds.ExtensionData.MoRef
$disk.DiskId = $hd[$i].ExtensionData.Key
$location.Disk += $disk
$i++
}
$spec.Location = $location
$spec.PowerOn = $false
$spec.Template = $false
$vm.ExtensionData.CloneVM($tgtFolder.Id,$cloneName,$spec)
write-host $spec
write-host $disk
Write-host "-----------------------------------"
}
}
My script expects $tgtDatastores to hold datastorenames (as strings).
Try changing this line
$tgtDatastores = $osdatatstore, $testdatastore
to
$tgtDatastores = $osdatatstore.Name, $testdatastore.Name
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Same error regarding the 3 arguments to CloneVM
That $vm does need to be an actual VM and not a template right?
Yes, the master VM is a regular VM, not a template.
Can you try with a simple test and use just the script I provided?
Just a regular VM with 2 or more hard disks that you want to clone to 2 or more datastores.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Tried the below, hard-coded the names of everything, same 3-argument error.
$masterName = 'DISKSPD_TEMPLATE_HDD'
$cloneName = 'CloneVM'
$tgtFolder = 'Clones_HDD'
$tgtDatastores = 'OS_HDD','host1_test_hdd1'
$tgtFolder = Get-Folder -Name $tgtFolder
$vm = Get-VM -Name $masterName
$hd = Get-HardDisk -VM $vm
if($hd.Count -ne $tgtDatastores.Count){
Write-Output "You have to provide a datastore for each harddisk in the master VM"
return
}
$spec = New-Object VMware.Vim.VirtualMachineCloneSpec
$location = New-Object VMware.Vim.VirtualMachineRelocateSpec
$i = 0
foreach($dsName in $tgtDatastores){
$ds = Get-Datastore -Name $dsName
$disk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$disk.Datastore = $ds.ExtensionData.MoRef
$disk.DiskId = $hd[$i].ExtensionData.Key
$location.Disk += $disk
$i++
}
$spec.Location = $location
$spec.PowerOn = $false
$spec.Template = $false
$vm.ExtensionData.CloneVM($tgtFolder.Id,$cloneName,$spec)
Did you check that there is sufficient free space available on those datastores where the clone will be created.
Can you have a look in the vpxd log, there should be more info on the failing method call.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference