Killing A Frozen Windows Server 2012 Hyper-V Virtual Machine

Virtual machines sometimes hang. Admins have the tools to kill hung machines but it is a delicate and potentially dangerous operation.
In October 2011, the Petri IT Knowledgebase published two posts covering how to retrieve a virtual machine’s GUID and how to use that information to kill a hung virtual machine. Those articles covered pre-Windows Server 2012 versions of Hyper-V.
Rather than browsing around Windows Explorer and Task Manager hoping you don’t kill a healthy production virtual machine by mistake, it is safer and easier to learn how to kill the right virtual machine using a few short lines of PowerShell.

Getting a Virtual Machine’s GUID

The GUID of a virtual machine is the globally unique identifier for that virtual machine. While it is possible for virtual machines to have the same name, in theory no two Hyper-V virtual machines should have the same GUID. Knowing this GUID can be especially useful. One of those occasions is when a virtual machine hangs and you are unable to turn it off using normal means such as Hyper-V Manager, Failover Cluster Manager, System Center, or PowerShell’s Stop-VM.
There are a number of ways to retrieve the GUID of a virtual machine. You can open up Explorer, browse to the virtual machine’s storage location, and get the name of the virtual machine XML file. That file is named after the GUID of the virtual machine.
The quickest way to retrieve a virtual machine’s GUID is to run a PowerShell query. This method gives you a sure result for later usage. You can use the Get-VM cmdlet to query the attributes of a virtual machine. The screenshot below shows how an attribute of the virtual machine, the GUID in this case, is easily retrieved.
 

Using PowerShell to get the GUID of a Hyper-V virtual machine

Using PowerShell to get the GUID of a Hyper-V virtual machine

You could run the following cmdlet to save the GUID into a variable. This variable can then be reused in subsequent cmdlets. That’s much safer than trying to remember a GUID.

​ $VMGUID = (Get-VM VM01).ID

Killing a Hung Virtual Machine

I don’t remember having to kill a hung virtual machine, but there is enough material on the Internet to suggest that some have had to do it on occasion. This is possible, even if it does not seem like it when you struggle to kill the virtual machine using the normal Hyper-V administration tools.
Go back and refresh your memory on Hyper-V architecture. Every running (even if it is hung) virtual machine has a small management process called the VM Worker Process that is running in user mode in the management OS on the host. You can kill a hung virtual machine by killing this VMWP.EXE process. The question is: which VMWP.EXE do you kill if there are lots of them running? You don’t want to kill the wrong VMWP.EXE and in turn terminate a healthy line of business application! The previously blogged method tells us that each VMWP.EXE process has a command line parameter that lists the GUID of the related virtual machine; we can search for the running instances of VMWP.EXE with the GUID of our failed virtual machine, kill that VMWP process, and the related virtual machine will stop executing. That was all done visually, but we can do this using PowerShell on WS2012 or later. First we need to get the virtual machine GUID:

​ # What is the VM called
​ $VM = "VM01"
​ # Get the VM GUID
​ $VMGUID = (Get-VM $VM).ID

We then need to search for a running process called VMWP that has the GUID of the virtual machine in its command line. This requires a WMI query. Unfortunately the Get-Process PowerShell cmdlet cannot query the CommandLine parameter:

​ $VMWMProc = (Get-WmiObject Win32_Process | ? {$_.Name -match 'VMWP' -and $_.CommandLine -match $VMGUID})

Armed with the process information, we can kill the process using the ID of that process. The –Force is optional. Without it the cmdlet will require you to confirm that you want to kill the process:

​ Stop-Process ($VMWMProc.ProcessId) –Force


You can take that code and turn it into a handy little PowerShell function:

​ Function KillHungVM ($VMName)
​ {

This function can be executed by running:

​ # KillHungVM <VM Name>
​ $VMGUID = (Get-VM $VMName).ID
​ $VMWMProc = (Get-WmiObject Win32_Process | ? {$_.Name -match 'VMWP' -and $_.CommandLine -match $VMGUID})
​ Write-Output "Killing the worker process for virtual machine '$VMName'"
​ Stop-Process ($VMWMProc.ProcessId) -Force
​ }