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

The following version of the Powershell script demonstrates the problem:

$hash = @{'a' = 1; 'b' = 2} Write-Host $hash['a'] # => 1 Write-Host $hash.a # => 1 # Two ways of printing using quoted strings. Write-Host "$($hash['a'])" # => 1 Write-Host "$($hash.a)" # => 1 # And the same two ways Expanding a single-quoted string. $ExecutionContext.InvokeCommand.ExpandString('$($hash[''a''])') # => 1 $ExecutionContext.InvokeCommand.ExpandString('$($hash.a)') # => Oh no! Exception calling "ExpandString" with "1" argument(s): "Object reference not set to an instance of an object." At line:1 char:1 + $ExecutionContext.InvokeCommand.ExpandString('$($hash.a)') + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : NullReferenceException 

Does anyone know why the $hash.key syntax works everywhere, but inside an explicit extension? Could this be fixed, or do I need to suck it and live with the syntax $hash[''key''] ?

+8
syntax powershell
source share
3 answers

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

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

Use for your example:

  '$($hash.a)' | render 
+4
source share

ExpandString api is not intended for use with PowerShell scripts, it has been added more for C # code. It is still a mistake that your example does not work (and I think it is fixed in V4), but that means there is a workaround - one that I recommend for general use.

Double quotes are effectively (but not literally) called ExpandString. So the following should be equivalent:

 $ExecutionContext.InvokeCommand.ExpandString('$($hash.a)') "$($hash.a)" 
+1
source share

I tried to save the text that asks the user in a text file. I wanted to have variables in a text file that were extended from my script.

My settings are stored in PSCustomObject with the name $ profile, so in my text I tried to do something like:

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

and then from my script, which I tried 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 a mistake

Throw an exception "ExpandString" with argument "1": "The object link is not installed in the object instance."

Finally, I realized that I only need to save the PSCustomObject values ​​that I want in the usual old variables, change the text file to use them instead of the object.property version, and everything worked beautifully:

 $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 !!!

+1
source share

All Articles