我有这个PowerShell cmdlet,它返回零个或多个自定义对象;返回的每个对象都有Type
,ID
和Status
属性,因此将cmdlet的输出发送到控制台将导致如下所示:
Type ID Status
---- -- ------
Foo 1 Active
Foo 3 Active
Baz 1 Inactive
Baz 2 Active
Baz 3 Broken
Bar 4 Active
使用PowerShell格式化文件,我尝试生成以下输出:
ID Foo Baz Bar
-- --- --- ---
1 Active Inactive
2 Active
3 Active Broken
4 Active
这有可能吗?通过ID对项目进行分组似乎很简单,但我还没有了解如何动态生成每个Type
的列?
请注意,我无法对cmdlet的输出类型进行任何更改,因为这会破坏我可能想要输出输出的其他cmdlet - 这就是为什么我认为解决方案理想情况下只涉及格式化。
修改 另一种思考这个问题的方法可能是:"你可以使用PowerShell格式化文件在管道中的最后一个项目被处理后打印一种页脚吗?"我想这假设每个单独项目的处理可以某种方式缓冲该项目,然后可以使用汇总缓冲项目的脚本块构建页脚。
答案 0 :(得分:1)
PowerShell格式文件不会对您有所帮助。例如,格式文件确定在您运行Get-ChildItem
或Get-Process
时显示哪些字段及其顺序。你在这里做的是动态变换。在SQL中,此操作称为PIVOT。 PIVOT通常是一种痛苦的动态PIVOTs,因为它们从根本上改变了数据。你将不得不手动完成。
那就是说,这并不是很难:
$Data = [PSCustomObject]@{Type = 'Foo'; ID = 1; Status = 'Active' },
[PSCustomObject]@{Type = 'Foo'; ID = 3; Status = 'Active' },
[PSCustomObject]@{Type = 'Baz'; ID = 1; Status = 'Inactive'},
[PSCustomObject]@{Type = 'Baz'; ID = 2; Status = 'Active' },
[PSCustomObject]@{Type = 'Baz'; ID = 3; Status = 'Broken' },
[PSCustomObject]@{Type = 'Bar'; ID = 4; Status = 'Active' }
function Get-PivotedObject {
param (
[Parameter(Mandatory = $true)]
$Data,
[Parameter(Mandatory = $true)]
[string]$Entity,
[Parameter(Mandatory = $true)]
[string]$Attribute,
[Parameter(Mandatory = $true)]
[string]$Value
)
$PivotHeaders = $Data | Select-Object -ExpandProperty $Attribute -Unique;
$Data | Select-Object -ExpandProperty $Entity -Unique | ForEach-Object {
$Record = [ordered]@{
$Entity = $_;
}
foreach ($Header in $PivotHeaders) {
$Record.$Header = $Data | Where-Object {
($_.$Entity -eq $Record.$Entity) -and ($_.$Attribute -eq $Header)
} | Select-Object -ExpandProperty $Value -First 1;
# Notice this only returns the first value it finds for a given entity and attribute
}
[PSCustomObject]$Record;
}
}
Get-PivotedObject -Data $Data -Entity 'ID' -Attribute 'Type' -Value 'Status'