Set Value of Nested Object Property by Name in PowerShell

£可爱£侵袭症+ 提交于 2019-11-28 08:57:38

问题


I want to set value of nested object property using PowerShell. When you are trying to set the value of the first level properties, it's quiet simple:

$propertyName = "someProperty"
$obj.$propertyName = "someValue"  # ← It works

For nested properties, it doesn't work:

$propertyName = "someProperty.someNestedProperty"
$obj.$propertyName = "someValue"  # ← It doesn't work and raises an error.

How to set value of nested object property by name of property using PowerShell?

MCVE

For those who want to reproduce the problem, here is a simple example:

$Obj= ConvertFrom-Json '{ "A": "x", "B": {"C": "y"} }'
# Or simply create the object:
# $Obj= @{ A = "x"; B = @{C = "y"} }
$Key = "B.C"
$Value = "Some Value"
$Obj.$Key = $Value

Run the command and you will receive an error:

"The property 'B.C' cannot be found on this object. Verify that the property exists and can be set."


回答1:


I created SetValue and GetValue methods to let you get and set a nested property of an object (including a json object) dynamically by name and they work perfect!

They are recursive methods which resolve the complex property and get the nested property step by step by splitting the nested property name.

GetValue and SetValue of Nested properties by Name

# Methods
function GetValue($object, $key)
{
    $p1,$p2 = $key.Split(".")
    if($p2) { return GetValue -object $object.$p1 -key $p2 }
    else { return $object.$p1 }
}
function SetValue($object, $key, $Value)
{
    $p1,$p2 = $key.Split(".")
    if($p2) { SetValue -object $object.$p1 -key $p2 -Value $Value }
    else { $object.$p1 = $Value }
}

Example

In the following example, I set B.C dynamically using SetValue and get its value by name using GetValue method:

# Example
$Obj = ConvertFrom-Json '{ "A": "x", "B": {"C": "y"} }'
# Or simply create the object:
# $Obj = @{ A = "x"; B = @{C = "y"} }
$Key = "B.C"
$Value = "Changed Dynamically!"
SetValue -object $Obj -key $Key -Value $Value
GetValue -object $Obj -key $Key



回答2:


May I propose an upgrade to Reza's solution. With this solution, you can have many level of nested properties.

function GetValue($object, [string[]]$keys)
{
    $propertyName = $keys[0]
    if($keys.count.Equals(1)){
        return $object.$propertyName
    }
    else { 
        return GetValue -object $object.$propertyName -key ($keys | Select-Object -Skip 1)
    }
}


function SetValue($object, [string[]]$keys, $value)
{
    $propertyName = $keys[0]
    if($keys.count.Equals(1)) {
        $object.$propertyName = $value
    }
    else { 
        SetValue -object $object.$propertyName -key ($keys | Select-Object -Skip 1) -value $value
    }
}

Usage

$Obj = ConvertFrom-Json '{ "A": "x", "B": {"C": {"D" : "y"}} }'
SetValue $Obj -key "B.C.D".Split(".") -value "z"
GetValue $Obj -key "B.C.D".Split(".")


来源:https://stackoverflow.com/questions/46451994/set-value-of-nested-object-property-by-name-in-powershell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!