Powershell: Eine Variable innerhalb einer Variablen; Variableception

Powershell: Eine Variable innerhalb einer Variablen; Variableception

Der einfachste Weg, mein Problem zu erklären, besteht darin, Ihnen die folgende vereinfachte Version meines Vorhabens zu zeigen:

PS C:\> $a = 'hello'
PS C:\> $a
hello
PS C:\> $b = '$a world!'
PS C:\> $b
$a world!

Was ich jetzt wirklich möchte, ist, dass der Aufruf von $b „Hallo Welt!“ zurückgibt, aber ich kann anscheinend keine Variable aufrufeninnerhalbeine andere Variable wie diese. Hat jemand Vorschläge oder Workarounds? Ich habe das Gefühl, dass ich hier einfach etwas Offensichtliches übersehe.

Bearbeiten: eine genauere Version dessen, was ich versuche zu tun:

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!

Also ziehe ich die erste Zeile aus hosts.txt und setze sie auf $selhost, was einfach „spr-it-minion“ ist. Dann ziehe ich die zweite Zeile aus config.txt, die einfach die Zeichenfolge „$selhost ist offline!“ ist, in der Hoffnung, dass ich beim Aufruf von $a „spr-it-minion ist offline!“ erhalte und bin mir nicht sicher, was ich tun soll.

Bearbeitung II: der Inhalt von hosts.txt bzw. config.txt.

hosts.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]

Bearbeitung III: DiePastebinzu meinem eigentlichen Skript, falls jemand von Ihnen interessiert ist.

Zeile 15: Ich habe $alertSubject auf die Zeichenfolge „$selhost ist offline!“ gesetzt, ohne Anführungszeichen oder ähnliches.

Zeile 82: Ich verwende $alertSubject als Betreffzeile einer E-Mail-Benachrichtigung und hoffe, dass der Wert der darin enthaltenen Variable etwa so dargestellt wird: „spr-it-minion ist offline!“ Aber wenn ich die E-Mail bekomme oder versuche, $alertSubject irgendwo im Skript einzugeben, steht dort nur „$selhost ist offline!“

Antwort1

Beim Definieren von Variablen in PowerShell 'bedeuten einfache Anführungszeichen ( ), dass Sie die wörtliche Version der Zeichenfolge wünschen. Verwenden Sie doppelte Anführungszeichen ( "), wenn Sie die Variablenerweiterung zulassen möchten:

PS C:\> $a = "hello"
PS C:\> $a
hello
PS C:\> $b = "$a world!"
PS C:\> $b
hello world!

Mehr Info:

Nach Kommentaren bearbeiten:

In Ihrem Beispiel, in dem Sie die Zeile aus einer Datei ziehen, ist es etwas schwieriger, da die Zeile als Literalzeichenfolge gezogen wird.

Der einfachste Weg (meiner Meinung nach) wäre die Verwendung derErsetzenMethode; so etwas wie:

$selHost = (get-content c:\scripts\hosts.txt)[0]
$a = ((get-content c:\scripts\config.txt)[1]).replace('$selhost', $selHost)

Antwort2

Wenn Sie einen String, der einen Variablennamen enthält, aus einer Datei in eine Variable einlesen, benötigen Sie etwas anderes als doppelte Anführungszeichen, um die String-Erweiterung zu bewirken. Es gibt ein Tool, das hier relevant ist. Es heißt ExpandString. Sehen Sie sich diesen Beispielcode an:

$selhost = 'spr-it-minion'

$b = '$selhost is offline!'
$c = $ExecutionContext.InvokeCommand.ExpandString($b)

$c

Was hier passiert, ist, dass ich $selhost und $b zunächst Literalwerte gegeben habe, ähnlich denen, die Sie aus den von Ihnen verwendeten Dateien lesen würden. Natürlich ist $b nicht richtig, da der Verweis auf $selhost nicht aufgelöst wird, wie in der akzeptierten Antwort beschrieben. Aber $c erhält den durch die Erweiterung von $selhost erzeugten Wert, den Sie in Ihrer Ausgabe verwenden können.

Die Anwendung auf Ihren Fall überlasse ich der Programmierübung.

Antwort3

Was Sie hier versuchen, ist dynamisches Powershell, d. h., Sie erstellen eine Zeichenfolge, die einen Powershell-Befehl enthält, und lassen Powershell dann diesen Befehl ausführen. Sie können dies beispielsweise mit Invoke-Expression tun:

$alertSubject = Invoke-Expression -Command "`"$((Get-Content '.\config.txt')[1])`""

Aus Gründen der Wartbarkeit möchten Sie es jedoch möglicherweise in etwa wie folgt aufteilen:

$config1 = (Get-Content '.\config.txt')[1]
$alertSubject = Invoke-Expression -Command "`"$config1`""

Die Backticks sind da, weil der Befehl, den Sie eigentlich ausführen möchten, folgender ist:

"$selhost is offline!"

Die äußeren Anführungszeichen ermöglichen $config1die Erweiterung, bevor der Wert übergeben wird Invoke-Expression. Dieser Wert muss doppelte Anführungszeichen enthalten, damit er $selhosterweitert werden kann, wenn der Befehl aufgerufen wird.

Alternativ können Sie die Anführungszeichen auch in die Konfigurationsdatei einfügen:

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

und dann einfach

$alertSubject = Invoke-Expression -Command $config1

In diesem Muster wurden die äußeren Anführungszeichen $config1gelöscht, da sie überflüssig sind.

Antwort4

Die Ersetzungsmethode funktioniert gut für die Ersetzung von Variablen innerhalb von Variablen, auch beim Aufruf von Powershell über Autohotkey:

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

Beachten Sie die Verwendung von einfachen Anführungszeichen bei der Suche nach inneren Variablen, die durch den Inhalt äußerer Variablen ersetzt werden sollen.

Ergebnis ist:

file1.doc
file2.doc
etc.

verwandte Informationen