Monthly Archives: April 2012

Stopping All Running Virtual Machines (Hyper-V)

So, a good friend and fellow MVP asked me for a script to shut down all running virtual machines on a server so she could do cold backups of them. This seemed like a perfectly reasonable request, and my first thought was “Well, this gets really obvious and easy in Windows Server 8” since we have a full set of Hyper-V cmdlets there. But then I sort of remembered doing something like this before, and hunted around and found this old TechNet Wiki article I wrote over a year ago. It wasn’t a full fledged script, but had all the pieces I needed to put together a simple script to stop all the VMs on the local Hyper-V host:

# This is a simple script to stop all the currently running VMs on the local
# Hyper-V host. It could easily be extended to accept a command line
# argument of the name of a remote yper-V hosts or a list of hosts into an array

$VMs = Get-WmiObject MSVM_ComputerSystem -computer "." -namespace "root\virtualization"
ForEach ($vm in $VMs) {
   if ( $ -ne $vm.elementname ) {   # skip the parent's name
      if ( $vm.EnabledState -eq 2 ) {      # If the VM is running
         $shutdown = Get-WmiObject MSVM_ComputerSystem -namespace "root\virtualization" –query “Associators of {$vm} where ResultClass=Msvm_ShutdownComponent”

         $shutdown.iniateShutdown($true,”System Maintenance”)

         sleep 5

So, what’s happening in that script? Well, Get-WmiObject grags a list of all the VMs on the local Hyper-V Host (-computer “.”), then we simply loop through the list (skipping host itself ($ -ne $vm.elementname), and for each VM that is running ($vm.EnabledState -eq 2), we get a shutdown object for that specific VM and then call the initiateShutdown method on that object. 


Note that this is a “forced shutdown”, so is equivalent to “shutdown –s –f” at the command line. Some processes may not get politely shutdown. Too bad, so sad. Since we need this to work regardless of what else is happening, that’s a necessary risk.