Migrating Virtual Machines to a preferred host with PowerCLI

VMware customers with a license that includes the Distributed Resource Scheduler (DRS) can work with affinity and anti-affinity rules for virtual machines and hosts to keep virtual machines on preferred hosts. Customers without DRS do not have such a built-in feature. After a server failure or after maintenance virtual machines may be on different hosts and not running on the host where you would want them to run.

With a simple script you can start a vMotion process to migrate machines to their preferred hosts. You could for example run such a script to migrate virtual machines back to the host you have selected after host maintenance.

I have also written an article with a script to do the same with using vSphere tags. The benefit of that approach is that you do not have to maintain an external file but rather create the host assignments in your inventory. You can find the article here.

To achieve this create a text file that will function as a CSV import file. The file must contain the header names vm and host on the first line followed by your list of virtual machine names and host names where those virtual machines should be running. In my example below i have used the filename vmotion-vmlist.csv. Unless you would specify a different path in the script place this file in the same folder where your script resides.

vm,host
vm01,server-1
vm02,server-1
vm03,server-1
vm04,server-2
vm05,server-2
vm06,server-2

Next create the PowerCLI script that will read the file and perform the migrations.

#Read the CSV file with vm,host
$VMList = Import-Csv .\vmotion-vmlist.csv
Connect-VIServer -Server <your-vcenter-server> 
foreach ($item in $VMList)

    Move-VM -VM $item.vm -Destination $item.host
}

That's all. For better readability of your output you could consider to add a pipeline with formatting:

Move-VM -VM $item.vm -Destination $item.host | format-table name, vmhost, powerstate -HideTableHeaders

It is also possible to add the -RunAsync parameter to the Move-VM command to invoke all migrations at the same time but that might add undesirable load on your hosts so if speed if not of the essence have the migrations run synchronously.

This script does not check if a virtual machine is already on the preferred host. That could be done but on the other hand if the vm is already on that host just nothing happens.

What you might want to add is some error handling. You could add the -ErrorAction parameter to the Move-VM command. You can use Stop to stop processing the for-each loop in the script. But it's also possible to use the Inquire option which will pause and ask what to do. These two options would look like this in the script:

Move-VM -VM $item.vm -Destination $item.host -ErrorAction Stop

or

Move-VM -VM $item.vm -Destination $item.host -ErrorAction Inquire

 

Tags