Filtering Based on Hash Table Contents

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

  • Author
    Posts
  • #15732
    Profile photo of Jacob Benson
    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
    Profile photo of Jacob Benson
    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
    Profile photo of Jacob Benson
    Jacob Benson
    Member

    That will work. Thanks Dave!

  • #15750
    Profile photo of Jacob Benson
    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
    Profile photo of Dave Wyatt
    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
    Profile photo of Jacob Benson
    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
    Profile photo of Dave Wyatt
    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.