Hello All,
Here is my problem. I am trying to automate the cold migration of roughly 30 VMs (obviously powered off) from one datacenter to another within the same Virtual Center. I have been able to migrate 1 VM at a time via PowerCLI by using the following script. I used Onyx to help me with the base for the script.
$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.datastore = New-Object VMware.Vim.ManagedObjectReference
$spec.datastore.type = "Datastore"
$spec.datastore.value = "datastore-1672"
$spec.pool = New-Object VMware.Vim.ManagedObjectReference
$spec.pool.type = "ResourcePool"
$spec.pool.value = "resgroup-4017"
$spec.host = New-Object VMware.Vim.ManagedObjectReference
$spec.host.type = "HostSystem"
$spec.host.value = "host-4018"
$spec.disk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator[] (1)
$spec.disk[0] = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$spec.disk[0].diskId = 2000
$spec.disk[0].datastore = New-Object VMware.Vim.ManagedObjectReference
$spec.disk[0].datastore.type = "Datastore"
$spec.disk[0].datastore.value = "datastore-1672"
$_this = Get-View -Id 'VirtualMachine-vm-4029'
$_this.RelocateVM_Task($spec, "defaultPriority")
What I am trying to do now is use variables for the values of Datastore,Pool,Host and Get-View for the VM itself to perform more than 1 migration at a time. So here is what I have tried to do
connect-viserver VCENTERSERVER.domain.local
$vms = Import-CSV "G:\temp\scripts\relocate.csv"
foreach ($vm in $vms) {
$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.datastore = New-Object VMware.Vim.ManagedObjectReference
$spec.datastore.type = "Datastore"
$spec.datastore.value = $vm.DatastoreName
$spec.pool = New-Object VMware.Vim.ManagedObjectReference
$spec.pool.type = "ResourcePool"
$spec.pool.value = $vm.ResourcePoolName
$spec.host = New-Object VMware.Vim.ManagedObjectReference
$spec.host.type = "HostSystem"
$spec.host.value = $vm.ESXHostName
$spec.disk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator[] (1)
$spec.disk[0] = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$spec.disk[0].diskId = 2000
$spec.disk[0].datastore = New-Object VMware.Vim.ManagedObjectReference
$spec.disk[0].datastore.type = "Datastore"
$spec.disk[0].datastore.value = $vm.DatastoreName
$_this = Get-View -Id $vm.Name
$_this.RelocateVM_Task($spec, "defaultPriority")
}
Here is what my CSV File looks like. I used PowerCLI to find the actual IDs for each object.
Name,DatastoreName,ResourcePoolName,ESXHostName
VirtualMachine-vm-4029,datastore-4557,resgroup-3694,HostSystem-host-3729
VirtualMachine-vm-4030,datastore-4558,resgroup-3694,HostSystem-host-3731
Here is the error message I receive when running the script
Exception calling "RelocateVM_Task" with "2" argument(s): "The object has already been deleted or has not been completely created"
At G:\temp\scripts\RelocateMOD.ps1:25 char:23
+ $_this.RelocateVM_Task <<<< ($spec, "defaultPriority")
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Exception calling "RelocateVM_Task" with "2" argument(s): "The object has already been deleted or has not been completely created"
At G:\temp\scripts\RelocateMOD.ps1:25 char:23
+ $_this.RelocateVM_Task <<<< ($spec, "defaultPriority")
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Any help is greatly appreciated.
That is one of the disadvantages of Onyx, the generated code is long-winded.
There is no need to use the Ids in the CSV file, just use the names.
And there is no need to specify a datastore for the vDisk if you are migrating that to the same datastore as the VM's other files
connect-viserver VCENTERSERVER.domain.local $vms = Import-CSV "G:\temp\scripts\relocate.csv"
foreach ($vm in $vms) { $spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.datastore = (Get-Datastore -Name $vm.DatastoreName).ExtensionData.MoRef
$spec.pool = (Get-ResourcePool -Name $vm.ResourcePoolName).ExtensionData.MoRef
$spec.host = (Get-VMHost -Name $vm.ESXHostName).ExtensionData.MoRef
$vmObj = Get-VM -Name $vm.Name | Get-View
$vmObj.RelocateVM_Task($spec, "defaultPriority") }
And your CSV could look like this
Name,DatastoreName,ResourcePoolName,ESXHostName
VM1,DS1,Pool1,ESX1
VM2,DS1,Pool2,ESX2
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
That is one of the disadvantages of Onyx, the generated code is long-winded.
There is no need to use the Ids in the CSV file, just use the names.
And there is no need to specify a datastore for the vDisk if you are migrating that to the same datastore as the VM's other files
connect-viserver VCENTERSERVER.domain.local $vms = Import-CSV "G:\temp\scripts\relocate.csv"
foreach ($vm in $vms) { $spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.datastore = (Get-Datastore -Name $vm.DatastoreName).ExtensionData.MoRef
$spec.pool = (Get-ResourcePool -Name $vm.ResourcePoolName).ExtensionData.MoRef
$spec.host = (Get-VMHost -Name $vm.ESXHostName).ExtensionData.MoRef
$vmObj = Get-VM -Name $vm.Name | Get-View
$vmObj.RelocateVM_Task($spec, "defaultPriority") }
And your CSV could look like this
Name,DatastoreName,ResourcePoolName,ESXHostName
VM1,DS1,Pool1,ESX1
VM2,DS1,Pool2,ESX2
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank you very much.....that worked perfectly!!!!