首页 > 解决方案 > Powershell:对象对象的格式表?

问题描述

我有一个 PSCustomObjects 的数组列表,我可以使用 Format-Table 输出它,并且看起来像预期的那样。

Name    Property1   Property2   Property3
----    ---------   ---------   ---------
name1   value1      value2      value3

现在它发生了,PSCustomObject 的一个属性需要保存两个(或更多)值,所以我决定遵循面向对象的方法并将该属性也更改为 PSCustomObject,最终出现在包含对象的对象列表中,然后输出如下所示:

Name    Property1   Property2                     Property3
----    ---------   ---------                     ---------
name1   value1      @{Sub1=valueX; Sub2=valueY}   value3

我正在寻找的是 Format-Table 的某种递归输出,它扩展了里面的对象,看起来像这样:

Name    Property1   Sub1     Sub2     Property3
----    ---------   ----     ----     ---------
name1   value1      valueX   valueY   value3

这有可能吗?或者在构建该对象列表时我是否必须回退到“正常”列表?

谢谢你!

标签: powershellpowershell-5.0

解决方案


您需要递归地做的就是发现叶子值的“路径”,然后为它们生成属性表达式选择器:

function Format-FlatTable {
  [CmdletBinding()]
  param(
    [Parameter(ValueFromPipeline=$true)]
    [psobject]$InputObject
  )

  begin {
    function Get-FlatSelector {
      param(
        [psobject]$Object,
        [string]$Prefix
      )

      # Enumerate all properties
      $object.psobject.Properties |ForEach-Object {
        # Nested custom object, let's recurse
        if($_.Value -is [System.Management.Automation.PSCustomObject]){
          Get-FlatSelector $_.Value -Prefix $_.Name 
        }
        else {
          if($prefix){
            # We're not at the root level anymore, construct a property expression table
            @{Name="$prefix.$($_.Name)";Expression=[scriptblock]::Create("`$_.$prefix.$($_.Name)")}
          }
          else{
            # Still at the root level, we can select value properties by name alone
            $_.Name
          }
        }
      }
    }
  }

  process
  {
    # Use the first input object to determine how to flatten
    $selectors = Get-FlatSelector $InputObject[0]

    # Use `Format-Table` to only select flattened property values
    $InputObject |Format-Table $selectors
  }
}

这将产生一个像你想要的表格格式,但没有任何命名冲突:

[pscustomobject]@{
  Name='Name1'
  Property1 = 'value1'
  Property2 = [pscustomobject]@{
    Sub1 = 'valueX'
    Sub2 = 'ValueY'
  }
  Property3 = 'value3'
} |Format-FlatTable

输出:

Name  Property1 Property2.Sub1 Property2.Sub2 Property3
----  --------- -------------- -------------- ---------
Name1 value1    valueX         ValueY         value3

推荐阅读