Powershell未显示PSCustomObjects(或其他对象)的某些属性

Powershell未显示PSCustomObjects(或其他对象)的某些属性,powershell,format,output,Powershell,Format,Output,最初,这个问题是在调查关于从哈希表数组中选择项的问题27373126的答案时提出的。这是一种比使用Foreach对象或带有哈希表参数的Select对象更短的获取属性的方法 发现我可以使用脚本块参数获取项以选择对象,如下所示: $hash = @{title="title1";detail="detail1"},@{title="title2";detail="detail2"} $hash | select-obje

最初,这个问题是在调查关于从哈希表数组中选择项的问题27373126的答案时提出的。这是一种比使用Foreach对象或带有哈希表参数的Select对象更短的获取属性的方法

发现我可以使用脚本块参数获取项以选择对象,如下所示:

$hash = @{title="title1";detail="detail1"},@{title="title2";detail="detail2"}
$hash | select-object {$_.title},{$_.detail}
function title{$_.title};function detail{$_.detail}
$hash | select {title},{detail}
通过定义如下函数,我可以整理使用名为$\ title和$\ detail的属性生成的输出对象:

$hash = @{title="title1";detail="detail1"},@{title="title2";detail="detail2"}
$hash | select-object {$_.title},{$_.detail}
function title{$_.title};function detail{$_.detail}
$hash | select {title},{detail}
然后,我尝试使用由属性名称列表定义的属性自动生成输出,我知道这些属性名称是错误的,这正是我发现问题的原因:

'title','detail' | foreach { $hash | select $_ }

title
-----





# 4 blank lines
我知道为什么有4个空行。$hash中没有标题成员,它是标题项。令人惊讶的是没有详细的专栏。我试过这个:

'title','detail' | foreach { $hash | select $_ } | gm

   TypeName: Selected.System.Collections.Hashtable

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
title       NoteProperty object title=null
Foreach对象提供参数来选择对象可能有些奇怪。尝试:

哪个命令正在生成输出?:

'start';$hash|select title;'in';$hash|select detail;'done'
start

title
-----


in


done
因此,每个部分有2个空行,但没有详细的成员。是时候更具体一点了:

'start';$hash|select title|gm;'in';$hash|select detail|gm;'done'
start


   TypeName: Selected.System.Management.Automation.Internal.Host.InternalHost

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
title       NoteProperty object title=null
in
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
detail      NoteProperty object detail=null
done
因此,第二个select正在生成一个detail成员,但它在某个地方丢失了。这个怎么样:

&{$hash|select title;$hash|select detail}|gm


   TypeName: Selected.System.Management.Automation.Internal.Host.InternalHost

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
title       NoteProperty object title=null
再也没有细节了。经过大量毫无结果的测试,一些有用的研究发现了部分答案。完整描述在中,但结果是最终显示由第一个对象的属性通过管道控制。此对象有一个title属性,但没有detail属性,因此输出的格式是匹配的。这就解释了为什么显示的输出没有detail列,但为什么最后一个Get成员没有显示它?Get成员应该已经收到了两个带有标题的对象,后跟两个带有详细信息的对象。我知道这一点,因为manual Get会员会向他们展示:

&{$hash|select title;$hash|select detail}|foreach{[componentmodel.typedescriptor]::getproperties($_)[0].name}
title
title
detail
detail

# Can't use gettype() since doesn't know about added properties
所以,似乎不仅仅是Format表根据管道中的第一个对象决定其输出。显然,Get成员也表现出这种行为,尽管在本例中,它是每种类型的第一个对象。所有对象都是PSCustomObjects,但第一个对象只有一个添加了标题的属性,因此Get成员假定所有PSCustomObjects看起来都一样

最后一个问题。其他哪些cmdlet(如果有的话)会在管道中显示第一个对象,以静默方式定义后续行为功能?

注意:在7.0之前的PowerShell版本中,确实不支持将哈希表作为选择对象的输入;在早期版本中,首先将其强制转换为[pscustomobject];例如。: [pscustomobject]@{title=title1;detail=detail1},[pscustomobject]@{title=title2;detail=detail2}选择对象标题,细节

重述您已经注意到的问题:第一个对象的属性中可能存在隐式格式的表输出锁作为显示列,没有这些属性的后续对象将显示空白列值-有关详细信息,请参阅。 需要注意的是,这只是一个显示问题

Get成员问题略有不同:它与第一个输入对象的类型无关,而是与共享相同类型的输入对象有关:Get成员的设计目的是为输入对象中的每个不同类型生成输出

问题在于,Get成员认为两个[pscustomobject]实例(如选择对象输出)是同一类型的,从.NET的角度来看,它们在技术上是相同的,即使它们具有不同的属性,因此Get成员实际上只显示第一个[pscustomobject]的成员输入对象中的实例,这些对象可能是也可能不是第一个输入对象

因此,为了通过管道将多个[pscustomobject]实例传递到Get Member并查看每个实例的属性,请通过ForEach对象调用Get Member:

至于:

这个问题。其他哪些cmdlet(如果有的话)会在管道中显示第一个对象,并以静默方式定义后续行为功能

除了可能隐式应用的Format Table之外,本质上,所有期望所有输入对象为相同类型的cmdlet都具有相同的属性集,尤其是Export Csv/ConvertTo Csv。任何数量的第三方cmdlet也可能属于这一类-无法列出详尽的列表,尤其是因为将来可能会引入新的cmdlet

通常,您可以从cmdlet的用途推断它是否需要统一的输入,希望文档也能说明这一点:

导出Csv和转换为Csv,因为它们创建表格数据,需要统一输入;虽然可以使用-Force with-Append将同样具有不同属性的Csv对象导出到预先存在的Csv文件中,但只添加新添加的对象上与预先存在的列属性匹配的属性,因此最终仍然强制执行一致性

相反,ConvertToJSON,因为它可以是串行的 自定义任意对象图,不需要统一输入

注意:在7.0之前的PowerShell版本中,哈希表确实不支持作为选择对象的输入;在早期版本中,首先将其强制转换为[pscustomobject];例如。: [pscustomobject]@{title=title1;detail=detail1},[pscustomobject]@{title=title2;detail=detail2}选择对象标题,细节

重述您已经注意到的问题:第一个对象的属性中可能存在隐式格式的表输出锁作为显示列,没有这些属性的后续对象将显示空白列值-有关详细信息,请参阅。 需要注意的是,这只是一个显示问题

Get成员问题略有不同:它与第一个输入对象的类型无关,而是与共享相同类型的输入对象有关:Get成员的设计目的是为输入对象中的每个不同类型生成输出

问题在于,Get成员认为两个[pscustomobject]实例(如选择对象输出)是同一类型的,从.NET的角度来看,它们在技术上是相同的,即使它们具有不同的属性,因此Get成员实际上只显示第一个[pscustomobject]的成员输入对象中的实例,这些对象可能是也可能不是第一个输入对象

因此,为了通过管道将多个[pscustomobject]实例传递到Get Member并查看每个实例的属性,请通过ForEach对象调用Get Member:

至于:

这个问题。其他哪些cmdlet(如果有的话)会在管道中显示第一个对象,并以静默方式定义后续行为功能

除了可能隐式应用的Format Table之外,本质上,所有期望所有输入对象为相同类型的cmdlet都具有相同的属性集,尤其是Export Csv/ConvertTo Csv。任何数量的第三方cmdlet也可能属于这一类-无法列出详尽的列表,尤其是因为将来可能会引入新的cmdlet

通常,您可以从cmdlet的用途推断它是否需要统一的输入,希望文档也能说明这一点:

导出Csv和转换为Csv,因为它们创建表格数据,需要统一输入;虽然可以使用-Force with-Append将同样具有不同属性的Csv对象导出到预先存在的Csv文件中,但只添加新添加的对象上与预先存在的列属性匹配的属性,因此最终仍然强制执行一致性

相反,converttojson不需要统一的输入,因为它可以序列化任意对象图


答案是全部。可返回命令/表达式的第一个对象输出决定了格式表配置。从同一命令或同一表达式输出的后续对象将仅显示第一个对象输出的属性值。答案仍然可能是所有这些对象。当您返回4个或更少的属性时,shell格式化程序将以表格式输出。当返回5个或更多属性时,格式化程序使用列表格式。中显示的答案是使用。计算特性与“选择对象”一起使用。它是一个哈希表,但它有特定的键,这些键必须始终存在,您可以向其提供值。你们不能像标题和细节那个样自己编键。@adminionofthings:最后一次并没有火焰之战。这不是关于回答问题27373126,而是关于我在回答这个问题时发现的一些本质上无关的东西。我对mklement0进行了升级投票,因为实际的cmdlet已列出。我没有将其标记为已回答,因为列表可能不完整。我不确定是否有可能在添加新cmdlet时创建一个完整的列表,该列表不会过时。也许我的问题本质上是一个修辞性的问题,应该作为一个警告,某些cmdlet会这样做,因此请小心使用相同类型但成员不同的管道对象。@mklement0,说得好。我想贴出的答案涵盖了评论中的所有内容。所有这些评论都应该被清除。答案中没有提到的东西,它们不会增加太多。答案是所有的。可返回命令/表达式的第一个对象输出决定了格式表配置。从同一命令或同一表达式输出的后续对象将仅显示第一个对象输出的属性值。答案仍然可能是所有这些对象。当您返回4个或更少的属性时,shell格式化程序将以表格式输出。当返回5个或更多属性时,格式化程序使用列表格式。中显示的答案是使用。计算特性与“选择对象”一起使用。它是一个哈希表,但它有特定的键,这些键必须始终存在,您可以向其提供值。你不能自己编像Title和Detai这样的键
l、 @Adminof Things:最后一次没有火焰之战。这不是关于回答问题27373126,而是关于我在回答这个问题时发现的一些本质上无关的东西。我对mklement0进行了升级投票,因为实际的cmdlet已列出。我没有将其标记为已回答,因为列表可能不完整。我不确定是否有可能在添加新cmdlet时创建一个完整的列表,该列表不会过时。也许我的问题本质上是一个修辞性的问题,应该作为一个警告,某些cmdlet会这样做,因此请小心使用相同类型但成员不同的管道对象。@mklement0,说得好。我想贴出的答案涵盖了评论中的所有内容。所有这些评论都应该被清除。他们没有添加答案中未包含的内容。所有cmdlet。。。展示行为定义了哪些cmdlet与问题匹配,但很难知道cmdlet是否期望对象相同。在导出CSV手册中,当您提交多个对象以导出CSV时,“导出CSV”将根据您提交的第一个对象的属性组织文件。如果其余对象没有指定的属性之一,则该对象的属性值为null,由两个连续的逗号表示。如果其余对象具有其他属性,则这些属性值不会包含在文件中。然后,当强制参数和附加参数组合在一起时,包含不匹配属性的对象可以写入CSV文件。只有匹配的属性才会写入文件。不匹配的属性将被丢弃。这可能意味着它会查看所有对象以确定列出的属性,但实际上意味着不会检查任何对象,并且会选择与文件中现有属性匹配的属性。不管怎样,我想考虑一下这个问题中所说的一切,这可能是我们能得到的最接近的答案。。。展示行为定义了哪些cmdlet与问题匹配,但很难知道cmdlet是否期望对象相同。在导出CSV手册中,当您提交多个对象以导出CSV时,“导出CSV”将根据您提交的第一个对象的属性组织文件。如果其余对象没有指定的属性之一,则该对象的属性值为null,由两个连续的逗号表示。如果其余对象具有其他属性,则这些属性值不会包含在文件中。然后,当强制参数和附加参数组合在一起时,包含不匹配属性的对象可以写入CSV文件。只有匹配的属性才会写入文件。不匹配的属性将被丢弃。这可能意味着它会查看所有对象以确定列出的属性,但实际上意味着不会检查任何对象,并且会选择与文件中现有属性匹配的属性。不管怎么说,我想把这个问题中所说的全部都考虑进去,这可能是我们能得到的最接近答案了。