Fun with PowerShell: Hyper-V Virtual Machine details
August 11, 2010
posted by James Kehr
Before I begin I will make a full confession. This code isn’t actually mine. Not really. I chopped most of it out of the PowerShell Management Library for Hyper-V.
Why would I do such a thing? I generally dislike calling external files in my PowerShell scripts. Not always, but most of the time. The more external files you have the harder it is to make a script highly portable, and, under most circumstances, scripts should be highly portable with as few external dependencies as possible. And so I ripped out Get-VM from hyperv.ps1 and turned it into a self-standing function called getVmDetails.
- function getVmDetails {
- param ($VM = $(throw "I need a VM please"), $hvServer = $(hostname))
- # check whether the VM is a string, if so grab the $VM object
- if ($VM -isnot [System.Management.ManagementBaseObject]) {
- $VM = gwmi -class "MSVM_ComputerSystem" -namespace "root\virtualization" -computername "$hvServer" | ?{$_.Caption -eq "Virtual Machine" -and $_.ElementName -match "$vm"}
- }
- $KVPComponent=(Get-WmiObject -computername $VM.__Server -Namespace root\virtualization -query "select * from Msvm_KvpExchangeComponent where systemName = '$($vm.name)'")
- if ($KVPComponent.GuestIntrinsicExchangeItems ) {
- ($KVPComponent.GuestIntrinsicExchangeItems + $KVPComponent.GuestExchangeItems )|
- forEach -begin {$KVPObj = New-Object -TypeName System.Object
- Add-Member -inputObject $KvpObj -MemberType NoteProperty -Name "VMElementName" -Value $vm.elementName} `
- -process {([xml]$_).SelectNodes("/INSTANCE/PROPERTY") | forEach -process {if ($_.name -eq "Name") {$propName=$_.value}; if ($_.name -eq "Data") {$Propdata=$_.value} } -end {Add-Member -inputObject $KvpObj -MemberType NoteProperty -Name $PropName -Value $PropData}} `
- -end {[string[]]$Descriptions=@()
- if ($KvpObj.ProcessorArchitecture -eq 0) {$descriptions += "x86" }
- if ($KvpObj.ProcessorArchitecture -eq 9) {$descriptions += "x64" }
- if ($KvpObj.ProductType -eq 1 ) {$descriptions += "Workstation" }
- if ($KvpObj.ProductType -eq 2 ) {$descriptions += "Domain Controller" }
- if ($KvpObj.ProductType -eq 3 ) {$descriptions += "Server" }
- $suites=@{1="Small Business";2="Enterprise";4="BackOffice";8="Communications";16="Terminal";32="Small Business Restricted";64="Embedded NT";128="Data Center";256="Single User";512="Personal";1024="Blade"}
- foreach ($Key in $suites.keys) {if ($KvpObj.suiteMask -band $key) {$descriptions += $suites.$key} }
- Add-Member -inputObject $KvpObj -MemberType NoteProperty -Name "Descriptions" -Value $descriptions
- $KvpObj
- }
- }
- }
$VM can be either a string or a [System.Management.ManagementBaseObject] object. If you chose to pass a string it needs to be the ElementName of the VM, which is the name of the VM as it appears in Hyper-V Manager. If the VM is on a remote server you have to pass the hostname of the Hyper-V host server as well; otherwise, the script will assume it's the local server.
Usage examples:
$vmDetails = getVmDetails "Win7_x86"
$vmDetails = getVmDetails "Win7_x86" "HvHost02"
$VM = gwmi -class "MSVM_ComputerSystem" -namespace "root\virtualization" -computername "HvHost02" | ?{$_.Caption -eq "Virtual Machine" -and $_.ElementName -match "Win7_x86"}
$vmDetails = getVmDetails $VM
Sample output would be:
VMElementName : Win7_X86
FullyQualifiedDomainName : WIN7X86.domain.com
OSName : Windows 7 Enterprise
OSVersion : 6.1.7600
CSDVersion :
OSMajorVersion : 6
OSMinorVersion : 1
OSBuildNumber : 7600
OSPlatformId : 2
ServicePackMajor : 0
ServicePackMinor : 0
SuiteMask : 256
ProductType : 1
OSEditionId : 4
ProcessorArchitecture : 0
IntegrationServicesVersion : 6.1.7600.16385
NetworkAddressIPv4 : 192.168.1.100
NetworkAddressIPv6 :
RDPAddressIPv4 : 192.168.1.100
RDPAddressIPv6 :
Descriptions : {x86, Workstation, Single User}
When the output of the function is loaded into a variable you get a PSObject that you can reference as usual. So $vmDetails.FullyQualifiedDomainName will give you the hostname of the guest operating system running on the VM, and $vmDetails.Descriptions[0] will give the bitness of the guest operating system.
Pretty handy, isn't it?
#James Kehr
Get-Member $OW | ?{$_.title -eq "System Administrator"`
-and $_.certification -contains 'MCITP:SA 2008, MCSE 2000, MCDST, Network+, A+'}
New-Variable -name company -value 'ORCS Web, Inc.' -description ‘www.orcsweb.com | 1.888.313.9421’












