2

I have a string that looks something like this:

$string = "property1.property2.property3"

And I have an object, we'll call $object. If I try to do $object.$string it doesn't interpret it that I want property3 of property2 of property1 of $object, it thinks I want $object."property1.property2.property3".

Obviously, using split('.') is where I need to be looking, but I don't know how to do it if I have an unknown amount of properties. I can't statically do:

$split = $string.split('.')
$object.$split[0].$split[1].$split[2]

That doesn't work because I don't know how many properties are going to be in the string. So how do I stitch it together off of n amounts of properties in the string?

user3066571
  • 1,381
  • 4
  • 14
  • 37
  • Take a look at this post: [Set Value of Nested Object Property by Name in PowerShell](https://stackoverflow.com/q/46451994/3110834) – Reza Aghaei Oct 22 '17 at 05:14

2 Answers2

3

A simple cheater way to do this would be to use Invoke-Expression. It will build the string and execute it in the same way as if you typed it yourself.

$string = "property1.property2.property3"
Invoke-Expression "`$object.$string"

You need to escape the first $ since we don't want that expanded at the same time as $string. Typical warning: Beware of malicious code execution when using Invoke-Expression since it can do anything you want it to.

In order to avoid this you would have to build a recursive function that would take the current position in the object and pass it the next breadcrumb.

Function Get-NestedObject{
    param(
        # The object we are going to return a propery from
        $object,
        # The property we are going to return            
        $property,
        # The root object we are starting from.
        $rootObject
    )
    # If the object passed is null then it means we are on the first pass so 
    # return the $property of the $rootObject. 
    if($object){
        return $object.$property
    } else {
        return $rootObject.$property
    }
}

# The property breadcrumbs
$string = '"Directory Mappings"."SSRS Reports"'
# sp
$delimetedString = $String.Split(".")

$nestedObject = $null

Foreach($breadCrumb in $delimetedString){
    $nestedObject = Get-NestedObject $nestedObject $breadcrumb $settings
}

$nestedObject

There are some obvious places where that function could be hardened and documented better but that should give you an idea of what you could do.

Matt
  • 45,022
  • 8
  • 78
  • 119
0

What's the use case here? You can split the string as you've described. This will create an array, and you can count the number of elements in the array so that n is known.

$string = "property1.property2.property3"
$split = $string.split('.')
foreach($i in 0..($split.Count -1)){
    Write-Host "Element $i is equal to $($split[$i])"
    $myString += $split[$i]
}
G42
  • 9,791
  • 2
  • 19
  • 34
  • If I split the string, how do I loop over it such that I stitch it together on the property I need, if it's of `n` length? – user3066571 Jul 18 '17 at 19:19
  • @user3066571 Still not clear on the user case - what you mean by _"stitch it together on the property"_? I've extended the answer to show how you can build a string with all of the parts concatenated into 1 variable `$myString`.... essentially you can do what you want to the parts within the `foreach` loop. – G42 Jul 18 '17 at 19:29
  • @gms0ulman OP has yet to comment but I think I know what he wanted. Have a look at my answer to see if you think that might be what they are going for. – Matt Jul 18 '17 at 19:37
  • @Matt Aaa I see! I think you've hit the nail on the head with _Invoke-Expression "`$object.$string"_; I find the other code confusing and think OP will as well. Good point on security, if OP does not have end-to-end control of the process. – G42 Jul 18 '17 at 19:55
  • Yeah. I don't like the other method but it is safer in a sense – Matt Jul 18 '17 at 23:42