Automation–Exploring the PowerShell behind the Surface Pro Hijinks

Hello Readers/Viewers!

So, by now you have seen this post and related video…You may have wondered, “Is this real life?” Or, “What did it take to do that?”

Well, this post is all about my part in the “hijinks”:

Automating the Surface Pro Hosted VM Live Migration

(both shared-nothing and shared storage)

Automation Specs

  • Windows Server 2012 with Hyper-V
  • Windows PowerShell v3 with Workflow
  • Windows PowerShell Remoting
  • Hyper-V Cmdlets in Windows PowerShell

Script Breakdown

At its core, the script really was simply executing the “Move-VM” Hyper-V Command. All other aspects of the script pertained to the logic governing the Live Migration process.

Here is the PowerShell for the “Shared Nothing” option:

Move-VM -ComputerName $SourceHostName $VM -DestinationHost $DestHost -DestinationStoragePath $DestPath

And here is the PowerShell for the “Shared Storage” option":

Move-VM -ComputerName $SourceHostName $VM -DestinationHost $DestHost

These script elements (and their if / elseif statements) were baked into a foreach -Parallel based on the list of VMs requested for Live Migration. This foreach was then baked into a PowerShell Workflow .

Here is the PowerShell for the entire Workflow portion of the script:

Workflow Invoke-ParallelLiveMigrate { Param (
    [parameter(Mandatory=$true)][int] $Shared,
    [parameter(Mandatory=$true)][String[]] $VMList,
    [parameter(Mandatory=$true)][String] $SourceHost,
    [parameter(Mandatory=$true)][String] $DestHost,
    [parameter(Mandatory=$true)][String] $DestPath)
    foreach -Parallel ($VM in $VMList) {
        if ($Shared -eq 0) {
            Move-VM -ComputerName $SourceHostName $VM -DestinationHost $DestHost -DestinationStoragePath $DestPath
        elseif ($Shared -eq 1) {
            Move-VM -ComputerName $SourceHostName $VM -DestinationHost $DestHost

This Workflow can then be called with the following PowerShell:

Invoke-ParallelLiveMigrate -Shared $Shared -VMList $VMList.Name -SourceHost $SourceHost -DestHost $DestHost -DestPath $DrivePath

All of this then was wrapped in an Invoke-Command executed against the $SourceHost as selected from the simple dialog box that was prompted during the demonstration. Again, if interested, here is the PowerShell for the Invoke-Command:

Invoke-Command -ComputerName $SourceHost -credential $credential -Authentication Credssp -ScriptBlock {param($Shared,$SourceHost,$DestHost,$DrivePath,$VMList)

} -ArgumentList $Shared,$SourceHost,$DestHost,$DrivePath,$VMList

The $VMList referenced was generated based on a Get-VM command which as you saw in the video popped out to a Grid View (for demo purposes). You can obviously just populate $VMList with Get-VM and desired filters. If you are interested, here is the PowerShell for the Get-VM and Out-GridView:

$VMList = Get-VM -ComputerName $SourceHost | Out-GridView -Title "Select one or more VMs to Live Migrate" -PassThru

Well, that is it! Those are the main components for the Live Migration we demonstrated in the video.

If you are curious about the simple dialog boxes used to select Server Names (where the Get-VM was executed and $SourceHost / $DestHost were populated), be sure to check out the following link (also referenced below). If you are wondering, the $DrivePath variable was hard coded to: "c:\VMs" for the demo. Oh, and finally, if you are wondering about the Popup Message Box used, check out this link.

For good measure… and since this is in the “Just for Fun” Track as well… for the script you will see in the download, with some conditional logic [ if ($VMList.Count -gt 1) ], you get he following Popup:



Useful References

Want a copy of this script?

Well, here it is on TechNet Gallery (of course):

Click here for the TechNet Gallery Contribution for these Example Runbooks!