如何解析PowerShell脚本块中的变量

6

我有以下内容:

$a = "world"
$b = { write-host "hello $a" }

我该如何获取脚本块的已解析文本,这应该是包括 Write-Host 在内的完整字符串:
write-host "hello world"

更新:额外澄清

如果您只打印$b,您会得到变量而不是已解析的值。

write-host "hello $a"

如果你执行带有 & $b 的脚本块,你将得到打印出来的值,而不是脚本块的内容:
hello world

这个问题正在寻找一个包含已评估变量的脚本块内容的字符串,即:
write-host "hello world"

你有一个 _脚本块_,需要调用/运行该脚本块。[微笑] 仅调用保存脚本块的变量 $Var 会返回字面内容,而不是运行它。您可以通过以下方式运行它... Invoke-Command -ScriptBlock $b 输出为 hello world - Lee_Dailey
1
我不相信这是一个重复的问题,因为我没有执行脚本块 - 我想要一个带有计算变量的语法字符串。 - alastairtree
@Lee_Dailey - 从答案中可以看出,您可以使用$ExecutionContext.InvokeCommand.ExpandString($b)来实现。 - alastairtree
@alastairtree - 哈!我学到了新东西! [咧嘴笑] 我很快会删除这条评论 - 并立即删除我的错误评论,以避免混淆他人。 - Lee_Dailey
1个回答

11

如果您的整个脚本块内容不是字符串(但您希望它是字符串),并且您需要在脚本块内进行变量替换,您可以使用以下方法:

$ExecutionContext.InvokeCommand.ExpandString($b)

在当前执行上下文中调用.InvokeCommand.ExpandString($b)将使用当前作用域中的变量进行替换。

以下是一种创建脚本块并检索其内容的方法:

$a = "world"
$b = [ScriptBlock]::create("write-host hello $a")
$b

write-host hello world

您同样可以使用脚本块符号 {} 来达到相同的效果,但是需要使用 & 调用运算符:

$a = "world"
$b = {"write-host hello $a"}
& $b

write-host hello world

使用上述方法的一个特点是,如果您随时更改了$a的值并再次调用脚本块,则输出将会更新如下:
$a = "world"
$b = {"write-host hello $a"}
& $b
write-host hello world
$a = "hi"
& $b
write-host hello hi

GetNewClosure() 方法可用于创建脚本块的克隆,以获取该脚本块当前评估的理论快照。它将不受后续代码中 $a 值更改的影响:

$b = {"write-host hello $a"}.GetNewClosure()
& $b
write-host hello world
$a = "new world"
& $b
write-host hello world

{} 表示脚本块对象,您可能已经知道了。这可以传递到 Invoke-Command,从而打开其他选项。在脚本块内还可以创建参数,稍后可以传入。有关更多信息,请参见about_Script_Blocks


抱歉,是指 $a 而不是 $b,尽管我认为问题仍然存在。已更新问题。 - alastairtree
这不正确,也没有抓住问题的关键 - 打印 $b 只会打印 write-host "hello $a",而问题要求打印 write-host "hello world" - alastairtree
你是否阅读了这篇文章并尝试了不同的场景?在脚本块中,必须将所有内容用引号括起来才能打印出整个文本,这在我的示例中已经有了。 - AdminOfThings
4
找到了一个简短的答案。只需运行这个$executioncontext.invokecommand.expandstring($b) - AdminOfThings
@AdamOfThings - 你懂的,谢谢,它是 $ExecutionContext.InvokeCommand.ExpandString($b),适用于任何给定的脚本块。 - alastairtree
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接