扩展文件内容中的变量

问题描述 投票:27回答:3

我有一个文件template.txt,其中包含以下内容:

Hello ${something}

我想创建一个PowerShell脚本来读取文件并扩展模板中的变量,即

$something = "World"
$template = Get-Content template.txt
# replace $something in template file with current value
# of variable in script -> get Hello World

我怎么能这样做?

powershell variables
3个回答
31
投票

另一个选择是使用ExpandString()例如:

$expanded = $ExecutionContext.InvokeCommand.ExpandString($template)

Invoke-Expression也可以使用。不过要小心。这两个选项都能够执行任意代码,例如:

# Contents of file template.txt
"EvilString";$(remove-item -whatif c:\ -r -force -confirm:$false -ea 0)

$template = gc template.txt
iex $template # could result in a bad day

如果你想拥有一个“安全”的字符串eval而不会意外地运行代码,那么你可以组合PowerShell作业和受限制的运行空间来做到这一点:

PS> $InitSB = {$ExecutionContext.SessionState.Applications.Clear(); $ExecutionContext.SessionState.Scripts.Clear(); Get-Command | %{$_.Visibility = 'Private'}}
PS> $SafeStringEvalSB = {param($str) $str}
PS> $job = Start-Job -Init $InitSB -ScriptBlock $SafeStringEvalSB -ArgumentList '$foo (Notepad.exe) bar'
PS> Wait-Job $job > $null
PS> Receive-Job $job
$foo (Notepad.exe) bar

现在,如果您尝试在使用cmdlet的字符串中使用表达式,则不会执行以下命令:

PS> $job = Start-Job -Init $InitSB -ScriptBlock $SafeStringEvalSB -ArgumentList '$foo $(Start-Process Notepad.exe) bar'
PS> Wait-Job $job > $null
PS> Receive-Job $job
$foo $(Start-Process Notepad.exe) bar

如果您希望在尝试命令时发现失败,请使用$ ExecutionContext.InvokeCommand.ExpandString扩展$ str参数。


5
投票

我找到了这个解决方案:

$something = "World"
$template = Get-Content template.txt
$expanded = Invoke-Expression "`"$template`""
$expanded

0
投票

因为我真的不喜欢一个要记住的想法 - 在这种情况下,记住PS将评估变量并运行模板中包含的任何命令 - 我找到了另一种方法来做到这一点。

构成您自己的令牌而不是模板文件中的变量 - 如果您不处理HTML,则可以使用例如<variable>,像这样:

Hello <something>

基本上使用任何唯一的令牌。

然后在PS脚本中,使用:

$something = "World"
$template = Get-Content template.txt -Raw
# replace <something> in template file with current value
# of variable in script -> get Hello World    
$template=$template.Replace("<something>",$something)

它比直接的InvokeCommand更麻烦,但它比设置有限的执行环境更简单,只是为了避免处理简单模板时的安全风险。 YMMV取决于要求:-)

© www.soinside.com 2019 - 2024. All rights reserved.