3

I'm new to StackOverflow but not all that new to PowerShell... I'm writing a function that uses the $host.UI.PromptForChoice() method to display a list of options to the user. It takes an array of objects, reads a property to use as a label, then displays the choices on the screen. When the property to use as the label is a simple string the function works fine. When the property needed for the label is two (or more) levels deep it doesn't work.

For example:

$object[i].base becomes $object[i].$var ($var = "base") <- this works!

$object[i].base.name becomes $object[i].$var ($var = "base.name") <- This returns nothing.

I have tried different ways of using the variable with no change. $object.{$var} $object.($var) $object."$var"

I'm almost certain this is an issue with how the '.' in the variable is being interpreted. It's all one string.

Here is the full function. I borrowed the basics of this code from another post on the Internet but now I can't find that post again. My apologies to the author for not properly crediting them!

function Show-UserChoices {
        param (
        [Parameter(Mandatory=$true)]
        $InputObject,
        [Parameter(Mandatory=$true)]
        [string]$LabelProperty,
        [string]$Caption = "Please make a selection",
        [string]$Message = "Type or copy/paste the text of your choice",
        [int]$DefaultChoice = -1
    )
    $choices = @()
    for($i=0;$i -lt $InputObject.Count;$i++){
        $choices += [System.Management.Automation.Host.ChoiceDescription]("$($InputObject[$i].$LabelProperty)")
    }
    $userChoice = $host.UI.PromptForChoice($Caption,$Message,$choices,$DefaultChoice)
    return $userChoice
}

Any suggestions as to what I'm missing here are appreciated!

UPDATE:

I found a solution to handling the properties. If I pass each property label as an index in an array I can assemble the expression in the function and run it. It might not be the prettiest code but it does what I need. Here is what I changed:

 .example
    Show-UserChoices -InputObject $object -LabelProperty foo,bar
    This will construct the expression $object.foo.bar

 [string[]]$LabelProperty, <-- now accepts an array of strings


$choices = @()
    for($i=0;$i -lt $InputObject.Count;$i++){
        $exp = '$InputObject[$i]'
        foreach ($j in $LabelProperty){
            $exp += '.' + $j
        }
        $choices += [System.Management.Automation.Host.ChoiceDescription]("$(Invoke-Expression $exp)")
    }
James
  • 31
  • 2
  • In short: the value of `$var` is invariably interpreted as a _single_ property name, not as a _path_ of property names; the same applies to literal strings: `$a.'foo.bar'` is _not_ the same as `$a.foo.bar` - the former looks for a property literally named `foo.bar`, the latter for a property `.foo` whose `.bar` property is to be accessed. – mklement0 Nov 13 '19 at 00:26
  • Thanks, I appreciate the comment. I actually thought of another solution shortly after posting this question and it worked... I added the fix to my original post for future reference. – James Nov 13 '19 at 05:39

0 Answers0