Hyper-V

Shutting Down Running VMs

A quick Hyper-V PowerShell one-liner today. This one will gracefully stop all virtual machines with RODC in their name.

 Get-VM -Name *rodc* | Where-Object {$_.State -eq "Running" } | Foreach-Object { Stop-VM $_.Name }

I needed this because I was cloning an RODC that I had virtualized, and I wanted a quick way to shut it down gracefully without actually logging on to it. (It's on a private subnet that is a nuisance for some things.) Then I simply extended it a bit to get all my RODC's and to make sure that I didn't try to stop a VM that was already stopped.

Charlie.

And, because I'm lazy and don't want to bother logging in to my VM host server, I modified this to get all the running VMs on the server and then stop them.

Get-VM -ComputerName Trey-VMHost `
          | Where-Object {$_.State -eq "Running" } `
          | Foreach-Object { Stop-VM $_.Name -ComputerName $_.ComputerName }

Notice that by the time I get to the end of the pipeline, I need to tell Stop-VM what computer these are running on. No problem, that's part of the object I'm passing in to it anyway. And, you could easily extend this by providing an array of host names to Get-VM to stop multiple VMs on multiple hosts.

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 Hyper-V hosts or a list of hosts into an array

$VMs = Get-WmiObject MSVM_ComputerSystem -computer "." -namespace "root\virtualization"
foreach ($vm in $VMs) {
   if ( $vm.name -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 ($vm.name -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.

 

ETA: Wow, this is an old script. Written before we had built-in Hyper-V cmdlets to do this. This still works, and isn't version dependent so far as I know, but I've written updated versions of this a couple of times since. The most recent was 2016, here.  You might want to check that post out. It's a modern, PowerShell v5 version.

Uninstalling Windows Server 2008 R2 SP1 Beta and RC

Before you can install Windows Server 2008 R2 SP1 (or Windows 7 SP1), you need to uninstall the beta or RC version that might be installed. On a GUI install of Windows Server, no problem, run AppWiz.cpl and click on Updates. But on Hyper-V Server 2008 R2 (or Server Core) there is no obvious way to uninstall the beta or RC versions of the Service Pack. You need to use the command line version of the Windows Update Installer: wusa.exe.

wusa.exe /uninstall /kb:976932

It’ll take a couple of reboots before it’s completely uninstalled, and then you can install the SP1 you just downloaded.

Update: Note, if it wasn't clear. This command line works equally well from GUI installs, including Windows 7.

PowerShell, Hyper-V and WMI

I’ve started an article over on the PowerShell Survival Guide Wiki to drop in quick hits how to do “stuff” with Hyper-V, using PowerShell and the native WMI interface of Hyper-V. The WMI namespace for Hyper-V is  “root\virtualization”. Turns out managing Hyper-V isn’t as hard as I thought, at least in no small part because working with WMI in PowerShell is actually pretty straightforward. I’m still learning and poking around, but this stuff is all over the net if your bingle skills are good. Today I added the simple steps needed to create a VHD, either dynamic or fixed, to the Wiki page. Any one who wants to join in is more than welcome – that’s what a Wiki is all about after all.

Charlie.