Hyper-V ID Hash Table

Microsoft Hyper-VIn Hyper-V, one of the challenges (at least that I’ve run into) has to do with naming. In addition to a name, Hyper-V objects such as virtual machines, are identified with a GUID. Most of the VM-related PowerShell cmdlets will let you specify a virtual machine name. But sometimes you’ll run across the GUID and wonder what is the corresponding virtual machine. Here’s a WMI query using Get-CIMInstance that shows the currently open terminal connections to a few virtual machines.

PS C:\> get-ciminstance -Namespace root\virtualization -class msvm_terminalconnection | Select connectionID,installdate

connectionID                                      installdate
------------                                      -----------
Microsoft:13876524-BFD8-40A1-95E3-926E37ACFBAB\1  1/3/2013 11:27:50 AM
Microsoft:80E967E6-57F9-4ECF-998A-D07B20B2287F\2  1/3/2013 8:12:56 AM
Microsoft:E1EDE8DA-D632-4F77-81C4-B117FFF1FE15\1  1/3/2013 8:08:35 AM

The GUID in the connection ID corresponds to a virtual machine. Here’s my approach for “translating” the GUID to a name. Every VM has an ID.

PS C:\> (get-vm chi-dc01).id

Guid
----
f7d3ad8b-6329-43a3-991e-8a630a94ec40

There is also an VMID property but that is merely an alias to ID. As you can see, the ID is a GUID object so to get just the GUID string takes another step.

PS C:\> (get-vm chi-dc01).id.guid
f7d3ad8b-6329-43a3-991e-8a630a94ec40

Now that I know how to capture this information, I can build a “lookup” object using a hash table.

PS C:\> Get-VM | Group-Object  -property {$_.ID.GUID} -AsHashTable -AsString

Here’s what I end up with:

vmidhash

Naturally, it makes more sense to save this to a variable.

PS C:\> $vmhash = Get-VM | Group-Object  -property {$_.ID.GUID} -AsHashTable -AsString

The VM GUID is the key and the VM object is the value. I can get items a few ways.

PS C:\> $vmhash.'13876524-bfd8-40a1-95e3-926e37acfbab'

Name     State   CPUUsage(%) MemoryAssigned(M) Uptime   Status
----     -----   ----------- ----------------- ------   ------
CHI-FP01 Running 0           761               03:34:51 Operating normally

PS C:\> $vmhash.item('13876524-bfd8-40a1-95e3-926e37acfbab')

Name     State   CPUUsage(%) MemoryAssigned(M) Uptime   Status
----     -----   ----------- ----------------- ------   ------
CHI-FP01 Running 0           761               03:35:11 Operating normally

PS C:\> $vmhash.GetEnumerator() | where {$_.name -match '13876524-bfd8-40a1-95e3-926e37acfbab'} | se
lect -ExpandProperty Value

Name     State   CPUUsage(%) MemoryAssigned(M) Uptime   Status
----     -----   ----------- ----------------- ------   ------
CHI-FP01 Running 0           761               03:36:29 Operating normally

Now I can add some logic to my Get-CIMInstance command to resolve the GUID to the VM name.

$vmhash = Get-VM | Group-Object  -property {$_.ID.GUID} -AsHashTable -AsString

Get-CimInstance -Namespace root\virtualization -class msvm_terminalconnection |
Select @{Name="Started";Expression={$_.installdate}},
@{Name="RunTime";Expression={(Get-Date)-$_.InstallDate}},
@{Name="VM";Expression={  
  #define a GUID regex
 [regex]$rx="(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}"
 
 $guid = $rx.Match($_.ConnectionID).Value
 $vmhash.item($guid).Name
}}

I also tweaked a few other properties. I extracted the GUID using a regular expression and then found the corresponding entry in the hash table. I could have added a little extra logic to test if the GUID existed as a key but I decided to just plow ahead.

vmidhashlookup

The hash table makes it very easy now to resolve virtual machine GUID’s to a user friendly name.

Post to Twitter Post to Plurk Post to Yahoo Buzz Post to Delicious Post to Digg Post to Facebook Post to FriendFeed Post to Google Buzz Post to Ping.fm Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati

About the Author

PowerShell.org Announcer

This is the official account for PowerShell.org and sponsor announcements.