Dear All,
I'm looking to script the cloning of VMs from one datastore to another. My initial tests involve the following script:
-
Connect-VIServer xxxxxxx
$sourceVMName = "ITSSCOM01-test"
$targetVMName = "ITSSCOM01"
$targetDatastore = "xxxxxx"
$targetFolder = Get-Folder -Name "test" | % {Get-View $_.ID}
function Clone-VM {
$VMCloneSpec = New-Object VMware.Vim.VirtualMachineCloneSpec
$VMCloneSpec.Location = New-Object VMware.Vim.VirtualMachineRelocateSpec
$VMCloneSpec.Location.datastore = (Get-View (Get-Datastore -VM $sourceVMName).ID).MoRef
$VMCloneSpec.powerOn = $FALSE
Write-Host "Cloning $sourceVMName to $targetVMName in $targetFolderName..."
(Get-View (Get-VM -Name $sourceVMName).ID).CloneVM_Task($targetFolder.MoRef, $targetVMName, $VMCloneSpec)
}
Clone-VM
Disconnect-VIServer -Confirm:$false
-
HOWEVER, i get the following error:
The operation is not supported on the object
From what i can google, people get this problem if they are not conected to a VirtualCenter server, but i am!
Hopefully i'm just missing something simple but i can't for the life of me see it. Any help would be most apreciated!
For the record, we have a 6 node esx 3.5 cluster and the VM i want to clone is powered OFF.
kind regards
Roman
Hi Roman,
There are two ways you can do that:
1. You can just call the synchronous method CloneVm(...)
2. You can invoke the WaitForTask($MoRef) method:
$taskMoRef = $vmView.CloneVm_Task(...)
$vmView.WaitForTask($taskMoRef)
Is the target datastore defined on the ESX server ?
Since you do not specify the host property in the VirtualMachineRelocateSpec object, the cloned VM will be created on the same ESX host as the source VM.
As a side-remark, it is always useful to capture the Task object that the xxx_Task methods produce.
It (sometimes) allows you to see the error that caused the failure of the method.
You can do something like this
.... $taskMoRef = (Get-View (Get-VM -Name $sourceVMName).ID).CloneVM_Task($targetFolder.MoRef, $targetVMName, $VMCloneSpec) $task = Get-View $taskMoRef while($task.info.state -eq "running" -or $task.info.state -eq "queued"){ $task = Get-View $taskMoRef } Write-Host $task.info.error ....
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yes, both datastores can be seen by the host.
You are quite right, i should capture the CloneVM_Task to check for errors. I will do this on my return to work on Monday and let you know the results.
Thanks for your reply.
Roman
LucD
The problem seemed to be with my Get-Folder statement (the 'test' folder was me messing about).
I assume that VMs are put into a folder called 'vm' by default(??) Trouble was, i has 3 'vm' folders! Once i got my script to correctly identify the 'vm' folder that contained the VM i wanted to clone, all was better.
The trouble now is that launching the clone task from my script submits it to my VirtualCenter and then exits, where as i need it to wait while the clone task actually completes, then move on to another one.....
Regards
Roman
Hi Roman,
There are two ways you can do that:
1. You can just call the synchronous method CloneVm(...)
2. You can invoke the WaitForTask($MoRef) method:
$taskMoRef = $vmView.CloneVm_Task(...)
$vmView.WaitForTask($taskMoRef)
Many thanks for that!
Works like a treat
regards
Roman
How do I "invoke the WaitForTask($MoRef) method"?
I'm still just starting out with the VI Toolkit, so this is still a little advanced for me, but this functionality would be really handy for a VM-backup script I'm working on (until we get a proper backup solution in place).
It is the last two lines from my previous post:
$taskMoRef = $vmView.Clone_VmTask(...)
$vmView.WaitForTask($taskMoRef)
$vmView is the view of the virtual machine managed object for which the clone task is initiated. Any task method like Clone_VmTask(...) returns a managed object reference to a task object ($taskMoRef in our case). Then you simply invoke the WaitForTask method for the managed object for which the task is initiated passing the task MoRef as an argument.
\Yavor