gpt4 book ai didi

Powershell 自定义对象隐藏属性类型

转载 作者:行者123 更新时间:2023-12-02 23:33:59 25 4
gpt4 key购买 nike

背景:
我有一个 PSCustomObject,它是通过 ... | convertfrom-json 转换一个 JSON 数组而创建的。 .该对象有许多其他的属性值对象(基本上它是许多 PSCustomObjects 的集合)。
通过了解对象,我知道它至少包含三种不同类型的对象(类型表示具有不同属性的 PSCustomObject)。
问题:
运行 Get-Member 时,我只有两种对象类型及其成员,根本没有列出第三种。我知道还有第三种对象类型,因为我可以选择仅在该对象中可用的属性。
笔记:
我也遇到过类似的问题,有些成员只会出现在get-member的结果中。仅当在 $object | select... 中首先被调用时方法,否则他们只是没有出现。我当时也没搞清楚。当前问题是不是 相同但可能相关,因为我尝试了 $object | select... 的方法它没有帮助。
笔记2:
我确实注意到,在尝试发布可重现的代码时,我只得到一种对象类型作为返回,而不是从 invoke-restmethod 中得到的两种类型。 ,这让我的问题变得更大,这里发生了什么,为什么返回了一些对象类型,而有些则没有。
例子:
get-member 结果示例

$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>
正如您所看到的,这里有两种对象类型,它们都有一些不同的属性名称。
样本:
我转换为对象的示例 Json。
取自@Jawad 的回答。
请注意:此示例不是我代码的精确副本,因为我的 psobject 是 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应该列出所有三个。
编辑#1:
感谢评论者的编辑,他们是对的,所以我添加了一个可重复的样本并澄清了我的问题。我还没有深入剖析给出的答案。

最佳答案

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仅通过(完整)类型名称区分类型 , 反射(reflect)在隐藏实例属性 .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列出两种类型, System.Int32System.String (但不是 System.Int32 再次)。

    [2] 分配任意类型名称的能力是 PowerShell 的 ETS(扩展类型系统)的一部分 - 参见 about_types.ps1xml

    关于Powershell 自定义对象隐藏属性类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60047788/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com