在 PowerShell 中将成员 AliasProperty 添加到子 属性

Add-Member AliasProperty to sub property in PowerShell

我有一个包含对象数组的对象 属性。

PS C:\> $Object

GroupType        : Object
StateRevCounter  : 3846
SchemaTag        : Computer
PropGroupList    : {DSM.MdsPropGroup, DSM.MdsPropGroup, DSM.MdsPropGroup, DSM.MdsPropGroup...}



PS C:\> $Object.PropGroupList

Tag                       PropertyList
---                       ------------
BasicInventory            {DSM.MdsTypedPropertyOfString, DSM.MdsTypedPropertyOfString, DSM.MdsTypedPr... 
ClientInfo                {DSM.MdsTypedPropertyOfNullableOfDateTime, DSM.MdsTypedPropertyOfNullableOf... 
Computer                  {DSM.MdsTypedPropertyOfString, DSM.MdsTypedPropertyOfNullableOfDateTime, DS...
CustomPatchManagement     {DSM.MdsTypedPropertyOfNullableOfBoolean, DSM.MdsTypedPropertyOfString}        
HardwareBasedRemoteMgmt   {DSM.MdsTypedPropertyOfString, DSM.MdsTypedPropertyOfNullableOfBoolean, DSM...



PS C:\> $Object.PropGroupList.PropertyList

TypedValue                                  Tag                                        Type
----------                                  ---                                        ----
7.4.1.4461                                  ClientVersion                            String
Client                                      ComputerRole                             Option
169                                         CPUArchitecture                     CatalogLink
2262                                        CPUType                             CatalogLink
DSMCLIENT00.Computers.ideri.dev             DirectoryContext                         String
DSMClient00.ideri.dev                       FullQualifiedName                        String
                                            InfrastructureRole                       Option
000C29E1B2FD                                InitialMACAddress                        String
227                                         InstalledOS                         CatalogLink
315                                         InstalledOSCulture                  CatalogLink
1458                                        InstalledOSFlavor                   CatalogLink
Windows 10 Enterprise 1511                  InstalledOSFriendlyName                  String
DSM.MdsVersion                              InstalledOSVersion                      Version
4193                                        InstalledRAM                              Int32
66057                                       LastBootServer                            Int32
.....

现在我想为 $Object 创建 AliasProperties,以直接在 $Object 的输出中显示 $Object.PropGroupList.PropertyList 的值,并在更改 AliasProperty 时更新正确位置的值。

期望的输出:

PS C:\> $Object

BasicInventory_ClientVersion   : 7.4.1.4461
BasicInventory_ComputerRole    : Client
BasicInventory_CPUArchitecture : 169
...
GroupType                      : Object
StateRevCounter                : 3846
SchemaTag                      : Computer
PropGroupList                  : {DSM.MdsPropGroup, DSM.MdsPropGroup, DSM.MdsPropGroup, DSM.MdsPropGroup...}

因此,如果我随后将 BasicInventory_ClientVersion 更新为 10.4.2.3333,子 属性(数组)中的相应值也会更新,反之亦然。

Add-Member -MemberType AliasProperty 甚至可以做到这一点吗?或者我可以只为对象根中的属性添加 AliasProperties 吗?

问候 塞博

您可以使用 Add-Member 添加成员类型 ScriptProperty。但是,构建对象是一个相当手动的过程。这是一个使用两个属性 ClientVersionComputerRole.

的示例
$object | Add-Member -MemberType ScriptProperty -Name "BasicInventory_ClientVersion" -Value {
    (($this.propgrouplist | Where Tag -eq 'BasicInventory').propertylist | where Tag -eq 'ClientVersion').TypedValue
}
$object | Add-Member -MemberType ScriptProperty -Name "BasicInventory_ComputerRole" -Value {
    (($this.propgrouplist | Where Tag -eq 'BasicInventory').propertylist | where Tag -eq 'ComputerRole').TypedValue
}

现在您可以更新源 属性 并将其反映在脚本中属性。

# Properties Before Change
$object | fl

GroupType                    : Object
PropGroupList                : @{Tag=BasicInventory; PropertyList=System.Object[]}
BasicInventory_ClientVersion : 7.4.1.4461
BasicInventory_ComputerRole  : Client

# Properties After Change
($Object.PropGroupList.PropertyList | Where Tag -eq 'ClientVersion').TypedValue = '20.3.4'
$object | fl

GroupType                    : Object
PropGroupList                : @{Tag=BasicInventory; PropertyList=System.Object[]}
BasicInventory_ClientVersion : 20.3.4
BasicInventory_ComputerRole  : Client

尝试使用变量使其动态化时要小心。脚本属性 值中使用的任何变量都将在根据调用范围中定义的变量调用对象时进行计算。例如,如果您将值指定为 {$tag},则需要在检索 $object 之前在某处定义 $tag

正如@AdminOfThings 所建议的,我最终使用了 ScriptProperty。谢谢。 我最终构建了一个函数来添加具有正确链接的属性到数组。

如您所见,我必须先将脚本块组成一个字符串,以便首先解析我的变量值。如果我直接将它写在脚本块中,变量 $prop.Tag 就不会被解析,因为它没有在脚本块中设置。

function ExpandObjectMdsPropGroupList ($ObjectList)
{
    foreach($obj in $ObjectList)
    {
        $PropGroupList = $obj.Propgrouplist
        foreach($propGrp in $PropGroupList)
        {
            foreach($prop in $propGrp.PropertyList)
            {
                # compose the getter
                $GetterScriptBlockAsString = "(`$this.propGroupList.PropertyList | Where-Object{`$_.Tag -eq `"$($prop.Tag)`"}).TypedValue"
                $GetterScriptBlock = [scriptblock]::Create($GetterScriptBlockAsString)

                # compose the setter
                [string]$typeOfPropTypedValue = $null
                try{
                    # get the type of TypedValue
                    $typeOfPropTypedValue = $prop.TypedValue.GetType()
                }catch{
                    # If TypedValue is null we have to get the type from get-member
                    $memberType = ($prop | Get-Member -Name TypedValue).Definition
                    $typeOfPropTypedValue = ($memberType.Remove($memberType.IndexOf(' ')))
                }
                if($typeOfPropTypedValue){
                    $typeOfPropTypedValue = "[$typeOfPropTypedValue]"
                }
                $SetterScriptBlockAsString = "param($typeOfPropTypedValue`$val);(`$this.propGroupList.PropertyList | Where-Object{`$_.Tag -eq `"$($prop.Tag)`"}).TypedValue = `$val"
                $SetterScriptBlock = [scriptblock]::Create($SetterScriptBlockAsString)

                # Add the member to the object
                $obj | Add-Member -MemberType ScriptProperty -Name "$($propGrp.Tag)_$($prop.Tag)" -Value $GetterScriptBlock -SecondValue $SetterScriptBlock
            }
        }
    }
    $ObjectList
}

现在我可以在任何带有 PropGroupList 的对象上使用该函数作为 属性 并且它添加 ScriptProperties 而不管列表中的 PropGroups 是什么。

多亏了 getter 和 setter,我可以更新任一侧的值。

问候 塞博