VMware Cloud Community
daunce
Enthusiast
Enthusiast
Jump to solution

Move-VM between datacenters on same vCenter

Hey all..

With a VM powered off, I'm trying to migrate a VM between datacenters within the same vCenter. There's no shared storage, different networks at the destination host. The GUI works (shows warning about missing network at destination), yet move-vm doesn't work between datacenters.

Trying: move-vm -vm test-20150309 -destination esx1 -datastore datastore1, I get the error:

move-vm : 3/9/2015 2:48:20 PM    Move-VM        Destination container must be in the same Datacenter.
At line:1 char:1
+ move-vm -vm test-20150309 -destination esx1. ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (esx1:VMHostImpl) [Move-VM], VimException
    + FullyQualifiedErrorId : Client20_VmHostServiceImpl_CheckMoveVmParameters_InvalidDatacenter,VMware.VimAutomation.
   ViCore.Cmdlets.Commands.MoveVM

The manual states -Destination can be folder,host,cluster etc.. Since hosts AND folders are bound by datacenters, I'm guessing it needs to know the new host & new folder. I've tried to use -destination twice, and I've tried -destination host,folder.

Move-VM : Cannot bind parameter because parameter 'Destination' is specified more than once. To provide multiple values to parameters that can accept multiple values, use the array syntax. For example, "-parameter value1,value2,value3".

Move-VM : Missing an argument for parameter 'Destination'. Specify a parameter of type 'VMware.VimAutomation.ViCore.Types.V1.Inventory.VIContainer' and try again.

I'm using PowerCLI 5.8, and tried on vCenter 5.0 and 4.0.

move-vm : 3/9/2015 2:48:20 PM    Move-VM        Destination container must be in the same Datacenter.
At line:1 char:1
+ move-vm -vm test-20150309 -destination esx1. ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (esx1:VMHostImpl) [Move-VM], VimException
    + FullyQualifiedErrorId : Client20_VmHostServiceImpl_CheckMoveVmParameters_InvalidDatacenter,VMware.VimAutomation.
   ViCore.Cmdlets.Commands.MoveVM

Tags (2)
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Does the SDK method work ?

See 3.  Re: moving vm to a different datacenter


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
19 Replies
LucD
Leadership
Leadership
Jump to solution

Does the SDK method work ?

See 3.  Re: moving vm to a different datacenter


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
daunce
Enthusiast
Enthusiast
Jump to solution

Hi Luc.

Thanks for the quick response. I appreciate the work you put in here.

RelocateVM as you pointed to did the trick.

For anyone else, I had to make a few changes for my environment, to cater for the default resource pool in that cluster.

$vmName = "TestVM"
$tgtDatastore = "datastore"
$tgtCluster = "cluster"
$tgtPool = "Resources" # "Resources" is the default resource pool

$vm = Get-VM -Name $vmName
$ds = Get-Datastore -Name $tgtDatastore
$esx = Get-Cluster -Name $tgtCluster | Get-VMHost | Get-Random
$rp = Get-ResourcePool -Name $tgtPool -Location $tgtCluster # Specify Cluster as there's multiple clusters with default resource pools in this vCenter.

$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.Datastore = $ds.ExtensionData.MoRef
$spec.Host = $esx.ExtensionData.MoRef
$spec.Pool = $rp.ExtensionData.MoRef
$vm.ExtensionData.RelocateVM($spec,"defaultPriority")


* Note: I've tested this works on vCenter 5.0/4.0 all the way down to ESX 2.5.5.

0 Kudos
snoopj
Enthusiast
Enthusiast
Jump to solution

I tried the help daunce through Twitter earlier and I was thrown off by the fact that the Move-VM cmdlet documentation states that you can give a datacenter as a VIContainer object to the -Destination parameter.  It appears this might be inaccurate if he's got to use .NET properties.

--j

0 Kudos
LucD
Leadership
Leadership
Jump to solution

It depends on the vCenter version afaik


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
snoopj
Enthusiast
Enthusiast
Jump to solution

That's odd.  I could have sworn the first Google link I hit for Move-VM ended up on the 4.1 Update 1 PowerCLI (which made me think vCenter 4.1) reference guide and it had the same sentence in it that the 5.8 guide had.

Either way, neither here nor there.  It's not like documentation has ever been 100% accurate with any product I've ever worked with.

0 Kudos
vMarkusK1985
Expert
Expert
Jump to solution

I picked up LucD's Script and created a whole Migration workflow with a simple placement decision:

Script – vSphere VM zwischen Datacenter verlagern | my cloud-(r)evolution

https://mycloudrevolution.com | https://twitter.com/vMarkus_K | https://github.com/vMarkusK
0 Kudos
Jason10481
Contributor
Contributor
Jump to solution

Hello,

I know this is an older post, but I'm trying to migrate powered off VMs with PowerCLI on the same vCenter from one cluster to another in different datacenters.  I'm using the exact method Luc provided with the SDK but am getting the following error:

Exception setting "Pool": "Cannot convert the "System.Object[]" value of type "System.Object[]" to type "VMware.Vim.ManagedObjectReference"."

Here is my code:

$VM = Get-VM -Name $vmName

$RP = Get-ResourcePool -Name "Resources" -Location $cluster

$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec

$spec.Datastore = $newDS.ExtensionData.MoRef

$spec.Host = $newHost.ExtensionData.MoRef

$spec.Pool = $RP.ExtensionData.MoRef

$VM.ExtensionData.RelocateVM($spec,"defaultPriority")

vCenter is on 6.0 Update 2

Anyone have any thoughts?  Been scratching my head with this one all morning.

Thanks in advance!

-Jason

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That error indicates that you have provided an array (multiple objects) instead of a single object.

For one or another reason you have more than one object in $RP


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
ioudas
Contributor
Contributor
Jump to solution

LucD I have similar errors. Can you help me solve my errors?

$vmName = "MYVM"

$tgtDatastore = "TestSAN"

$tgtCluster = "GD SVRM"

$tgtPool = "Resources"

$vm = Get-VM -Name $vmName

$ds = Get-Datastore -Name $tgtDatastore

$esx = Get-Cluster -Name $tgtCluster | Get-VMHost | Get-Random

$rp = Get-ResourcePool -Name $tgtPool

$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec

$spec.Datastore = $ds.ExtensionData.MoRef

$spec.Host = $esx.ExtensionData.MoRef

$spec.Pool = $rp.ExtensionData.MoRef

$vm.ExtensionData.RelocateVM($spec,"defaultPriority")

Exception setting "Datastore": "Cannot convert the "System.Object[]" value of

type "System.Object[]" to type "VMware.Vim.ManagedObjectReference"."

At C:\movevm.ps1:12 char:1

+ $spec.Datastore = $ds.ExtensionData.MoRef

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationExceptio

   n

    + FullyQualifiedErrorId : ExceptionWhenSetting

Exception setting "Pool": "Cannot convert the "System.Object[]" value of type

"System.Object[]" to type "VMware.Vim.ManagedObjectReference"."

At C:\movevm.ps1:14 char:1

+ $spec.Pool = $rp.ExtensionData.MoRef

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationExceptio

   n

    + FullyQualifiedErrorId : ExceptionWhenSetting

Exception calling "RelocateVM" with "2" argument(s): "A specified parameter

was not correct: spec.location.datastore"

At C:\movevm.ps1:15 char:1

+ $vm.ExtensionData.RelocateVM($spec,"defaultPriority")

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

    + FullyQualifiedErrorId : VimException

I cant seem to get your code to work on any of my 3 hypervisors.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

It looks as if you have multiple ResourcePool objects returned, hence the "System.Object[]" in the error message.

If you have multiple vSphere server connections open (check $global:defaultviservers), add a Server parameter on the Get-ResourcePool cmdlet.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
ioudas
Contributor
Contributor
Jump to solution

I am having a hard time finding the information youre talking about. If i set the mode to single via Set-PowerCLIConfiguration -DefaultVIServerMode Single i still get errors in the script.....

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Can you check if this line returns more than one object?

Get-Datastore -Name $tgtDatastore


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
ioudas
Contributor
Contributor
Jump to solution

PowerCLI C:\> Set-PowerCLIConfiguration -DefaultVIServerMode Single

Performing operation 'Update vSphere PowerCLI configuration.'?

[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help

(default is "Y"):y

Scope    ProxyPolicy     DefaultVIServerMode InvalidCertificateAction  DisplayD

                                                                       eprecati

                                                                       onWarnin

                                                                       gs

-----    -----------     ------------------- ------------------------  --------

Session  UseSystemProxy  Multiple            Unset                     True

User                     Multiple

AllUsers                 Single

PowerCLI C:\> Get-Datastore -Name "TestSAN"

Get-Datastore : 10/13/2016 12:19:36 PM    Get-Datastore        You are not

currently connected to any servers. Please connect first using a Connect

cmdlet.

At line:1 char:1

+ Get-Datastore -Name "TestSAN"

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ResourceUnavailable: (:) [Get-Datastore], ViServ

   erConnectionException

    + FullyQualifiedErrorId : Core_BaseCmdlet_NotConnectedError,VMware.VimAuto

   mation.ViCore.Cmdlets.Commands.GetDatastore

PowerCLI C:\> Connect-VIServer -Server 10.40.30.242 -User "administrator@vsphere

.local" -Password "MYPASSHERE"

Name                           Port  User

----                           ----  ----

10.40.30.242                   443   VSPHERE.LOCAL\Administrator

PowerCLI C:\>  Get-Datastore -Name "TestSAN"

Name                               FreeSpaceGB      CapacityGB

----                               -----------      ----------

TestSAN                              5,355.414       6,143.750

TestSAN                              5,355.414       6,143.750

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You seem to have two datastores with the same name, that is causing the error message.

You can select either one of those, or if you want it to be a specific one, you will have to use more parameters on the Get-Datastore cmdlet.

For example Location or RelatedObject.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
ioudas
Contributor
Contributor
Jump to solution

The names of the data stores are identical between clusters for sure. I assume this means we cant have them named identically unless we specificy the related/location.

Looking at how to specify that. I am kinda lost. What would that look like for the other cluster?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You can do something like this

$clus1 = Get-Cluster -Name cluster1

$ds = Get-Datastore -Name ds1 -RelatedObject $clus1


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
ioudas
Contributor
Contributor
Jump to solution

LucD. This worked flawlessly.

Here is an example set of code.

$vmName = "NRFVORION1"

$tgtDatastore = "ISCSIOBRSERVER"

$tgtCluster = "GD SVRM"

$tgtPool = "Resources"

Set-PowerCLIConfiguration -DefaultVIServerMode single -Confirm:$false

Connect-VIServer -Server 10.40.30.242 -User "administrator@vsphere.local" -Password "mypwhere"

$clus1 = Get-Cluster -Name $tgtCluster

$vm = Get-VM -Name $vmName

$ds = Get-Datastore -Name $tgtDatastore -RelatedObject $clus1

$esx = Get-Cluster -Name $tgtCluster | Get-VMHost | Get-Random

$rp = Get-ResourcePool -Name $tgtPool -Location $tgtCluster

$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec

$spec.Datastore = $ds.ExtensionData.MoRef

$spec.Host = $esx.ExtensionData.MoRef

$spec.Pool = $rp.ExtensionData.MoRef

$vm.ExtensionData.RelocateVM($spec,"defaultPriority")

Disconnect-VIServer -Server * -Force -Confirm:$false

One thing i noted was some devices do not move with say serial devices or printers hooked up.

I get error

Exception calling "RelocateVM" with "2" argument(s): "Currently connected

device 'Serial port 1' uses backing '/dev/char/serial/uart0', which is not

accessible."

At C:\sms\movevm.ps1:20 char:1

+ $vm.ExtensionData.RelocateVM($spec,"defaultPriority")

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

    + FullyQualifiedErrorId : VimException

There is a uart0 on the other server. I am trying to remove the port and readd it. If you have an example how to fix that. I would greatly appreciate your expert knowledge. 🙂

0 Kudos
ioudas
Contributor
Contributor
Jump to solution

I did find some documentation on grammatically removing it. but it cannot do it with a powered on status.

Function Get-SerialPort {
    Param (
        [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
        $VM
    )
    Process {
        Foreach ($VMachine in $VM) {
            Foreach ($Device in $VMachine.ExtensionData.Config.Hardware.Device) {
                If ($Device.gettype().Name -eq "VirtualSerialPort"){
                    $Details = New-Object PsObject
                    $Details | Add-Member Noteproperty VM -Value $VMachine
                    $Details | Add-Member Noteproperty Name -Value $Device.DeviceInfo.Label
                    If ($Device.Backing.FileName) { $Details | Add-Member Noteproperty Filename -Value $Device.Backing.FileName }
                    If ($Device.Backing.Datastore) { $Details | Add-Member Noteproperty Datastore -Value $Device.Backing.Datastore }
                    If ($Device.Backing.DeviceName) { $Details | Add-Member Noteproperty DeviceName -Value $Device.Backing.DeviceName }
                    $Details | Add-Member Noteproperty Connected -Value $Device.Connectable.Connected
                    $Details | Add-Member Noteproperty StartConnected -Value $Device.Connectable.StartConnected
                    $Details
                }
            }
        }
    }
}

Function Remove-SerialPort {
    Param (
        [Parameter(Mandatory=$True,ValueFromPipelinebyPropertyName=$True)]
        $VM,
        [Parameter(Mandatory=$True,ValueFromPipelinebyPropertyName=$True)]
        $Name
    )
    Process {
        $VMSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
        $VMSpec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec
        $VMSpec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec
        $VMSpec.deviceChange[0].operation = "remove"
        $Device = $VM.ExtensionData.Config.Hardware.Device | Foreach {
            $_ | Where {$_.gettype().Name -eq "VirtualSerialPort"} | Where { $_.DeviceInfo.Label -eq $Name }
        }
        $VMSpec.deviceChange[0].device = $Device
        $VM.ExtensionData.ReconfigVM_Task($VMSpec)
    }
}

If i can remove the connected status i can migrate the vm and then edit it to be connected without issue.

0 Kudos
ioudas
Contributor
Contributor
Jump to solution

Managed to get that to work with some more code from lucd.

$vmName = "TestVM"
$serialName = "Serial port 1"
$startConnected = $false
$connected = $false

$vm = Get-VM -Name TestVM

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$dev = New-Object VMware.Vim.VirtualDeviceConfigSpec
$dev.Operation = "Edit"
$dev.Device = $vm.ExtensionData.Config.Hardware.Device |
 
where {$_ -is [VMware.Vim.VirtualSerialPort] -and $_.DeviceInfo.Label -eq $serialName}
$dev.Device.Connectable.Connected = $connected
$dev.Device.Connectable.StartConnected = $startConnected
$spec.DeviceChange += $dev

$vm.ExtensionData.ReconfigVM($spec


Thank you so much for all your help!

0 Kudos