Powershell: 変数内の変数; Variableception

Powershell: 変数内の変数; Variableception

私の問題を説明する最も簡単な方法は、私がやろうとしていることの簡略化されたバージョンを示すことです。

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 から 2 行目を抜き出して、「$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

config.txt:

172.31.1.124
$selhost Is Offline!
$selhost Is Offline!
[email protected]
[email protected]

編集III:ペーストビンもし興味があれば、私の実際のスクリプトをご覧ください。

15 行目: $alertSubject を引用符などなしで文字列「$selhost is offline!」に設定しました。

行 82: $alertSubject を電子メール アラートの件名として使用し、そこに含まれる変数の値が「spr-it-minion はオフラインです!」のように表されることを期待しています。しかし、電子メールを受信したり、スクリプト内のどこかで write-host $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 に、使用しているファイルから読み取るものと同様のリテラル値を与えています。もちろん、承認された回答で概説されているように、$selhost への参照が解決されていないため、$b は正しくありません。ただし、$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.

関連情報