Search code examples
powershellfiltercollectionsselect-object

How do I select objects from a collection that has any property containing specific text, and only outputting only those specific properties?


I have a collection of AdObjects. I need to output any object in that collection that has a property value that matches specific text and only want to output just those matching properties.

For example:

# $adObjects contain following objects and properties.
#   I'm searching for properties containing "bingo!"

$adObjects

name            : object1
property1       : asdf
property2       : bingo!
property3       : bingo!

name            : object2
property1       : asdf
property2       : bingo!
property3       : asdf

name            : object3
property1       : asdf
property2       : asdf
property3       : asdf

# Do Stuff

#Expected Output

name            : object1
property2       : bingo!
property3       : bingo!

name            : object2
property2       : bingo!

I'm fairly certain this won't be possible with just some sort of filter on any properties during Select-Object and will likely require some form of

  1. enumerate through each $adobject
  2. enumerate through each property
  3. if property.value like "bingo!", then
  4. create new collection of pscustomobjects with a name property plus any other properties that match
  5. output entire collection of pscustomobjects and all their properties

I guess my question is: Am I on the right track, or is there an easier way? I've tried using ChatGPT but it simply cannot do it. Either my prompts are bad or this is just too complex.


Solution

  • This is doable but not very efficient, you can access the object's properties and their values using .PSObject.Properties, then the logic is to determine if the property .Value is equal to bingo! or the property .Name is equal to name, and when that condition is met it is added to a new object.

    $data = @(
        [pscustomobject]@{
            name      = 'object1'
            property1 = 'asdf'
            property2 = 'bingo!'
            property3 = 'bingo!'
        }
        [pscustomobject]@{
            name      = 'object2'
            property1 = 'asdf'
            property2 = 'bingo!'
            property3 = 'asdf'
        }
        [pscustomobject]@{
            name      = 'object3'
            property1 = 'asdf'
            property2 = 'asdf'
            property3 = 'asdf'
        }
    )
    
    $data | ForEach-Object {
        $properties = $_.PSObject.Properties
        $newObj = [ordered]@{}
    
        foreach ($property in $properties) {
            if ($property.Value -eq 'bingo!' -or $property.Name -eq 'name') {
                $newObj[$property.Name] = $property.Value
            }
        }
    
        if ($newObj.Keys.Count -gt 1) {
            [pscustomobject] $newObj
        }
    } | Format-List