Search code examples
arrayspowershellpropertiesadditionmember

Add-Member AliasProperty to sub property in PowerShell


I have an object that has an array of objects as a property.

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
.....

Now I want to create AliasProperties for $Object to show the values of $Object.PropGroupList.PropertyList directly within the output of $Object and update the values at the right spot, if the AliasProperty is changed.

Desired output:

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...}

So if I then update BasicInventory_ClientVersion to for example 10.4.2.3333, the corresponding value in the sub property (array) is updated as well and vice versa.

Is this even possible with Add-Member -MemberType AliasProperty? Or can I only add AliasProperties for properties in the root of the object?

Regards Sebbo


Solution

  • You can use a Add-Member to add member type ScriptProperty. However, building the object is a fairly manual process. Here is an example using two properties, ClientVersion and ComputerRole.

    $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
    }
    

    Now you can update the source property and have it be reflected in the scriptproperty.

    # 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
    

    Use caution when trying to make this dynamic with variables. Any variable used in the scriptproperty value will be computed when the object is called based on the variables defined in the calling scope. For example, if you assigned value to be {$tag}, $tag would need to be defined somewhere before $object is retrieved.