Fun with PowerShell: Hyper-V Virtual Machine details

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.

http://pshyperv.codeplex.com/

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.

 
  1. function getVmDetails {   
  2.     param ($VM = $(throw "I need a VM please"), $hvServer = $(hostname))   
  3.     # check whether the VM is a string, if so grab the $VM object   
  4.     if ($VM -isnot [System.Management.ManagementBaseObject]) {   
  5.         $VM = gwmi -class "MSVM_ComputerSystem" -namespace "root\virtualization" -computername "$hvServer" | ?{$_.Caption -eq "Virtual Machine" -and $_.ElementName -match "$vm"}   
  6.     }   
  7.     $KVPComponent=(Get-WmiObject -computername $VM.__Server -Namespace root\virtualization -query "select * from Msvm_KvpExchangeComponent where systemName = '$($vm.name)'")   
  8.     if ($KVPComponent.GuestIntrinsicExchangeItems  ) {   
  9.     ($KVPComponent.GuestIntrinsicExchangeItems + $KVPComponent.GuestExchangeItems )|    
  10.         forEach -begin {$KVPObj = New-Object -TypeName System.Object    
  11.                 Add-Member -inputObject $KvpObj -MemberType NoteProperty -Name "VMElementName" -Value $vm.elementName} `   
  12.          -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}}  `   
  13.          -end {[string[]]$Descriptions=@()   
  14.                if ($KvpObj.ProcessorArchitecture -eq 0)  {$descriptions += "x86" }   
  15.                if ($KvpObj.ProcessorArchitecture -eq 9)  {$descriptions += "x64" }   
  16.                if ($KvpObj.ProductType -eq 1 )  {$descriptions += "Workstation" }   
  17.                if ($KvpObj.ProductType -eq 2 )  {$descriptions += "Domain Controller" }   
  18.                if ($KvpObj.ProductType -eq 3 )  {$descriptions += "Server" }    
  19.                $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"}   
  20.                foreach  ($Key in $suites.keys) {if ($KvpObj.suiteMask -band $key)  {$descriptions += $suites.$key} }   
  21.                Add-Member -inputObject $KvpObj -MemberType NoteProperty -Name "Descriptions" -Value $descriptions  
  22.     
  23.                $KvpObj  
  24.          }    
  25.   }   
  26. }  

$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’

blog comments powered by Disqus