Dela via


More on the accessing the Hyper-V API from Powershell

... 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}  
 $global:Counter=-1  
 $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

Technorati Tags: Microsoft,Windows Server 2008,Hyper-v,Virtulization,Powershell

 

Comments

  • Anonymous
    January 01, 2003
    The machine is running quite happily and has never been snapped. Late on Monday make a snapshot. This

  • Anonymous
    January 01, 2003
    It is possible open the Hyper-V console for an individual VM without opening the full mmc.  You

  • Anonymous
    January 01, 2003
    In my last post I explained how snapshots work and gave a little bit of PowerShell for creating a one

  • Anonymous
    January 01, 2003
    In which we see how to set the number of CPUs I started with getting MSVM Computer System objects - which

  • Anonymous
    January 01, 2003
    Ibrahim, sorry I should have said that $vsMgtSvc = Get-wmiObject -nameSpace rootvirtualization -class Msvm_virtualSystemManagementService __server is the name of the machine where the WMI command executed and $VsMgtSvc.SystemName is the name of the hyper-V machine. In practice they will usually be the same.

  • Anonymous
    April 24, 2008
    Nice post. I can’t find where you get $VSMgtSvc from... and it seems to work better if you change $VSMgtSvc.SystemName to $vm.__SERVER Cheers, Ibrahim