PowerShell 递归对象属性

问题描述 投票:0回答:2

我需要一种方法(递归地)为我提供对象的所有属性。 不知道传输的对象有多少个子对象。

示例对象:

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

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

非常感谢!

powershell object recursion
2个回答
10
投票

使用隐藏的

psobject
成员集枚举属性,然后递归:

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

输出(带有示例对象层次结构):

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

请注意,上面显示的函数没有努力防止无限循环递归引用,因此:

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

会让你的CPU旋转


0
投票

根据@Matthias的答案,我修改为获得不同类型的列表输出,因为“我需要那样”。

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

如果您使用变量名称作为 -ParentName 作为选项来调用它,您将得到以下列表:

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   

就像马蒂亚斯(Matthias)一样,我懒得添加属性循环保护,它会毁了那个例子。

© www.soinside.com 2019 - 2024. All rights reserved.