8

以下 Powershell 脚本演示了该问题:

$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

任何人都知道为什么$hash.key语法在任何地方都有效,但在显式扩展中?这可以解决吗,还是我必须接受它并使用$hash[''key'']语法?

4

3 回答 3

4

我使用这种方法,因为这个错误存在于 v4 中(不在 v5 中)

function render() {
    [CmdletBinding()]
    param ( [parameter(ValueFromPipeline = $true)] [string] $str)

    #buggy
    #$ExecutionContext.InvokeCommand.ExpandString($str)

    "@`"`n$str`n`"@" | iex
}

您的示例的用法:

  '$($hash.a)' | render
于 2015-03-12T09:04:55.820 回答
1

我试图将提示用户的文本存储在文本文件中。我希望能够在从我的脚本扩展的文本文件中包含变量。

我的设置存储在一个名为 $profile 的 PSCustomObject 中,因此在我的文本中,我试图执行以下操作:

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

然后从我的脚本中我试图做:

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

这当然给我留下了错误

使用“1”参数调用“ExpandString”的异常:“对象引用未设置为对象的实例。”

最后我发现我只需要将我想要的 PSCustomObject 值存储在常规的旧变量中,更改文本文件以使用这些值而不是 object.property 版本,并且一切正常:

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

在文本中我改为

你好 $First $Last!!!

于 2014-12-05T15:45:35.883 回答
1

ExpandString api 并不完全适用于 PowerShell 脚本,它是为 C# 代码添加的更多内容。您的示例不起作用仍然是一个错误(我认为它已在 V4 中修复),但这确实意味着有一种解决方法 - 我建议将其用于一般用途。

双引号字符串有效(但不是字面意思)调用 ExpandString。所以以下应该是等价的:

$ExecutionContext.InvokeCommand.ExpandString('$($hash.a)')
"$($hash.a)"
于 2013-09-23T03:09:41.723 回答