1

How can one change the property value of an object in Powershell which is not at the first layer?

Let's take this object

$MyObject = [PSCustomObject]@{
    Name              = 'test'
    SomeComplexObject = @{
        Prop1 = 'AAA'
        Prob2 = 'BBB'
    }
}

Should I need to change a surface property (first layer), I can simply do:

# The Idea is that I don't know what is the property name because I get it dynamically.
$ThePropertyNameIWantToChange = "Name"
$MyObject.$ThePropertyNameIWantToChange = "New Value"

How can I do the same if I need to change Prop1?

# This won't work obvisouly but this is to show the gist of it.
$SubProperty = "SomeComplexObject.Prop1"
$MyObject.$SubProperty = "New Value" 

The idea is that whenever I change a property value, there is stuff (same stuff always) that need to be performed before and after.

I would like to be able to do something like this.

ChangeObjectValue -InputObject $MyObject -Parameter {$_.SomeComplexObject} -Value 'New Value'

So far, I was able to do this by:

  • Converting the scriptblock to a string, then doing some replace / append, creating a new scriptblock, and invoking it.

I came up with the following (working)

$MyObject = [PSCustomObject]@{
    Name              = 'test'
    SomeComplexObject = @{
        Prop1 = 'AAA'
        Prob2 = 'BBB'
    }
}

function ChangeObjectValue {
    param (
        [Object]$ConfigObject,
        [ScriptBlock]$ScriptBlock,
        [Object]$Value
    )
   
    $NewSblockStr = $ScriptBlock.ToString().Replace('$_.', '$args[0].') + '= $args[1]'
    $NewSb = [scriptblock]::Create($NewSblockStr)

    Write-Host 'Do stuff I need before' -ForegroundColor Green
    
    $NewSb.Invoke($ConfigObject, $Value)
    Write-Host 'Done' -ForegroundColor Cyan
    
}

Write-Host $MyObject.SomeComplexObject.Prop1 -ForegroundColor Cyan
ChangePPValue -ConfigObject $MyObject -ScriptBlock { $_.SomeComplexObject.Prop1 } -Value 'JAREF'
$MyObject.SomeComplexObject.Prop1

That being said, it feels a bit finicky and I was wondering if there was a more robust way to achieve this without what seems to me to be the long way around.

Summary We all know we can assign a value to an object dynamically by using a string as the property name (which can come from a variable or be passed down from a function) but what about drilling down into an object to set a second or third level property? Is there a simple way to do this?

mklement0
  • 382,024
  • 64
  • 607
  • 775
Sage Pourpre
  • 9,932
  • 3
  • 27
  • 39
  • 1
    As soon as I changed my title from "sub property" to "nested property", I started getting some results. That being said, Your reference link definitely hit the spot. Thank you @mklement0 – Sage Pourpre Aug 09 '21 at 21:59

0 Answers0