![格式化如何使用返回一组元素的 PowerShell 函数?](https://linux22.com/image/1328273/%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E8%BF%94%E5%9B%9E%E4%B8%80%E7%BB%84%E5%85%83%E7%B4%A0%E7%9A%84%20PowerShell%20%E5%87%BD%E6%95%B0%EF%BC%9F.png)
如果我写这个小函数:
function Foo {
Get-Process | % { $_ }
}
如果我跑
Foo
它仅显示一小部分属性:
PS C:\Users\Administrator> foo
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
86 10 1680 412 31 0,02 5916 alg
136 10 2772 2356 78 0,06 3684 atieclxx
123 7 1780 1040 33 0,03 668 atiesrxx
...
...
但即使只显示 8 列,也还有很多其他属性(如图foo | gm
所示)。
是什么原因导致此功能仅显示这 8 个属性?
我实际上正在尝试构建一个类似的函数,该函数从第三方 .Net 库返回复杂对象。该库正在扁平化对象的 2 级层次结构:
function Actual {
$someDotnetObject.ACollectionProperty.ASecondLevelCollection | % { $_ }
}
此方法以列表形式转储对象(每个属性一行)。
我如何控制显示的内容,保持实际对象可用?
我尝试过这个:
function Actual {
$someDotnetObject.ACollectionProperty.ASecondLevelCollection | % { $_ } | format-table Property1, Property2
}
它在控制台中显示预期的表格:
Property1 Property2
--------- ---------
ValA ValD
ValB ValE
ValC ValF
但是我丢失了我的物品。运行Get-Member
结果显示:
TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatStartData
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
autosizeInfo Property Microsoft.PowerShell.Commands.Internal.Format.AutosizeInfo autosizeInfo {get;set;}
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property System.String ClassId2e4f51ef21dd47e99d3c952918aff9cd {get;}
groupingEntry Property Microsoft.PowerShell.Commands.Internal.Format.GroupingEntry groupingEntry {get;set;}
pageFooterEntry Property Microsoft.PowerShell.Commands.Internal.Format.PageFooterEntry pageFooterEntry {get;set;}
pageHeaderEntry Property Microsoft.PowerShell.Commands.Internal.Format.PageHeaderEntry pageHeaderEntry {get;set;}
shapeInfo Property Microsoft.PowerShell.Commands.Internal.Format.ShapeInfo shapeInfo {get;set;}
TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupStartData
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property System.String ClassId2e4f51ef21dd47e99d3c952918aff9cd {get;}
groupingEntry Property Microsoft.PowerShell.Commands.Internal.Format.GroupingEntry groupingEntry {get;set;}
shapeInfo Property Microsoft.PowerShell.Commands.Internal.Format.ShapeInfo shapeInfo {get;set;}
而不是显示第二级子对象成员。在这种情况下,我无法将结果通过管道传输到等待此类参数的函数。
Powershell 应该如何处理这种情况?
答案1
这实际上是由格式文件控制的。从 powershell help about_Format.ps1xml
:
Windows PowerShell 中的 Format.ps1xml 文件定义 Windows PowerShell 中对象的默认显示。你可以创建自己的 Format.ps1xml 文件来更改对象的显示或定义在 Windows PowerShell 中创建的新对象类型的默认显示。
当 Windows PowerShell 显示对象时,它会使用结构化格式文件中的数据来确定对象的默认显示。格式文件中的数据决定对象是以表格还是列表形式呈现,并决定默认显示哪些属性。
格式仅影响显示。它不会影响哪些对象属性会沿管道传递或如何传递。
根据您的示例,get-process
返回System.Diagnostics.Process
,其(输出格式)定义在DotNetTypes.format.ps1xml
:
<Name>process</Name>
<ViewSelectedBy>
<TypeName>System.Diagnostics.Process</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Label>Handles</Label>
<Width>7</Width>
<Alignment>right</Alignment>
</TableColumnHeader>
<TableColumnHeader>
<Label>NPM(K)</Label>
<Width>7</Width>
<Alignment>right</Alignment>
</TableColumnHeader>
(output omitted)
答案2
尝试这样的操作:
... | ForEach-Object {
Write-Host $_.Something
$_
}
代码块内的尾随$_
传递对象。