VMware Cloud Community
Mozana
Contributor
Contributor
Jump to solution

Multiple Cold Migrations via PowerCLI across datacenters

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.  

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

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

View solution in original post

0 Kudos
2 Replies
LucD
Leadership
Leadership
Jump to solution

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

0 Kudos
Mozana
Contributor
Contributor
Jump to solution

Thank you very much.....that worked perfectly!!!!

0 Kudos