Tags: PowerShell
Praktisch jede prozedurale Programmiersprache benötigt Konstrukte, die Anweisungen abhängig vom Zutreffen bestimmter Bedingungen auszuführen. Dafür haben sich if/else und switch eingebürgert, die auch PowerShell unterstützt. Im Vergleich zu anderen Script-Sprachen zeigt sie jedoch einige syntaktische Eigenheiten.
Wenn man häufig zwischen verschiedenen Script-Sprachen wie PHP, Javascript oder PowerShell wechselt, dann verheddert man sich leicht in den syntaktischen Unterschieden.
If-Konstrukt in PowerShell
Für eine if-Anweisung in PowerShell gelten folgende Regeln:
- PowerShell unterscheidet nicht zwischen Groß- und Kleinschreibung, so dass man If, if oder IF verwenden kann. Das Gleiche gilt natürlich auch für else.
- Der Vergleichsausdruck muss in runden Klammern stehen,
- die davon abhängige/n Anweisung/en in geschweiften Klammern
Im einfachsten Fall enthält der Vergleichsausdruck nur eine Variable, die darauf geprüft wird, ob sie definiert wurde bzw. einen Wert ungleich Null hat. Trifft das zu, dann ist das Ergebnis des Ausdrucks TRUE, sonst FALSE:
if($test){
echo "Wert von Test: " $test
}
Vergleiche mit Operatoren
In der Regel wird man jedoch Bedingungen formulieren, für die man Vergleichsoperatoren benötigt. Will man etwa prüfen, ob eine Variable größer oder gleich einem bestimmten Wert ist, dann würde das so aussehen:
if($test -ge 5){ echo "test ist größer oder gleich 5" }
Regeln für bedingte Anweisungen
Für die Anweisungen, die vom if-Statement abhängen, gelten die üblichen syntaktischen Regeln: Sie müssen anders als bei Javascript oder PHP nicht mit einem Semikolon abgeschlossen werden, wenn jede von ihnen in einer eigenen Zeile steht.
Will man beispielsweise aber in einer interaktiven Shell mehrere Statements einer bedingten Anweisung in eine Zeile packen, dann trennt man sie durch Semikola:
if(Test-Path *.gif){gci *.gif|foreach{$len += $_.length}; Write-Host $len " Bytes"}
Im Unterschied zu VB-Script benötigt man in PowerShell kein End If. Das trifft auch dann zu, wenn dem if- ein else-Zweig folgt. Für Letzteren gilt die gleiche Syntax wie für if, nur dass er natürlich keinen Vergleich benötigt. Auf else folgt direkt der Block, der ausgeführt wird, wenn die if-Bedingung nicht zutrifft:
Serie von Abfragen mit elseif
Reichen eine if-Abfrage plus ein else -Zweig nicht aus, dann kann man mehrere Vergleichsausdrücke aneinanderreihen. PowerShell bietet zu diesem Zweck ein eigenes Schlüsselwort namens elseif.
Trifft der Vergleich im if-Ausdruck nicht zu, dann werden anschließend alle elseif-Statements geprüft. Ist das Ergebnis bei einem von ihnen TRUE, dann wird der davon abhängige Block ausgeführt und anschließend das gesamte if-elseif- else verlassen. Ist weder die Bedingung von if noch einer elseif-Abfrage wahr, dann kommt die abschließende optionale else-Anweisung zum Zug:
if (Vergleich-1) { Anweisungen }
elseif (Vergleich-2) { Anweisungen }
elseif (Vergleich-3) { Anweisungen }
else { Anweisungen }
switch als Alternative zu langen elseif-Listen
Gerade bei langen if-elseif-Kaskaden ist eleganter, auf eine switch-Anweisung auszuweichen. Sie funktioniert nach dem gleichen Muster wie bei allen Sprachen, die syntaktisch von C abgeleitet wurde, also etwa PHP oder Javascript. In PowerShell eignet sich switch jedoch nur für die Prüfung auf Gleichheit, man kann also dort keine Vergleichsoperatoren verwenden.
Ähnlich wie bei if folgt der zu vergleichende Wert in runden Klammern unmittelbar auf das switch-Schlüsselwort, die Prüfung mit dem Vergleichswert findet aber dann erst im anschließenden Block statt:
switch (Read-Host "Wählen Sie einen Menüpunkt"){
1 {"Datei wird gelöscht"}
2 {"Datei wird angezeigt"}
3 {"Datei erhält Schreibschutz"}
default {"Ungültige Eingabe"}
}
Entspricht die Eingabe den Werten 1, 2 oder 3, dann wird die entsprechende Meldung angezeigt, sonst der Hinweis auf eine ungültige Eingabe.
PowerShell wertet bei switch alle Vergleiche aus
Wenn eine Bedingung zutrifft, dann werden die dazugehörigen Anweisungen ausgeführt, aber PowerShell arbeitet dann die verbleibenden Vergleichswerte des switch -Blocks trotzdem noch ab. Falls eine weitere Bedingung zutrifft, dann kommen auch deren Anweisungen zum Zug.
Möchte man dieses Verhalten unterbinden, dann muss man einen Vergleich mit break abschließen. Es bewirkt den Ausstieg aus dem switch-Block, wenn eine Bedingung zutrifft.
Im obigen Beispiel würde das so aussehen:
1 {"Datei wird gelöscht"; break}
Groß- und Kleinschreibung, Wildcards, Regex
Der Vergleich von Zeichenketten erfolgt standardmäßig ohne Rücksicht auf Groß- und Kleinschreibung. Will man das nicht, dann kann man switch um den Schalter -CaseSensitive ergänzen.
Eine Besonderheit von switch in PowerShell besteht darin, dass man beim Vergleich von Strings auch Wildcards und reguläre Ausdrücke verwenden kann. Zu diesem Zweck muss man die Schalter -wildcard oder -regex angeben:
switch -wildcard(" PowerShell "){
"Power*" {echo "'*' steht für 'shell'";break;}
"*ersh*" {echo "'*' ersetzen 'Pow' und 'ell'";break;}
"PowerShe??" {echo "Muster passt, weil ?? zwei 'l' ersetzt"}
}
Bei Wildcards steht '*' als Platzhalter für mehrere beliebige Zeichen, das '?" dagegen nur für eines. Die Verwendung von regulären Ausdrücken erfolgt analog zu Wildcards, nur mit dem Unterschied, dass man den Schalter -regex verwendet.
Täglich Know-how für IT-Pros mit unserem Newsletter
Verwandte Beiträge
Weitere Links
2 Kommentare
für alle, denen das da oben zu kompliziert ist, weil man einfach nur kurz wissen will, wie eine NORMALE IF-ABFRAGE aussieht, bitte hier weiterlesen:
IF($zusatz -eq 'Text') {
#tu irgendwas
}
ELSE {
#tu irgendwas
}
Bitte beachten, die Vergleichsoperatoren (als gleich, ungleich etc.) sind in Powershell ein wenig anders:
https://www.windowspro.de/script/vergleichsoperatoren-powershell-eq-lt-g...
Da ist es gut beschrieben.
Ich denke das das SWITCH statement unlogisch implementiert ist.
Weil dort nur auf Gleichheit geprüft wird ist die Auswertung aller Vergleiche in der Regel sinnlos. Ein Wert kann nicht zu mehreren Vergleichswerten gleich sein.
Ausnahme: Wenn in den Vergleichen mit regulären Ausdrücken gearbeitet wird, dann geht das. Das ist aber ein Sonderfall, der m.E. besser mit einem Schalter aktivierbar sein sollte.
Nur meine 0,02€!