James O'Neill's Blog

April 19, 2008

More on the accessing the Hyper-V API from Powershell

Filed under: How to,Powershell,Virtualization,Windows Server,Windows Server 2008 — jamesone111 @ 5:51 pm

… In which we find VMs, them choose one, start them, stop them  , and connect to them.

I spent more of the last week than I planned looking at Hyper-V and Powershell, and I’m getting dangerously close to calling myself an expert.

There are two WMI objects which do most of the work “Msvm_ImageManagementService” and “Msvm_virtualSystemManagementService” and I’ve got posts to write about things you can do with both of them, and some of the tricks of Wbemtest as well.

I also found that in several places I needed the WMI object representing the VM, or the object representing its status. Cue two functions

function Get-VM   
{Param ($machineName="%")
Get-WmiObject -Namespace "root\virtualization"               
-Query "SELECT * FROM Msvm_ComputerSystem
                       WHERE ElementName like '$machineName' AND caption like 'Virtual%' "
} #example 1: Get-VM
#           Returns WMI Msvm_ComputerSystem objects for all Virtual Machines #           (n.b. Parent Partition is filtered out)
#Example 2:  Get-VM "%2008%" #        Returns WMI Msvm_ComputerSystem objects for machines containing 2008 in their name #        (n.b.Wild card is % sign not *)

I re-wrote my function for displaying VM status as a format function and this little bit of code

function Format-VMStatus 

{param ($VM) if ($VM -eq $null) {$VM=$input}
$VM | Format-Table -autoSize  -properties as in the old post


Function Get-VMStatus
{Param ($machineName="%")
Get-VM $MachineName | Format-VmStatus

and Choosing a VM turned into

function Choose-VM  
{$VMs = Get-VM 
$VMs| Format-VmStatus | out-host
$VMs[ [int[]](Read-Host "Which one(s) ?").Split(",")] }

I wanted to be able to start a VM  (multiple VMs), stop it, pause it or connect to it using either it’s name or the Msvm_ComputerSystem object so I wrote 4 little functions which will do just that. (Yes I should have 3 of them calling a single “change state” function !)

function Start-VM 
{Param ($vm)
if ($vm -is [array]) {$vm | forEach-object {Start-VM $_ } }
if ($vm -is [string]) {$vm=(Get-VM $vm) }
if ($vm -is [System.Management.ManagementObject]) {$vm.requestStateChange(2) }
#Example Start-vm (choose-vm) - prompts the user to select one or more VMs and starts them

function Suspend-VM
{Param ($vm)

if ($vm -is [array]) {$vm | forEach-object {Suspend-VM $_ } } if ($vm -is [string]) {$vm=(Get-VM $vm) }

if ($vm -is [System.Management.ManagementObject]) {$vm.requestStateChange(32769) }

function Stop-VM
{Param ($vm) if ($vm -is [array]) {$vm | forEach-object {Stop-VM $_ } }
if ($vm -is [string]) {$vm=(Get-VM $vm) } if ($vm -is [System.Management.ManagementObject]) {$vm.requestStateChange(3) }

function Get-VMConnectSession
{Param ($vm) if ($vm -is [string]) {& 'C:\Program Files\Hyper-V\vmconnect.exe' $VSMgtSvc.SystemName $vm } if ($vm -is [System.Management.ManagementObject]) {& 'C:\Program Files\Hyper-V\vmconnect.exe' $VSMgtSvc.SystemName $vm.elementName } } #Example: Get-VMconnectSession $tenby
#         Launches a Terminal connection to the server pointed to by $tenby.

In the next post I’ll look at things we can do with virtual disks using the “Msvm_ImageManagementService object

This post originally appeared on my technet blog.


Create a free website or blog at WordPress.com.

%d bloggers like this: