Why doesn't $hash.key syntax work inside the ExpandString method?

后端 未结 3 1214
隐瞒了意图╮
隐瞒了意图╮ 2021-01-12 04:05

The following Powershell script demonstrates the issue:

$hash = @{\'a\' = 1; \'b\' = 2}
Write-Host $hash[\'a\']        # => 1
Write-Host $hash.a                   


        
相关标签:
3条回答
  • 2021-01-12 04:27

    I was trying to store text that prompts the user in a text file. I wanted to be able to have variables in the text file that are expanded from my script.

    My settings are stored in a PSCustomObject called $profile and so in my text I was trying to do something like:

    Hello $($profile.First) $($profile.Last)!!!
    

    and then from my script I was trying to do:

    $profile=GetProfile #Function returns PSCustomObject 
    $temp=Get-Content -Path "myFile.txt"
    $myText=Join-String $temp
    $myText=$ExecutionContext.InvokeCommand.ExpandString($myText) 
    

    which of course left me with the error

    Exception calling "ExpandString" with "1" argument(s): "Object reference not set to an instance of an object."

    Finally I figured out I only needed to to store the PSCustomObject values I want in regular old variables, change the text file to use those instead of the object.property version and everything worked nicely:

    $profile=GetProfile #Function returns PSCustomObject 
    $First=$profile.First
    $Last=$profile.Last
    $temp=Get-Content -Path "myFile.txt"
    $myText=Join-String $temp
    $myText=$ExecutionContext.InvokeCommand.ExpandString($myText) 
    

    And in the text I changed to

    Hello $First $Last!!!

    0 讨论(0)
  • 2021-01-12 04:29

    I use this method, since this bug exists in v4 (not in v5)

    function render() {
        [CmdletBinding()]
        param ( [parameter(ValueFromPipeline = $true)] [string] $str)
    
        #buggy
        #$ExecutionContext.InvokeCommand.ExpandString($str)
    
        "@`"`n$str`n`"@" | iex
    }
    

    Usage for your example:

      '$($hash.a)' | render
    
    0 讨论(0)
  • 2021-01-12 04:43

    The ExpandString api is not exactly meant for use from PowerShell scripts, it was added more for C# code. It's still a bug that your example doesn't work (and I think it's been fixed in V4), but it does mean there is a workaround - one that I recommend for general use.

    Double quoted strings effectively (but not literally) call ExpandString. So the following should be equivalent:

    $ExecutionContext.InvokeCommand.ExpandString('$($hash.a)')
    "$($hash.a)"
    
    0 讨论(0)
提交回复
热议问题