Alex
Alex

Reputation: 155

PowerShell recursive object properties

I need a method that gives me all the properties of an object (recursively). It is not known how many sub-objects the transferred object has.

Example object:

$Car = [PSCustomObject] @{
    Tire          = [PSCustomObject] @{
        Color = "Black"
        Count = 4
    }

    SteeringWheel = [PSCustomObject]@{
        Color   = "Blue"
        Buttons = 15
    }
}

Thank you so much!

Upvotes: 4

Views: 3370

Answers (2)

Joachim Otahal
Joachim Otahal

Reputation: 332

Based on the answer of @Matthias I modified to get a different type of list output since "I needed it that way".

function Get-PropertiesRecursive {
    param (
        [Parameter(ValueFromPipeline)][object]$InputObject,
        [String]$ParentName
    )
    if ($ParentName) {$ParentName +="."}
    foreach ($Property in $InputObject.psobject.Properties) {
        if ($Property.TypeNameOfValue.Split(".")[-1] -ne "PSCustomObject") {
            [pscustomobject]@{
                TypeName = $Property.TypeNameOfValue.Split(".")[-1]
                Property = "$ParentName$($Property.Name)"
                Value = $Property.Value
            }
        } else {
            Get-PropertiesRecursive $Property.Value -ParentName "$ParentName$($Property.Name)"
        }
    }
}

If you call it with the variable name as -ParentName as option you will get this list:

Get-PropertiesRecursive $Car -ParentName '$Car'

TypeName Property                   Value
-------- --------                   -----
String   $Car.Tire.Color            Black
Int32    $Car.Tire.Count            4    
String   $Car.SteeringWheel.Color   Blue 
Int32    $Car.SteeringWheel.Buttons 15   

And just as Matthias I was too lazy to add property-loop protection, it would have blown up that example.

Upvotes: 1

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174465

Use the hidden psobject member set to enumerate the properties, then recurse:

function Resolve-Properties 
{
  param([Parameter(ValueFromPipeline)][object]$InputObject)

  process {
    foreach($prop in $InputObject.psobject.Properties){
      [pscustomobject]@{
        Name = $prop.Name
        Value = $prop.Value
      }
      Resolve-Properties $prop.Value
    }
  }
}

Output (with your sample object hierarchy):

PS C:\> Resolve-Properties $Car

Name          Value
----          -----
Tire          @{Color=Black; Count=4}
Color         Black
Length        5
Count         4
SteeringWheel @{Color=Blue; Buttons=15}
Color         Blue
Length        4
Buttons       15

Be careful, the function shown above makes no effort to protect against infinitely looping recursive references, so:

$a = [pscustomobject]@{b = [pscustomobject]@{a = $null}}
$a.b.a = $a
Resolve-Properties $a

Will send your CPU spinning

Upvotes: 10

Related Questions