# encoding: ascii
# api: powershell
# title: VMWare Quick Migration
# description: Performs the functional equivalent of a Hyper-V Quick Migration by suspending a VM, moving it to a new host, and resuming it. This does not require vMotion licensing. It works by providing required VM objects via the pipeline or the second argument, and specifying the Destination host in the first argument, so you can use whatever query you want to build a list of VM’s to send to the command.
# version: 0.2
# type: function
# author: Justin Grote
# license: CC0
# function: QuickMigrate-VM
# x-poshcode-id: 1535
# x-archived: 2016-03-02T18:04:34
# x-published: 2010-12-15T15:08:00
#
# This is very useful for migrating virtual machines around in an environment that isn’t licensed for vMotion, such as vSphere Essentials Plus customers. It can even be used to quickly migrate virtual machines between clusters, assuming both clusters have access to the same LUNs. Note that VMotion rules still apply! (You need processor or EVC compatability between hosts as the CPU sets need to match).
# Want to perform maintenance on a host and need to move the virtual machines off? Easy:
# Get-VMHost myhost1 | Get-VM | QuickMigrate-VM myhost2
# Does not work with the free ESXi (except accidentally with ESX 3.5u2) due to the VMWare APIs being disabled.
#
#########################################
#Name: VMWare Quick Migration Function
#Author: Justin Grote <jgrote NOSPAMAT enpointe DOT com>
#Credit: Inspired by Mike DiPetrillo's Quick Migration Script: http://www.mikedipetrillo.com/mikedvirtualization/2008/10/quick-migration-for-vmware-the-power-of-powershell.html
#Version: 0.2
#Last Revised: 15 Dec 2009
#
#Description: Performs the fucntional equivalent of a Hyper-V Quick Migration by suspending a VM,
# moving it to a new host, and resuming it. This does not require vMotion licensing.
# it works by providing required VM objects via the pipeline or the second argument,
# and specifying the Destination host in the first argument.
# The commeand accepts both text strings and VMHost objects for the VMHost Parameter
#
#Prerequisites:
# Powershell v1
# VMWare PowerCLI 4.0 (May work with earlier version but not tested)
# VMWare Foundation Edition or Better (for API support). May work with VMWare Server 2 but not tested.
#
#Instructions to Install: Save this script and import into your session with, for example, . C:\temp\quickmigrate.ps1
# You can also include it in your PowerCLI profile to have it automatically included.
#Command Usage: get-vm MyTestVM | Quick-MigrateVM "MyTestHost2"
#########################################
function QuickMigrate-VM {
PARAM(
$NewVMHost = ""
, [VMware.VimAutomation.Client20.VirtualMachineImpl]$VMsToMigrate = $null
)
BEGIN {
if (!$NewVMHost){
Write-Error "No Destination VMHost Specified. You must specify a host to migrate to. `n Example: Get-VM `"Test`" | QuickMigrate-VM `"Host1`""
break
}
elseif ($VMsToMigrate) {
Write-Output $InputObject | &($MyInvocation.InvocationName) -NewVMHost $newVMHost
}
else {
#If NewVMHost was provided as a String, convert it into a VMHost Object.
if ($NewVMHost.GetType().Name -eq "String") {
set-variable -name destinationVMHost -value (get-vmhost $NewVMHost) -scope 1
}
#Make sure that we have a VMHost object to work with.
if (! $destinationVMHost -or (! $destinationVMHost.GetType().Name -eq "VMHostImpl")) {
write-error "Destination VM Host was not found or you provided the wrong object type. Please provide a VMHostImpl object or specify the fully qualified name of a VM Host"
break
}
write-host -fore white "===Begin Quick Migration==="
}
}
PROCESS {
$step = 0
$skip = $false
#In the Event of an error, output the error, and skip the rest of the current item.
#This is a workaround for the fact that "continue" doesn't work in a function process loop.
trap {
write-host -fore yellow "`tSKIPPED: "$_.Exception.Message
set-variable -name skip -value ($true) -scope 1
continue
}
$vmToMigrate = $_
### Validation Checks
if($_ -is [VMware.VimAutomation.Client20.VirtualMachineImpl]) {
write-host -fore white "Quick Migrating $($vmToMigrate.Name) to $NewVMHost..."
}
else {
throw "Object Passed was not a Virtual Machine object. Object must be of type VMware.VimAutomation.Client20.VirtualMachineImpl."
}
# Check for connected devices
if (! $skip -and (get-cddrive $vmToMigrate).ConnectionState.Connected -ieq "TRUE") {
throw "Connected CD Drive. Please disconnect and try again."
}
if (! $skip -and (get-floppydrive $vmToMigrate).ConnectionState.Connected -ieq "TRUE") {
throw "Connected Floppy Drive. Please disconnect and try again."
}
# Make sure the current VM Host and the Destination Host are different.
$sourceVMHost = get-vmhost -vm $vmToMigrate
if (! $skip -and ($sourceVMHost.Name -eq $destinationVMHost.Name)) {
throw "Source and Destination Hosts are the same."
}
###Validation Complete, begin Migration
if (! $skip) {
$step++
write-host -fore cyan "`t$($step). Suspending $($vmToMigrate.Name)..."
$suspend = Suspend-VM -VM $vmToMigrate -confirm:$false
}
if (! $skip) {
$step++
write-host -fore cyan "`t($step). Moving $($vmToMigrate.Name) "to" $($destinationVMHost.Name)"
$migrate = Get-VM $vmToMigrate | Move-VM -Destination $destinationVMHost
}
if (! $skip) {
$step++
write-host -fore cyan "`t($step). Resuming" $vmToMigrate.Name"..."
$resume = Start-VM -VM $vmToMigrate
}
write-host -fore green "`tCOMPLETED"
}
END { write-host -fore white "===END Quick Migration===" }
}