Filtering Based on Hash Table Contents

This topic contains 6 replies, has 2 voices, and was last updated by  Jacob Benson 3 years, 4 months ago.

  • Author
    Posts
  • #15732

    Jacob Benson
    Member

    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.

  • #15735

    Jacob Benson
    Member

    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 ""}

  • #15749

    Jacob Benson
    Member

    That will work. Thanks Dave!

  • #15750

    Jacob Benson
    Member

    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.

  • #15751

    Dave Wyatt
    Moderator

    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
    }
    
  • #15752

    Jacob Benson
    Member

    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'}

  • #15740

    Dave Wyatt
    Moderator

    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

You must be logged in to reply to this topic.