![Powershell:變數中的變數;可變感受](https://rvso.com/image/1449093/Powershell%EF%BC%9A%E8%AE%8A%E6%95%B8%E4%B8%AD%E7%9A%84%E8%AE%8A%E6%95%B8%EF%BC%9B%E5%8F%AF%E8%AE%8A%E6%84%9F%E5%8F%97.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 已離線!”希望當我打電話給 $a 時我會得到“spr-it-minion 離線了!”我不知道該怎麼辦。
編輯二:分別是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 已離線!”沒有引號或任何東西。
第 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!
更多資訊:
評論後編輯:
對於從文件中提取行的範例,這有點棘手,因為它將行作為文字字串提取。
最簡單的方法(IMO)是使用代替方法;就像是:
$selHost = (get-content c:\scripts\hosts.txt)[0]
$a = ((get-content c:\scripts\config.txt)[1]).replace('$selhost', $selHost)
答案2
當您從檔案中讀取包含變數名的字串並將其讀取到變數中時,您將需要除雙引號之外的其他內容來導致字串擴展。有一個與這裡相關的工具。它稱為展開字串。看看這個範例程式碼:
$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
即使從 Autohotkey 呼叫 powershell 時,replace 方法也適用於變數替換中的變數:
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.