如何以与Format-List相同的方式汇总对象?

时间:2013-06-12 19:46:30

标签: powershell formatting

例如,查看进程线程会显示如下内容:

PS C:\> (Get-Process)[0] | Format-List -Property Threads

Threads : {1548, 1600, 15940, 13996}

但如果您实际上直接获取该属性,它看起来像这样:

PS C:\> (Get-Process)[0].Threads

BasePriority            : 8
CurrentPriority         : 9
Id                      : 1548
IdealProcessor          : 
PriorityBoostEnabled    : 
PriorityLevel           : 
PrivilegedProcessorTime : 
StartAddress            : 8790537024736
StartTime               : 
ThreadState             : Wait
TotalProcessorTime      : 
UserProcessorTime       : 
WaitReason              : UserRequest
ProcessorAffinity       : 
Site                    : 
Container               : 

BasePriority            : 8
... etc

格式列表显然有一种智能地汇总对象的方法。它取了一个对象列表,从每个对象中拉出一个代表属性,并将其显示为一个短数组。我找不到允许我以相同方式汇总对象集合的方法或cmdlet。

我希望能够将任意对象集合传递给方法并对其进行汇总。这在列出Exchange对象中的电子邮件地址,列出AD对象中的组以及许多其他地方时使用...我怀疑这些都是特殊情况。


扩展(从@ JoelSmith的评论中学习更多内容):

.NET对象具有formatting definitionsformatting output时由Powershell使用。使用help about_Format.ps1xml [1]可以获得更多详细信息。这些定义是通用的,可以通过任何命令访问,但默认情况下,Powershell中没有函数可以直接检索对象属性的输出,就像在Format-List中显示一样。

一个hackish解决方法是分割和剥离输出,如下所示:

(Get-Mailbox user | Format-List -Property Languages | Out-String).Split(':')[1].Trim()
    # => {en-US,fr-CA}

但是这种方法非常脆弱,当输出跨越多行或在输出中包含冒号时会失败:

(Get-Mailbox user | Format-List -Property EmailAddresses | Out-String).Split(':')[1].Trim()
    # => {smtp

需要的是一种方法,它读取为对象定义的格式化定义并直接检索它,然后使用它输出所需的字符串。我没有在网上找到任何例子。

4 个答案:

答案 0 :(得分:1)

通常.ToString()有效但有时他们忘记实现该方法。

 (Get-Process)[0] | %{$_.Threads.Id}

编辑:回答下面的评论

(Get-Process)[0] | Format-List -Property Threads | Out-String

不幸的是并非所有cmdlet都相同。

答案 1 :(得分:1)

你在找这样的东西吗?

(Get-Process)[0].Threads | Format-Table -Property ID -AutoSize

   Id
   --
13060
13064
13068
13072
13076
13080
13084

这需要针对每个cmdlet进行自定义,具体取决于输出的内容以及所需的字段。它不适用于(Get-Process)[0] | Format-Table -Property Threads -AutoSize的原因是因为Threads返回线程对象,并且像第一个样本一样显示对象数组(对象在集合中的字符串表示{{1 }})。

答案 2 :(得分:1)

到目前为止,这是我能说的:

Id属性是线程对象(System.Diagnostics.ProcessThread)的默认显示属性。 我在PowerShell的任何类型文件中找不到任何跟踪,但我可以改变Format- *显示线程的方式(需要PowerShell 3.0)。

默认格式为cmdlet格式打印每个线程对象的Id值:

Threads : {1548, 1600, 15940, 13996}

格式化cmdlet会检查$FormatEnumerationLimit变量的值(默认值为4)以决定如何格式化对象。 如果结果是一个对象(标量),则只打印为:

Threads : 1548

如果它是一个项目集合,并且集合计数达到$FormatEnumerationLimit(4)的值,它将显示为:

Threads : {1548, 1600, 15940, 13996}

大于$FormatEnumerationLimit的计数看起来像(...表示有更多对象):

Threads : {1548, 1600, 15940, 13996...}

我可以告诉Id是使用的默认属性,因为我可以将其更改为另一个属性并查看其值在输出中的反映。 例如,在这里我将ThreadState设置为默认的显示属性:

PS> Update-TypeData -TypeName System.Diagnostics.ProcessThread -DefaultDisplayProperty ThreadState -Force
PS> (Get-Process)[0] | Format-List -Property Threads

Threads : {Wait, Wait, Wait, Wait...}

# revert back    
PS> Update-TypeData -TypeName System.Diagnostics.ProcessThread -DefaultDisplayProperty Id -Force

希望有所帮助

答案 3 :(得分:1)

您可以使用

PSStandardMembers.DefaultDisplayProperty

PSStandardMembers.DefaultDisplayPropertySet

对象的属性,以确定应为每种类型显示的默认属性。您可以阅读更多相关信息here。我们最近在PowerShell项目中遇到了类似的问题。你可以找到this discussion we've had helpful。 PS v2和v3之间存在一些细微差别,我们在该线程上进行辩论。