IF, ELSE, SWITCH: Bedingte Anweisungen in PowerShell


    Tags:

    Powershell-LogoPraktisch jede proze­durale Programmier­sprache benötigt Konstrukte, die Anweisungen abhängig vom Zutreffen bestimmter Bedingungen auszu­führen. Dafür haben sich if/else und switch einge­bürgert, die auch PowerShell unter­stützt. Im Vergleich zu anderen Script-Sprachen zeigt sie jedoch einige syntak­tische Eigen­heiten.

    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.

    2 Kommentare

    Bild von Yan
    Yan sagt:
    20. April 2016 - 13:33

    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.

    Bild von LuI
    LuI sagt:
    6. Juli 2016 - 9:52

    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€!