vasedgod
Contributor
Contributor

How to clone a VM with two VHDs on different datastores in PowerCLI?

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!

0 Kudos
15 Replies
LucD
Leadership
Leadership

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

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
vasedgod
Contributor
Contributor

I meant VMDK, sorry about that! Smiley Happy I'll look into the method you mentioned, thanks!

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
vasedgod
Contributor
Contributor

A sample script would be really helpful if you don't mind, thanks!

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
vasedgod
Contributor
Contributor

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?

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
vasedgod
Contributor
Contributor

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 "-----------------------------------"

    }

}

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
vasedgod
Contributor
Contributor

Same error regarding the 3 arguments to CloneVM Smiley Sad

That $vm does need to be an actual VM and not a template right?

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
vasedgod
Contributor
Contributor

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)

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos