Bring on the Scripts!
Okay! Now that initial documentation of the Hyper-V WMI API is available I thought I would respond with a "Week of Hyper-V Scripts".
Starting with a simple one - here is a script that will list the name, identifier and state for each virtual machine on the physical computer:
VBScript:
Option Explicit
Dim WMIService
Dim VMList
Dim VM
'Get instance of 'virtualization' WMI service on the local computer
Set WMIService = GetObject("winmgmts:\\.\root\virtualization")
'Get all the MSVM_ComputerSystem object
Set VMList = WMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem")
For Each VM In VMList
if VM.Caption = "Microsoft Virtual Computer System" then
WScript.Echo "========================================"
WScript.Echo "VM Name: " & VM.ElementName
WScript.Echo "VM GUID: " & VM.Name
WScript.Echo "VM State: " & VM.EnabledState
end if
Next
PowerShell:
# Get all VM objects on the local computer
$VMs = gwmi -class "MSVM_ComputerSystem" -namespace "root\virtualization" -computername "."
foreach ($VM in $VMs){
if ($VM.Caption -match "Microsoft Virtual Computer System"){
write-host "=================================="
write-host "VM Name: " $VM.ElementName
write-host "VM GUID: " $VM.Name
write-host "VM State: " $VM.EnabledState
}
}
Now to pull these scripts apart a bit:
The flow of these scripts is:
- Get WMI Service object for virtualization namespace
- Execute WMI query to get all VM objects
- Iterate over the VM objects
For each virtual machine object we display the "ElementName" - which is the friendly name that you give the virtual machine ("Windows Server Foo") - the "Name" - which is a GUID that is used to internally uniquely identify the virtual machine and the "EnabledState" (you can find what the different EnabledState values mean here: https://msdn2.microsoft.com/en-us/library/cc136822(VS.85).aspx).
"gwmi" is PowerShell shorthand for "Get-WMIObject"
Amusingly enough this script would also return information about the parent partition (which is technically a virtual machine) which is why I check the caption of the virtual machine and only display information about entries that are actually virtual machines.
Cheers,
Ben
Comments
Anonymous
January 28, 2008
> Amusingly enough this script would also return information about the parent partition (which is technically a virtual machine). This is a very questionable design decision - even if all partitions run under the same hypervisor, for the user the host ("parent partition") is a very different thing from a guest ("child partition").Anonymous
January 28, 2008
> Amusingly enough this script would also return information about the parent partition (which is technically a virtual machine). This is a very questionable design decision - even if all partitions run under the same hypervisor, for the user the host ("parent partition") is a very different thing from a guest ("child partition"). Well, at least with WMI you don't have to do the funny security stuff to write a simple Powershell script.Anonymous
January 29, 2008
Why you write PowerShell the VBS way?! :( gwmi MSVM_ComputerSystem -namespace "rootvirtualization" -computername "." | where {$_.Caption -eq "Microsoft Virtual Computer System"} | Format-List ElementName, Name, EnabledStateAnonymous
January 29, 2008
Thanks - this is great stuff. What do you need to run these scripts from a desktop? I'd like to be able to query multiple Hyper-V machines from my desktop.Anonymous
January 29, 2008
Ben, How would I do this WMI via C#? Which Interop DLL would I need to use to get the Hyper-V WMI? ThanksAnonymous
January 30, 2008
Jonathan - The fact that we report the parent is actually to maintain compatibility with the DMTF management standard. Xaegr - Sorry, I just find it easier to read this way. Jason - You can run this from a remote system without needing to install any thing. Just change the '.' to the computer name. Nehru - You do not need an interop DLL, I will post on this later. Cheers, BenAnonymous
January 30, 2008
Nehru, You can do this is managed code like this: //Connection credentials to the remote computer - not needed if the logged in account has access ConnectionOptions conn = new ConnectionOptions(); ManagementScope ms = new ManagementScope(@".rootvirtualization", conn); //get the computers ObjectQuery query = new ObjectQuery("SELECT * FROM Msvm_ComputerSystem"); //Execute the query ManagementObjectSearcher searcher = new ManagementObjectSearcher(ms, query); //Get the results ManagementObjectCollection computers = searcher.Get(); //loop through found computers listBox1.Items.Clear(); foreach (ManagementObject computer in computers) { Console.WriteLine(computer["ElementName"].ToString()); }Anonymous
February 04, 2008
Ben, we have some custom code written to control VMs on Virtual Server 2005. Is there a back words compatibility layer? Or does all this code need to be re-written for WMI? thanks!