Author Posts

May 29, 2014 at 8:00 am

I have a bunch of Custom Properties in Virtual Machine Manager (VMM). I am trying to filter based on those values (which are stored as a hashtable) and am struggling figuring out how to do this. I want to be able to run a command that does something like this:

Get-SCVirtualMachine -VMMServer Blah -All | Select-Object Name | Where MyCustomProperty -ne ""

Here is what I have figured out so far:

$props = Get-SCVirtualMachine -VMMServer Blah -Name Comp | Select CustomProperty

$props
CustomProperty
--------------
{Application Owner, Update Time, Last Updated, Infrastructure Owner...

$props | gm
TypeName: Selected.Microsoft.SystemCenter.VirtualMachineManager.VM

Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
CustomProperty NoteProperty System.Collections.Hashtable CustomProperty=System.Collections.Hashtable

$props.CustomProperty
Name Value
---- -----
Application Owner Someone
Update Time 1:00 AM
Last Updated 03/28/2013
Infrastructure Owner Jacob Benson
Day To Be Updated 3rd Saturday - DEV

$props.CustomProperty.'Application Owner' -ne ""
True

However, I have no idea how to work this into a Where-Object (if that's what I even want to do) to Filter based on the contents of a value in the hash table.

If I export all of the VMM properties to Excel, all it shows me is that the values for CustomProperty are part of a hash table, it doesn't display any of the values.

May 29, 2014 at 8:15 am

I answered my own question, but now I have another question.

This is the command that I run to get my list (as an example).

Get-SCVirtualMachine -VMMServer Blah -All | Select Name | Where-Object {$_.CustomProperty.'ApplicationOwner' -ne ""}

However, now the question is how do I select the objects in the hash table like this (this obviously doesn't work):

Get-SCVirtualMachine -VMMServer Blah -All | Select Name,CustomProperty.'Application Owner' | Where-Object {$_.CustomProperty.'ApplicationOwner' -ne ""}

This is closer, but just gives me the hash table, not the values inside:

Get-SCVirtualMachine -VMMServer Blah -All | Select-Object Name,CustomProperty | Where-Object {$_.CustomProperty.'ApplicationOwner' -ne ""}

May 29, 2014 at 8:43 am

So you're trying to basically unwrap the CustomProperty hashtable and produce an object which has those properties? For that, I'd probably try this:

Get-SCVirtualMachine -VMMServer Blah -All |
ForEach-Object {
    $obj = $_
    New-Object psobject -Property $obj.CustomProperty |
    Add-Member -NotePropertyName 'Name' -NotePropertyValue $obj.Name -Passthru
} |
Where-Object { $_.'Application Owner' -ne '' }

Here I just used the hashtable to pass to New-Object, which is a lazy but convenient way of getting the job done, if you want the property names to match what's already in $_.CustomProperty. If you wanted to do some transformation on those names (such as changing "Application Owner" with a space to just ApplicationOwner), you'd have to hard-code the possible from / to values.

Edit: Note that the -NotePropertyName and -NotePropertyValue parameters to Add-Member were added in PowerShell 3.0. For 2.0 compatibility, you'd use -MemberType NoteProperty -Name 'Name' -Value $obj.Name

May 29, 2014 at 11:13 am

That will work. Thanks Dave!

May 29, 2014 at 11:25 am

I spoke too soon. All that ends up giving me is a column with one of the Custom Properties (Last Updated) and the Name of the VM. How/Where do I add the select-object so that I can get the Name,CustomProperty1,CustomProperty2, etc etc. Right now it's giving the last of the 4 Custom Properties in the hash table.

PS. I had no idea this would be this complicated.

May 29, 2014 at 11:29 am

Hmm... I'll need to know more about the objects that are in play here. It doesn't seem like that CustomProperty field is really a HashTable, based on what you've said. Try this, and paste the output here:

Get-SCVirtualMachine -VMMServer Blah -All |
Select-Object -First 1 |
ForEach-Object {
    Get-Member -InputObject $_ | Out-Host
    Get-Member -InputObject $_.CustomProperty | Out-Host
}

May 29, 2014 at 11:47 am

Turns out I was making this much more complicated than I needed it to. I was confused because Intellisense wasn't giving me what I thought should be there. Turns out I just need to run the command like this.

Get-SCVirtualMachine -VMMServer Blah -All | Where-Object {$_.CustomProperty.'ApplicationOwner' -ne ""} | Select-Object Name,{$_.CustomProperty.'Application Owner'},{$_.CustomProperty.'Last Updated'}