Thursday, May 9, 2019

VMWare PowerCli Get All VMs In A Cluster On A Specific Datastore

I'm a novice using VMWare PowerCli so I use a lot of Google searches to figure out the complex and challenging PowerCli commands. 

What I was trying to do was migrate / move all VMs in a cluster from one datastore to a different datastore.  I had 200+ VMs spread across 16 servers to move. Doing this via the console has its own challenges mostly the web clients both are cumbersome to use.

My biggest challenge was getting a list of VMs by cluster AND datastore. I thought this would be easy. Just use "get-vm -location XXX -datastore YYY".  But no, that returns VMs in the cluster or on the datastore. That list of 500 VMs.

I was never able to figure out how to get the list I wanted so I just brute force tried to move every one of the 500 VMs. If they were already on the target datastore, then it just finished and moved onto the next VM.  If the VM was NOT on the source datastore, then it failed and moved on to the next VM.  Those on the source datastore were moved.  Not very deterministic but it worked.

I continued to investigate how to do this trying to figure out the the API doc which is really a pain to use as well. Luckily Google has all the answers.

With the help of a blog post from 2102 by psvmware I was able to get the list of VMs I sought. I am pretty sure this can be used for different objects but I didn't mess around with that yet.

The command looks like this
Get-Cluster "MyCluster"|Get-vm |?{($_.extensiondata.config.datastoreurl|%{$_.name}) -contains "SourceDatastore"}| select -expandproperty name 
This returns only the VM name which can be used to move the VM

Here is my simple script that get s a list of VMs in a  cluster on a specific datastore then sorts the VMs by name ascending order and moves them to a different datastore. I actually used 2 scripts. One that sorts ascending and one that sorts descending so I can run them both and move 2 VMs at a time eventually running into each other. (when they both tried to move the same VM, one just waited for the other to finish).



$vchost="my.vcenter.server"
$vcuser="myUser"
$vcpassword="myPassword"
$srcdatastore="mySrcDatastoreName"
$vccluster="myClusterName"
$dstdatastore="myDestinationDatastoreName"
Connect-VIServer -server $vchost -user "$vcuser" -password $vcpassword
$vm = Get-Cluster "$vccluster"|Get-vm |?{($_.extensiondata.config.datastoreurl|%{$_.name}) -contains "$srcdatastore"}| select -expandproperty name |sort-object -ascending
foreach ($i in $vm) {
move-vm $i -datastore $dstdatastore -DiskStorageFormat thin
}

No comments: