1

How can I configure PowerShell to select an object property (top level or nested) based on the contents of a variable?

I have PowerShell script that reads the contents of a file (JSON), converts it to an object and then selects one of the properties. However, the content is not consistent and the location of the desired property within the JSON may change.

I'd like to be able to set a -PropertyPath parameter on the script that will enable users to pass in the path to the desired property within the object.

Take the following example, which allows for the selection of an object property based on the value of -PropertyPath. It works because the property is not nested.

$PropertyPath= "myProperty"
$definition = (Get-Content -Path $definitionFilePath -Raw | ConvertFrom-Json).$PropertyPath

Now take the following failed example where the property to get is nested (and does exist), which fails with no error, but $definition is empty - presumably because a property called "random.myProperty" does not exist.

$PropertyPath= "random.myProperty"
$definition = (Get-Content -Path $definitionFilePath -Raw | ConvertFrom-Json).$PropertyPath

Any help would be appreciated.

David Gard
  • 11,225
  • 36
  • 115
  • 227

1 Answers1

1

The dot '.' property represents the dereference operator. Powershell seems to treat the entire string as the property name.

One way to get the desired functionality: use a helper function to manually parse and traverse the path (via):

function OutputNested ($obj, $Value )
{
    $value_array = $Value.split(".");    
    $output = $obj;
    foreach ( $nested in $value_array ) 
    {
        $output = $output.$nested;
    }
    return $output;
}

$PropertyPath= "stuff.onetype"
$definitionFilePath = "C:\Users\UserName\Source\powershell\so12943819\so12943819.json"

# Works directly
#$definition = $(Get-Content -Path $definitionFilePath -Raw | ConvertFrom-Json).stuff.onetype

# Works via helper function
$definition = OutputNested (Get-Content -Path $definitionFilePath -Raw | ConvertFrom-Json) $PropertyPath

$definition

JSON input file:

{ 
    "stuff": {
        "onetype": [
            {"id":1,"name":"John Doe"},
            {"id":2,"name":"Don Joeh"}
        ],
        "othertype": {"id":2,"company":"ACME"}
    }, 
    "otherstuff": {
        "thing": [[1,42],[2,2]]
     }
}

Output:

id name    
-- ----    
 1 John Doe
 2 Don Joeh
iokevins
  • 1,427
  • 2
  • 19
  • 29
  • If you need both get/set functionality, this answer has a recursive take: https://stackoverflow.com/a/46796446/182742 – iokevins Jun 28 '19 at 16:01