我有一个PSCustomObject,它是通过转换JSON数组而创建的... | convertfrom-json
。该对象还有许多其他对象用于属性值(基本上是许多PSCustomObjects的集合)。通过了解对象,我知道它至少包含三种不同类型的对象(类型表示具有不同属性的PSCustomObject)。
当运行Get-Member I时,只有两个对象类型及其成员,而第三个则没有列出。我知道还有第三种对象类型,因为我可以选择仅在该对象中可用的属性。
我曾经有过一个类似的问题,即get-member
只有在$object | select...
方法中首先被调用时,某些成员才会出现在结果中,否则它们不会出现。那时候我也没弄清楚。当前的问题不一样,但可能是相关的,因为我尝试了方法,$object | select...
但没有帮助。
我确实在尝试发布可重现的代码时注意到,我只得到一种对象类型的回报,而不是从那里得到的两种invoke-restmethod
,这使我的问题变得更大,这是怎么回事,为什么有些对象类型被返回而有些却没有。
获取成员结果示例
$res.address_objects.ipv4 | gm
TypeName: Selected.System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
host NoteProperty System.Management.Automation.PSCustomObject <snip>
name NoteProperty string name=<snip>
uuid NoteProperty string uuid=<snip>
zone NoteProperty string zone=<snip>
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
name NoteProperty string name=<snip>
network NoteProperty System.Management.Automation.PSCustomObject <snip>
uuid NoteProperty string uuid=<snip>
如您所见,这里有两种对象类型,它们都有一些不同的属性名称。
取自@Jawad的答案。
请注意:此示例不是我的代码的精确副本,因为我的psobject是a的结果,该结果invoke-restmethod
自动将json转换为对象。
$json = @"
{
"address_objects": {
"ipv4": [{
"host": "hostValue",
"name": "hostName",
"uuid": "value",
"zone": "thisZone"
},
{
"name": "NewName",
"network": "newNetwork",
"uuid": "thisUuid"
},
{
"name": "NewName",
"range": "newrange",
"uuid": "thisUuid"
}]
}
}
"@ | ConvertFrom-Json
Get-member
:$json.address_objects.ipv4 | gm
TypeName: Selected.System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
host NoteProperty System.Management.Automation.PSCustomObject <snip>
name NoteProperty string name=<snip>
uuid NoteProperty string uuid=<snip>
zone NoteProperty string zone=<snip>
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
name NoteProperty string name=<snip>
network NoteProperty System.Management.Automation.PSCustomObject <snip>
uuid NoteProperty string uuid=<snip>
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
name NoteProperty string name=<snip>
range NoteProperty System.Management.Automation.PSCustomObject <snip>
uuid NoteProperty string uuid=<snip>
基本上有三个不同的psCustomObjects,因此get-member
应将它们全部列出。
由于评论者的编辑,它们是正确的,因此我添加了可复制的示例并阐明了我的要求。我尚未深入剖析给出的答案。
Get-Member
通过设计列出了其输入对象中的不同类型。[1]
但是,实例的问题[pscustomobject]
在于,即使它们具有不同的属性,Get-Member
也无法将它们识别为不同的类型。
# Send 3 [pscustomobject] instances with distinct properties to Get-Member
[pscustomobject] @{ one = 1; two = 2; three = 3 },
[pscustomobject] @{ four = 4; five = 5 },
[pscustomobject] @{ six = 6; seven = 7 } | Get-Member
以下内容意外地仅产生一个输出对象,仅显示第一个 [pscustomobject]
实例的成员:
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
one NoteProperty int one=1
three NoteProperty int three=3
two NoteProperty int two=2
Get-Member
区分类型只能通过他们的(全)类型名称所反映的隐藏实例属性,.pstypenames
第一个元素(.pstypenames[0]
),不考虑给定的情况下的特定属性。默认情况下
,[pscustomobject]
实例的类型名称是System.Management.Automation.PSCustomObject
。
请注意,.pstypenames[0]
默认情况下,它包含与类型名称相同的类型名称.GetType().FullName
,但是可以插入“虚构的”名称[2],[pscustomobject]
例如,在Select-Object
cmdlet创建的实例中会发生这种情况(请参阅底部)。
解决方法:
注意:以下操作适用于显示输出(应该很好,因为该Get-Member
输出通常用于视觉检查)。
[pscustomobject] @{ one = 1; two = 2; three = 3 },
[pscustomobject] @{ four = 4; five = 5 },
[pscustomobject] @{ six = 6; seven = 7 } |
Group-Object { "$($_.psobject.Properties.Name)" } | ForEach-Object {
Get-Member -InputObject $_.Group[0] | Out-Host
}
Group-Object
用于通过使用计算出的属性(通过{ ... }
为每个输入对象评估的脚本块())按属性名称列表将输入对象分组。
$_.psobject.Properties.Name
产生一个包含所有属性名称的数组,并将其"$(...)"
转换为以空格分隔的列表。然后ForEach-Object
,通过将每个组的第一个实例($_.Group[0]
)直接传递给来处理每个组Get-Member
Get-Member
调用产生单独的显示输出Out-Host
;没有它,显示输出将错误地建议一个包含所有不同类型的属性的单一输入类型。如果您只对所有输入对象中的不同属性名称列表感兴趣:
# This yields the sorted array of all unique property names, across all
# input objects:
# 'five', 'four', 'one', 'seven', 'six', 'three', 'two'
[pscustomobject] @{ one = 1; two = 2; three = 3 },
[pscustomobject] @{ four = 4; five = 5 },
[pscustomobject] @{ six = 6; seven = 7 } |
ForEach-Object { $_.psobject.Properties.Name } | Sort-Object -Unique
至于你的症状:
请注意,您的第一个Get-Member
输出块提到了一个不同的类型名称:Selected.System.Management.Automation.PSCustomObject
该Selected.
前缀表示该对象是通过Select-Object
cmdlet创建的。尽管从技术上讲,这样的对象也是一个[pscustomobject]
实例,但修改后的类型名称会导致Get-Member
将其视为其他类型。
这是一个简化的示例:
$obj = [pscustomobject] @{ one = 1; two = 2 }
$obj, ($obj | Select-Object -Property *) | Get-Member
这产生了以下内容;请注意,属性如何相同,只是类型名称不同:
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
one NoteProperty int one=1
two NoteProperty int two=2
TypeName: Selected.System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
one NoteProperty int one=1
two NoteProperty int two=2
但是请注意,就像所有[pscustomobject]
具有类型名称的实例System.Management.Automation.PSCustomObject
一样,即使它们具有不同的属性也是如此,所有具有的实例也是如此Selected.System.Management.Automation.PSCustomObject
。也就是说,由于共享相同的固定类型名称,Select-Object
创建的[pscustomobject]
实例也都被视为相同。
[1]例如,1, 2, 3 | Get-Member
仅列出一种类型System.Int32
,因为所有输入对象都具有该类型。相比之下,1, 'foo', 2 | Get-Member
列出2种,System.Int32
和System.String
(而不是System.Int32
再次)。
[2]分配任意类型名称的功能是PowerShell的ETS(扩展类型系统)的一部分-请参见about_types.ps1xml
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句