【问题标题】:How to display all properties with Format-Table cmdlet如何使用 Format-Table cmdlet 显示所有属性
【发布时间】:2021-06-11 08:58:01
【问题描述】:

我有几个 [pscustomobject] 对象不能具有所有属性。

例如:

PS> $1 = [pscustomobject]@{ A='a1'; B='b1' }
PS> $2 = [pscustomobject]@{ A='a2'; C='c2' }

我尝试使用Format-Table 显示所有属性,如下所示:

PS> $1,$2 | Format-Table

A  B
-  -
a1 b1
a2

PS> $2,$1 | Format-Table

A  C
-  -
a2 c2
a1

但每次它只显示集合中第一个对象的属性。

我想显示所有属性,例如我设置-Property 参数显式

PS> $1,$2 | Format-Table -Property A,B,C

A  B  C
-  -  -
a1 b1
a2    c2

设置-Property 参数是好的,如果:

  1. 所有属性集都是预先知道的
  2. 集合很小,我可以用Get-Member -MemberType Properties获得所有属性

但我有一个庞大的集合(超过 10000 个对象),属性未知,所以我需要帮助。

备注: Format-Table 将仅用于小切片(10-100 个元素)。

【问题讨论】:

    标签: powershell pscustomobject


    【解决方案1】:

    为此,您可以使用以下函数将所有属性合并到第一个对象中:

    function Complete-ObjectHeaders {
        # function to add properties to the first item in a collection of PSObjects
        # when this object is missing properties from items further down the array.
        # you may need this if you have such a collection and want to export it
        # to Csv, since Export-Csv (and also Format-Table) only looks at the FIRST
        # item to create the csv column headers.
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true, Position = 0)]
            [PSObject[]]$Collection,
    
            [int]$MaxItemsToTest = -1,  # < 0 --> test all items in the collection
            [switch]$SortHeaders
        ) 
    
        # Try and find all headers by looping over the items in the collection.
        # The headers will be captured in the order in which they are found. 
        if ($MaxItemsToTest -gt 0) {
            $MaxItemsToTest = [math]::Min($MaxItemsToTest, $Collection.Count)
            $headers = for($i = 0; $i -lt $MaxItemsToTest; $i++) {
                ($Collection[$i].PSObject.Properties).Name
            }
            $headers = $headers | Select-Object -Unique
        }
        else {
            $headers = $Collection | ForEach-Object {($_.PSObject.Properties).Name} | Select-Object -Unique
        }
    
        if ($SortHeaders) { $headers = $headers | Sort-Object }
    
        # update the first object in the collection to contain all headers
        $Collection[0] = $Collection[0] | Select-Object $headers
    
        ,$Collection
    }
    

    这样使用:

    $1 = [pscustomobject]@{ A='a1'; B='b1' }
    $2 = [pscustomobject]@{ A='a2'; C='c2' }
    
    # just output to console
    Complete-ObjectHeaders -Collection $1,$2 | Format-Table -AutoSize
    
    # or capture the merged array of objects in a new variable you can save as CSV file for instance
    $merged = Complete-ObjectHeaders -Collection $1,$2
    $merged | Export-Csv -Path 'D:\Test\Merged.csv' -NoTypeInformation
    

    输出:

    A  B  C 
    -  -  - 
    a1 b1   
    a2    c2
    

    【讨论】:

      【解决方案2】:

      感谢@theo 提供answer

      我用它编写了我自己的函数版本,它支持流水线

      function Expand-Properties {
        [Cmdletbinding()]
        param(
          [Parameter(ValueFromPipeline)]
          $InputObject,
          [Parameter()]
          [Alias('All')]
          [switch]
          $ExpandAll,
          [Parameter()]
          [switch]
          $SortHeaders
        )
      
        begin {
          $collection = [System.Collections.ArrayList]::new()
          $properties = [System.Collections.ArrayList]::new()
        }
      
        process {
          [void]$collection.Add($InputObject)
          $properties.AddRange((($InputObject.PSObject.Properties).Name))
        }
      
        end {
          if ($SortHeaders) {
            $properties = $properties | Sort-Object -Unique
          } else {
            $properties = $properties | Select-Object -Unique
          }
          if ($ExpandAll) {
            for ($i = 0; $i -lt $collection.Count; ++$i) {
              $collection[$i] = $collection[$i] | Select-Object -Property $properties
            }
          } else {
            $collection[0] = $collection[0] | Select-Object -Property $properties
          }
          $collection
        }
      }
      

      示例:

      PS> $1 = [pscustomobject]@{ A='a1'; B='b1' }
      PS> $2 = [pscustomobject]@{ A='a2'; C='c2' }
      PS> $1, $2 | Expand-Properties
      
      A  B  C 
      -  -  - 
      a1 b1   
      a2    c2
      

      【讨论】:

      • 非常感谢您提供此信息。它对我来说就像一个魅力:)。我将输出行调整为$collection | out-gridview,因为我有许多对象属性并不完全适合控制台屏幕。
      猜你喜欢
      • 2015-07-23
      • 2015-05-14
      • 2022-11-19
      • 2015-07-18
      • 1970-01-01
      • 2022-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多