![Powershell:变量内的变量;Variableception](https://linux22.com/image/1449093/Powershell%EF%BC%9A%E5%8F%98%E9%87%8F%E5%86%85%E7%9A%84%E5%8F%98%E9%87%8F%EF%BC%9BVariableception.png)
因此,解释我的问题的最简单方法是向您展示我正在尝试做的事情的简化版本:
PS C:\> $a = 'hello'
PS C:\> $a
hello
PS C:\> $b = '$a world!'
PS C:\> $b
$a world!
现在我真正想要的是调用 $b 返回“hello world!”但我显然无法调用变量之内另一个像这样的变量。有人有什么建议或解决方法吗?我觉得我在这里忽略了一些明显的东西。
编辑:我正在尝试做的更准确的版本:
PS C:\> $selHost = (get-content c:\scripts\hosts.txt)[0]
PS C:\> $selhost
spr-it-minion
PS C:\> $a = (get-content c:\scripts\config.txt)[1]
PS C:\> $a
$selhost Is Offline!
PS C:\> $b = "$a"
PS C:\> $b
$selhost Is Offline!
因此,我从 hosts.txt 中取出第一行,并将其设置为 $selhost,也就是“spr-it-minion”。然后,我从 config.txt 中取出第二行,也就是字符串“$selhost is offline!”,希望当我调用 $a 时,我得到“spr-it-minion is offline!”,但我不知道该怎么做。
编辑II:分别是hosts.txt和config.txt的内容。
主机名.txt:
spr-it-minion
spr-saflok
spr-crosby
spr-vmhost01
spr-vmhost02
spr-vmhost03
配置.txt:
172.31.1.124
$selhost Is Offline!
$selhost Is Offline!
[email protected]
[email protected]
编辑三:粘贴箱如果你们有兴趣的话可以看一下我的实际脚本。
第 15 行:我将 $alertSubject 设置为字符串“$selhost is offline!”,不带引号或任何其他内容。
第 82 行:我使用 $alertSubject 作为电子邮件警报的主题行,希望它包含的变量的值能够表示为:“spr-it-minion 处于离线状态!”但是当我收到电子邮件或尝试在脚本中的任何位置写入主机 $alertSubject 时,它只会显示“$selhost 处于离线状态!”
答案1
在 PowerShell 中定义变量时,单引号 ( '
) 表示您需要字符串的文字版本。"
如果要允许变量扩展,请使用双引号 ( ):
PS C:\> $a = "hello"
PS C:\> $a
hello
PS C:\> $b = "$a world!"
PS C:\> $b
hello world!
更多信息:
评论后编辑:
对于从文件中提取行的示例,这有点棘手,因为它将该行作为文字字符串提取。
最简单的方法(在我看来)是使用代替方法;类似于:
$selHost = (get-content c:\scripts\hosts.txt)[0]
$a = ((get-content c:\scripts\config.txt)[1]).replace('$selhost', $selHost)
答案2
当您从文件中读取包含变量名的字符串并将其放入变量中时,除了双引号之外,您还需要其他东西来引发字符串扩展。这里有一个相关的工具。它叫做 ExpandString。请看以下示例代码:
$selhost = 'spr-it-minion'
$b = '$selhost is offline!'
$c = $ExecutionContext.InvokeCommand.ExpandString($b)
$c
这里发生的事情是,首先我给出了 $selhost 和 $b 文字值,类似于您从正在使用的文件中读出的值。当然,$b 是不对的,因为对 $selhost 的引用未解析,如接受的答案中所述。但 $c 获得了通过扩展 $selhost 生成的值,您可以在输出中使用它。
我将把它作为编码练习应用到您的案例中。
答案3
您在这里尝试执行的是动态 Powershell,即创建一个包含 Powershell 命令的字符串,然后让 Powershell 运行该命令。您可以使用 Invoke-Expression 执行此操作,例如:
$alertSubject = Invoke-Expression -Command "`"$((Get-Content '.\config.txt')[1])`""
但是,出于可维护性的考虑,你可能想把它分解成如下形式:
$config1 = (Get-Content '.\config.txt')[1]
$alertSubject = Invoke-Expression -Command "`"$config1`""
之所以使用反引号,是因为您实际想要运行的命令是:
"$selhost is offline!"
外部引号允许$config1
在将值传递到之前进行扩展Invoke-Expression
。该值需要包含双引号,以便$selhost
在调用命令时可以进行扩展。
或者,您可以在配置文件中放置双引号:
172.31.1.124
"$selhost Is Offline!"
"$selhost Is Offline!"
[email protected]
[email protected]
然后就可以了
$alertSubject = Invoke-Expression -Command $config1
在这个模式中,外面的双引号$config1
已经被删除,因为它们是多余的。
答案4
replace 方法对于变量内的变量替换非常有效,即使从 Autohotkey 调用 powershell 时也是如此:
uri = file$k.doc
psScript2 =
(
param($param1)
for($k=1; $k -le 6; $k++){
$uri = $param1.replace('$k',"$k")
echo $uri
}
)
Run PowerShell.exe -noexit -Command &{%psScript2%} '%uri%',, show
return
注意使用单引号来搜索要用外部变量内容替换的内部变量
结果是:
file1.doc
file2.doc
etc.