Reputation: 2172
I have a list of objects that look similar to this:
$srvobj = New-Object PSObject -Property @{
"Prop1" = Do-Something $value
"Prop2" = Do-SomethingElse $othervalue
"Prop3" = Do-AnotherThing $thirdvalue
}
Based on the value of each variable passed to the functions, the objects will have different values for Prop1, Prop2, and Prop3. Is there a way to filter the list of objects so I only return objects that have one of their properties set to false? Ex:
$obj1 = New-Object PSObject -Property @{
"Prop1" = $true
"Prop2" = $true
"Prop3" = $true
}
$obj2 = New-Object PSObject -Property @{
"Prop1" = $true
"Prop2" = $false
"Prop3" = $true
}
$objarray = @($obj1, $obj2)
$fails = $objarray | Where-Object { $_ -contains $false }
If I echoed $fails
in the pseudo-code above, it would only return $obj2
since it had a false value for one of the properties.
I know it is possible to check every value of each property then manually add them to a new array; but the problem with that is that I have a lot of objects, with a lot of properties (more than I am showing in this example).
Is there any way to filter out the array of objects so that I only get the ones I need?
Upvotes: 1
Views: 6746
Reputation: 54971
This is one possible solution:
$obj1 = New-Object PSObject -Property @{
"Prop1" = $true
"Prop2" = $true
"Prop3" = $true
}
$obj2 = New-Object PSObject -Property @{
"Prop1" = $true
"Prop2" = $false
"Prop3" = $true
}
$objarray = @($obj1, $obj2)
$objarray | Where-Object {
$obj = $_
$obj | gm -MemberType Properties | % {
if($obj."$($_.Name)" -eq $false) { $true }
}
}
Or even simpler:
$obj1 = New-Object PSObject -Property @{
"Prop1" = $true
"Prop2" = $true
"Prop3" = $true
}
$obj2 = New-Object PSObject -Property @{
"Prop1" = $true
"Prop2" = $false
"Prop3" = $true
}
$objarray = @($obj1, $obj2)
$objarray | ? { $_.psobject.Properties | ? { $_.Value -eq $false } }
Upvotes: 0
Reputation: 36332
Ok, we're going to add an additional member to your custom objects so that they remember who they are once they're added to the array. Then we'll filter using -match
and we'll get what you want.
$obj1 = New-Object PSObject -Property @{
"Name" = "Obj1"
"Prop1" = $true
"Prop2" = $true
"Prop3" = $true
}
$obj2 = New-Object PSObject -Property @{
"Name" = "Obj2"
"Prop1" = $true
"Prop2" = $false
"Prop3" = $true
}
$objarray = @($obj1, $obj2)
$fails = $objarray | Where-Object { $_ -match $false }
I suppose if you really, really want it to return $obj2
you could escape a $
into the Name value like "Name" =
"`$obj2"
Upvotes: 1
Reputation: 3163
Try this:
$fails = $objArray | % {
$obj = $_
$obj.PSObject.Properties | % {
if ($_.Value -eq $false) {
$obj
}
}
}
PSObject is a hidden property on all PSObjects, that contains a bunch of information about the object, including being able to iterate through the properties.
Upvotes: 3