Powershell 如何以格式列表的方式总结对象?

Powershell 如何以格式列表的方式总结对象?,powershell,formatting,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 IdealPro

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

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
但如果你真的直接抓住了那块地产,它看起来是这样的:

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对象具有Powershell在运行时使用的。更多详细信息可通过
关于\u Format.ps1xml的帮助获得。这些定义是通用的,可以通过任何命令访问,但默认情况下,Powershell中没有函数可以直接检索对象属性的输出,因为它将显示在格式列表中

一种黑客的解决方法是像这样分割和剥离输出:

(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
需要的是一个方法,该方法读取为对象定义的格式定义并直接检索它,然后使用它输出所需的字符串。我在网上找不到任何示例。

通常.ToString()可以工作,但有时他们会忘记实现该方法

 (Get-Process)[0] | %{$_.Threads.Id}
编辑:回答下面的评论

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

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

您正在寻找类似的内容吗

(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
返回线程对象,并且对象数组的显示方式与您的第一个示例类似(对象在集合中的字符串表示方式
{..}
)。

到目前为止,我可以告诉您:

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

默认情况下,format cmdlet打印每个线程对象的Id值:

Threads : {1548, 1600, 15940, 13996}
格式化cmdlet检查
$FormatEnumerationLimit
变量的值(默认值为4)以决定如何格式化对象。 如果结果是一个对象(标量),则仅打印为:

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

Threads : {1548, 1600, 15940, 13996}
大于
$FormatEnumerationLimit
的计数将如下所示(…表示有更多对象):

我可以告诉您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
希望对您有所帮助

您可以使用

PSStandardMembers.DefaultDisplayProperty


对象的属性,以确定应为每种类型显示的默认属性。你可以阅读更多关于它的内容。最近,我们在like PowerShell项目中遇到了类似的问题。你可以找到。PS v2和v3之间存在一些细微的差异,我们对此进行了讨论。

奇怪的是,通常您可以通过管道让成员了解cmdlet的底层属性、方法、对象类型等。当我在此处使用您的cmdlet执行此操作时,会得到多个不同的类型(get Process)[0]|格式列表-属性线程|获取成员类型名称:Microsoft.PowerShell.Commands.Internal.Format.FormatStartData类型名称:Microsoft.PowerShell.Commands.Internal.Format.GroupStartData类型名称:Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData仅适用于此特定情况。。。我无法想象Format List有500个方法来处理各种cmdlet中使用的所有不同类型的集合。我特别需要能够传递任意集合;线程只是一个例子。cmdlet可以指定默认的表视图和列表视图显示的内容,并且可以自定义,而许多cmdlet可以帮助您使用.ToString()方法。并非每个cmdlet都实现了该方法,除了重新格式化列表输出的格式之外,您可以做的事情不多。像这样:(Get Process)[0]|格式列表-属性线程| Out string我对你的术语有点困惑;线程不是cmdlet,而是对象的集合。它没有与之直接关联的代码。Format-List cmdlet能够以某种方式重新格式化各种各样的对象集合。此功能是否在外部可用?您的解决方法有许多额外的无关文本。Format-List是格式化Get-Process cmdlet的一种方法。所有cmdlet都是对象。您要问的是,为什么编写Get进程的人使用格式列表进行输出。这是由创建者在与cmdlet关联的xml文件中配置的。有关这方面的更多信息:绝对有用,但目标是有一种方法可以直接检索冒号后面的文本,而无需文本黑客和
格式列表
。我想操作的大多数对象已经有了很好的格式信息。。。但是除了
Format-*
cmdlet之外,没有任何函数可以读取该元数据。我必须以不同的方式阅读您的问题。如果目标是获取每个对象的线程,那么直接引用属性,或者使用select object扩展它。他基本上要求的是不存在的魔法属性。遗憾的是,powershell没有那么聪明。你需要知道