VMware Cloud Community
Skagnola
Enthusiast
Enthusiast
Jump to solution

Move-VM between compute resources / datastores

In the near future, my environment may need to move 100+ VMs from one compute resource / datastores to a different compute / datastore. I am able to successfully test doing a single move like so:

 

Move-VM -VM testvm -Destination [destination host in the cluster} -Datastore [destination ds in the cluster]

 

However, if I want to allow vMotion to automatically determine what destination host and datastore to move the VMs to, what are the arguments and how to move these VMs? Also, if I want to set a move limit such that only 2 or three are moved at a time?

In the GUI, when choosing to migrate both compute / datastore you are prompted for the top-level cluster resource and does not require the specific host. The datastore it requires you to choose the store. 

I am fairly new to PowerCLI /PowerShell so any help is appreciated. Thanks!

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Try like this.

Note that I take a new randon ESXi node for each VM, otherwise all your VMs owuld be moved to the same ESXi node in the cluster.

Also note that since you are moving VM, the freespace on the datastores will change, hence we calculate that one as well again for each VM.

$tgtClusterName = 'K7C'

$cluster = Get-Cluster -Name $tgtClusterName

$vmList = Get-Content C:\vms.txt

foreach ($vm in $vmList) {

    $esx = Get-VMHost -Location $cluster | Get-Random

    $ds = Get-Datastore -Name k7c*-cml*-brhev* | Sort-Object -Property FreeSpaceGB -Descending | Select -First 1

    VMware.VimAutomation.Core\Move-VM -VM $vm -Destination $esx -Datastore $ds

}


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

View solution in original post

0 Kudos
21 Replies
LucD
Leadership
Leadership
Jump to solution

On the Move-VM cmdlet you can specify a cluster for the Destination parameter.

Same for the Datastore parameter, you can select a datastore or a datastorecluster.

Normally the system will limit the number of parallel vMotions you can do.

You can also monitor the maximum number yourself from a script (there are a number of threads in this community on that subject).

It comes down to doing the Move-VM in the background (the RunAsync parameter), capturing the the Tasks and controlling how many you want to have running at the same time.

But again, the system determined maximum is the limit.


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

0 Kudos
Skagnola
Enthusiast
Enthusiast
Jump to solution

Thanks for the quick response. 

Right, I am able to get a successful move when specifying the Destination (specific host in the cluster) and Datastore (specific host in the ds)

 

Move-VM -VM testvm1 -Destination esx1-1p01-domain.com -Datastore data-esx1-storage1

 

However when trying to specify via a cluster name it will fail

Move-VM -VM testvm1 -Destination ESX1 -Datastore ESX1

"No host is compatible with the virtual machine."

Wondering if there is a 'long name' I might have to use when referring a cluster name. Also if there is a way to have PCLI automate the placement of the VM, maybe based on the one with the most available space, or if by a certain name in the datastore cluster?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Is DRS enabled in that cluster?

Yes, SDRS should do that for you, but that will not necessarily be the datastore with the most free space.

If you want that, you'll have to add that logic to your script I'm afraid.


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

0 Kudos
Skagnola
Enthusiast
Enthusiast
Jump to solution

Appears DRS is enabled on the destination cluster

 

vSphere DRS is Turned ON                                                                                                                                                   
DRS Automation
Automation Level
Fully Automated
 
DRS automatically places virtual machines onto hosts at VM power-on, and virtual machines are automatically migrated from one host to another to optimize resource utilization.
 
Migration Threshold
Apply priority 1, priority 2, and priority 3 recommendations.
 
DRS provides recommendations when workloads are moderately imbalanced. This threshold is suggested for environments with stable workloads. (Default)
 
Predictive DRS
Predictive DRS is disabled. vCenter will not respond to forecasted metrics from vRealize Operations.
 
Virtual Machine Automation
Individual virtual machine automation levels enabled.
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Then there must be an incompatibility for the vMotion.

What does it say when you try to start the vMotion from the Web Client (and select the cluster, not a specific ESXi node).

Otherwise have a go with the script Matt gave in Re: vmotion -- dry run through powercli


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

0 Kudos
Skagnola
Enthusiast
Enthusiast
Jump to solution

When I use the Web Client, I am able to select the cluster with no compatibility issues. There is one when selecting a datastore

If this operation is performed, the virtual machine will lose vSphere HA protection. If you proceed with this operation and it completes successfully, "vSphere HA will not attempt to restart the VM after a subsequent failure. vSphere HA protection will be restored when any network partitions or disk accessibility issues are resolved.".

Of course, you can continue the operation despite the warning in the Web Client.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

And do you have HA enabled on the system where the VM is running?

Does it work when you use the default resourcepool on the target cluster as the Destination?

$tgtClusterName = 'Cluster'

$rp = Get-ResourcePool -Name Resources -Location $tgtClusterName


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

0 Kudos
Skagnola
Enthusiast
Enthusiast
Jump to solution

And do you have HA enabled on the system where the VM is running?

Yep; looks like that is set.

vSphere HA Protection: Protected

.. where the VM is sourcing from.

I may not be crafting the script ( movevm.ps1 ) properly. See below for my syntax

$tgtClusterName = 'name'

$rp = Get-ResourcePool -Name Resources -Location $tgtClusterName

$vm = 'testvm1p01'

$ds = 'name'

Function Move-VM

    {

  -VM $vm -Destination $tgtClusterName -Datastore $ds $rp

    }

  

After running, nothing happens.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I'm not sure what the Function is doing there, but try something like this

$tgtClusterName = 'name'

$cluster = Get-Cluster -Name $tgtClusterName

$rp = Get-ResourcePool -Name Resources -Location $cluster

$vm = 'testvm1p01'

$ds = 'name'

Move-VM -VM $vm -Destination $rp -Datastore $ds


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

0 Kudos
Skagnola
Enthusiast
Enthusiast
Jump to solution

Really appreciate the replies and patience, Luc!

Getting an error returned that seems kind of odd... as though the Move-VM does not like the cmdlet -VM.

Of note, I am crafting this in PowerShell ISE and getting this after saving the edits and then running the

=============================================

$tgtClusterName = 'K7C'

$cluster = Get-Cluster -Name $tgtClusterName

$rp = Get-ResourcePool -Name Resources -Location $cluster

$vm = -VM 'testvm1p01'

$ds = 'K7C'

Move-VM -VM $vm -Destination $rp -Datastore $ds

==============================================

-VM : The term '-VM' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

If I run this from the commandline as the script file .\movevm.ps1, nothing happens.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I have the impression you also have the Hyper-V PowerShell module installed, and that module also contains a Move-VM cmdlet.

Can you check with

Get-Command -Name Move-VM


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

0 Kudos
Skagnola
Enthusiast
Enthusiast
Jump to solution

That returns

CommandType     Name                                               Version    Source                                                                                                                                                                

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

Function               Move-VM                                                             

0 Kudos
Skagnola
Enthusiast
Enthusiast
Jump to solution

And some more info about the PCLI install

PowerCLI Version

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

   VMware PowerCLI 6.5.1 build 5377412

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

Component Versions

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

   VMware Cis Core PowerCLI Component 6.5 build 6820716

   VMware VimAutomation Core PowerCLI Component 6.5 build 6234650

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That si not right, that shoudl say Cmdlet for the PowerCLI MOve-VM.

Can you replace the Move-VM, in your script, with VMware.VimAutomation.Core\Move-VM ?


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

0 Kudos
Skagnola
Enthusiast
Enthusiast
Jump to solution

That comes back with

========================================

VMware.VimAutomation.Core\Move-VM : 12/8/2017 12:33:25 PM Move-VM Could not find StorageResource with name 'name'.

At C:\Users\Skagnola\Documents\movevm.ps1:9 char:1

+ VMware.VimAutomation.Core\Move-VM -VM $vm -Destination $rp -Datastore ...

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

    + CategoryInfo          : ObjectNotFound: (name:String) [Move-VM], VimException

    + FullyQualifiedErrorId : Core_ObnSelector_SelectObjectByNameCore_ObjectNotFound,VMware.VimAutomation.ViCore.Cmdlets.Commands.MoveVM

VMware.VimAutomation.Core\Move-VM : 12/8/2017 12:33:25 PM Move-VM Destination is a Resource Pool owned by a Cluster, but the VM you are trying to move is not in that Cluster. Please select for destination a Host in that Cluster or a Resource

Pool owned by a stanalone Host.

At C:\Users\Skagnola\Documents\movevm.ps1:9 char:1

+ VMware.VimAutomation.Core\Move-VM -VM $vm -Destination $rp -Datastore ...

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

    + CategoryInfo          : InvalidArgument: (Resources:ResourcePoolImpl) [Move-VM], VimException

    + FullyQualifiedErrorId : Client20_VmHostServiceImpl_MoveVm_ResourcePoolOwnedByCluster,VMware.VimAutomation.ViCore.Cmdlets.Commands.MoveVM

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ok, that is much better, we are at last using the Move-VM fomr PowerCLI.

There are two errors that the Move-VM reports:

  1. You don't seem to have replaced the string 'name' with an actual datastorename.
  2. The VM you are trying to move, is not located in a cluster but on standalone ESXi node it seems. That means that instead of the cluster, you will have to a host in the cluster.

Try like this (but do not forget to get actual names for the cluster and the datastore.

$tgtClusterName = 'name'  # <== Replace with the actual clustername

$cluster = Get-Cluster -Name $tgtClusterName

$esx = Get-VMHost -Location $cluster | Get-Random

$vm = 'testvm1p01'

$ds = 'name'              # <== Replace with a datastorename in the target cluster

VMware.VimAutomation.Core\Move-VM -VM $vm -Destination $esx -Datastore $ds


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

0 Kudos
Skagnola
Enthusiast
Enthusiast
Jump to solution

Ok I think I can definitely do that. I had the correct entry in 'name' but redacted it from the output when I pasted it here.

For the part

$ds = 'name'        # <== Replace with a datastorename in the target cluster

Is there a way to add something like this with that variable

Get-Datastore | Where {$_.name -Like 'k7c-cml-brhev*'}

... and somehow have it moved to one of the resulting datastores, but based on most free space?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Sure, try like this

Get-Datastore -Name k7c-cml-brhev* | Sort-Object -Property FreeSpaceGB  -Descending | Select -First 1


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

0 Kudos
Skagnola
Enthusiast
Enthusiast
Jump to solution

Luc! That worked nicely for the single test VM!

So to make it even closer to the final task, going from a single column list of VMs C:\vms.txt, how would I tell this to loop over these lines, but then wait until the move is complete before doing another? Ergo, it will pull updated free space on the available datastores as it goes before proceeding.

Does there need to be a Wait-Task inserted somewhere?

$tgtClusterName = 'K7C'

$cluster = Get-Cluster -Name $tgtClusterName

$esx = Get-VMHost -Location $cluster | Get-Random

$vmList = Get-Content C:\vms.txt

$ds = Get-Datastore -Name k7c*-cml*-brhev* | Sort-Object -Property FreeSpaceGB -Descending | Select -First 1

foreach (in $vmList) {VMware.VimAutomation.Core\Move-VM -VM $vm -Destination $esx -Datastore $ds} <================Don't think I have this syntax correct as it bombs out.

0 Kudos