.. include:: Abbrev.txt Bedingungen *********** Häufig wird man nicht einen *linearen* Quellcode schreiben, sondern in Abhängigkeit von bestimmten Bedingungen den einen oder den anderen Quellcode ausführen. Powershell kennt mehrere Möglichkeiten für das Prüfen von Bedingungen. Einfache Vergleiche =================== Mit Hilfe der Vergleichsoperatoren lässt sich eine Bedingung bereits in der Konsole vornehmen. Im Gegensatz zu anderen Programmiersprachen verwendet PS bei der Formulierung von Vergleichsoperatoren eine der englischen Sprache verwandte Syntax und nicht die sonst verwendeten mathematischen Operationszeichen. Eine Übersicht finden sie hier :ref:`vergleichsoperator`. .. index:: Vergleichsoperator Wie der Tabelle zu entnehmen ist, gibt es drei Varianten der Vergleichsoperatoren. Soll die Groß- und Kleinschreibung berücksichtigt werden, stellt man dem Operator ein "c", ansonsten ein "i" voraus. Wird dies weggelassen, ist case-insensitive eingestellt. Beurteilen Sie die Ergebnisse der folgenden Vergleiche: .. code-block:: sh 4 -eq 10 "secret" -ieq "SECRET" 123 -lt 123.5 12 -eq "Hello" 12 -eq "000012" "12" -eq 12 "12" -eq 012 "012" -eq 012 123 -lt 123.4 123 -lt "123.4" 123 -lt "123.5" .. image:: images/vergleichs_operator_ergebnis.png Umgekehrte Vergleiche ===================== .. index:: -not, ! Ein Vergleich hat als Ergebnis immer entweder ein *true* oder ein *false* Mit Hilfe des *-not* - Operators bzw. des *!* können diese Ergebnisse auch umgedreht werden. .. code-block:: sh $a = 10 $a -gt 5 True -not ($a -gt 5) False # Shorthand: instead of -not "!" can also be used: !($a -gt 5) False Verbinden mehrerer Vergleiche ============================= .. index:: and, or Mit Hilfe der Verknüpfungsoperatoren *-and* bzw. *-or* können mehrere Vergleiche auch zu einem Gesamtvergleich verbunden werden. .. code-block:: sh ( ($age -ge 18) -and ($sex -eq "m") ) :ref:: `logischeOperatoren` :ref:: `auswahl_if_elseif_else` Verzweigung =========== Die Vergleichsoperatoren geben zwar einen Hinweis auf True oder False, aber sie allein lassen keine Auswahlentscheidung des Programmiers zu. Deshalb finden die Vergleichsoperatoren ihren Einsatz innerhalb von Wenn-Dann-Statements, die eine Reaktion auf True oder False zulassen. Die Syntax dieser Anweisung ist wie folgt .. code-block:: sh If (condition) { # If the condition applies, # this code will be executed } $a = 11 If ($a -gt 10) { "$a is larger than 10" } 11 is larger than 10 .. image:: images/ps_ifelse.png .. code-block:: sh If ($a -gt 10) { "$a is larger than 10" } Else { "$a is less than or equal to 10" } Mehrere Bedingungen können über das *ElseIf* - Statement beschrieben werden. .. code-block:: sh If ($a -gt 10) { "$a is larger than 10" } Else { "$a is less than or equal to 10" } If ($a -gt 10) { "$a is larger than 10" } ElseIf ($a -eq 10) { "$a is exactly 10" } ElseIf ($a -ge 10) { "$a is larger than or equal to 10" } Else { "$a is smaller than 10" } Die Bedingungen können natürlich noch in sich verschachtelt werden .. image:: images/ps_if_elseif.png :width: 500 Auswahl ======= .. index:: switch UM eine Variable auf verschiedene Werte hin abzuprüfen, ist neben dem if-elseif-Statement noch eine weitere Möglichkeit vorhanden. Sie kann allerdings nur auf **eine Variable** angewendet werden. .. image:: images/ps_switch.png :width: 500 .. code-block:: sh $value = 1 $switch($value) { 1 {"Number 1" } 2 {"Number 2" } 3 {"Number 3" } } Number 1 Als Standard-Vergelcihsoperator wird *-eq* genommen. Es sind aber auch andere Vergleiche denkbar. .. code-block:: sh $value = 8 Switch ($value) { # Instead of a standard value, a code block is used # that results in True for numbers smaller than 5: {$__-le 5} { "Number from 1 to 5" } # A value is used here; Switch checks whether this # value matches $value: 6 { "Number 6" } # Complex conditions are allowed as they are here, # where -and is used to combine two comparisons: {(($__-gt 6) -and ($__-le 10))} { "Number from 7 to 10" } } Number from 7 to 10 Auch ein Mischen ist möglich: .. code-block:: sh $value = 8 Switch ($value) { # The initial value (here it is in $value) # is available in the variable $_: 6 { "Number 6" } {(($_ -gt 6) -and ($_ -le 10))} { "$_ is a number from 7 to 10" } } 8 is a number from 7 to 10 Default ------- .. index:: default, switch Falls keine der Bedingungen zutrifft, kann mit Hilfe des Schlüsselwortes **default** eine Klausel ausgeführt werden. .. code-block:: sh $value = 50 Switch ($value) { {$_ -le 5} { "$_is a number from 1 to 5" } 6 { "Number 6" } {(($_ -gt 6) -and ($_ -le 10))} { "$_ is a number from 7 to 10" } # The code after the next statement will be # executed if no other condition has been met: default {"$_ is a number outside the range from 1 to 10" } } 50 is a number outside the range from 1 to 10 Break ----- .. index:: break Häufig kann es vorkommen, dass mehrere Vergleiche innerhalb einer switch-Anweisung gültig sind. |PS| würde dann mehrere Klauseln ausführen. Um dies zu verhindern, kann man jede Klausel mit Hilfe des Schlüsselwortes **break** versehen. Nach der ersten erfolgreichen Klausel beendet |PS| die Ausführung. .. code-block:: sh $value = 50 Switch ($value) { 50 { "the number 50" } {$_ -gt 10} {"larger than 10"} {$_ -is [int]} {"Integer number"} } The Number 50 Larger than 10 Integer number $value = 50 Switch ($value) { 50 { "the number 50"; break } {$_ -gt 10} {"larger than 10"; break} {$_ -is [int]} {"Integer number"; break} } The number 50 String-Vergleiche ----------------- Da switch nur auf Gleichheit prüft, sind auch andere Datentypen vergleichbar. .. code-block:: sh $action = "sAVe" Switch ($action) { "save" { "I save..." } "open" { "I open..." } "print"{ "I print..." } Default{ "Unknown command" } } I save... Groß- und Kleinschreibung kann man mit der Option -case eingeschaltet werden .. code-block:: sh $action = "sAVe" Switch -case ($action) { "save" { "I save..." } "open" { "I open..." } "print" { "I print..." } Default { "Unknown command" } } Unknown command Wildcards können ebenfalls überprüft werden .. index:: wildcard .. code-block:: sh $text = "IP address: 10.10.10.10" Switch -wildcard ($text) { "IP*" { "The text begins with IP: $_" } "*.*.*.*" { "The text contains an IP " + "address string pattern: $_" } "*dress*" { "The text contains the string " + "'dress' in arbitrary locations: $_" } } The text begins with IP: IP address: 10.10.10.10 The text contains an IP address string pattern: IP address: 10.10.10.10 The text contains the string 'dress' in arbitrary locations: IP address: 10.10.10.10 Reguläre Ausdrücke ------------------ .. todo:: Eigenes Kapitel schreiben switch auf Listen ----------------- .. todo:: Erst mal weglassen, da noch kein Array behandelt Was mach folgener Code ? .. code-block:: sh $array = 1..5 Switch ($array) { {$_ % 2} { "$_ is odd."} Default { "$_ is even."} } 1 is odd. 2 is even. 3 is odd. 4 is even. 5 is odd. Zusammenfassung --------------- Übersetzen Sie folgenden Text: Intelligent decisions are based on conditions, which in the simplest form can be reduced to plain Yes or No answers. Using the comparison operators, you can formulate such conditions and can even combine these with the logical operators to form complex queries. The simple Yes/No answers of your conditions determine whether particular PowerShell instructions should be carried out or not. In the simplest form, you can use the Where-Object cmdlet in the pipeline. It functions there like a filter, allowing only those results through the pipeline that correspond to your condition. If you would like more control, or would like to execute larger code segments independently of conditions, use the If statement, which evaluates as many different conditions as you wish and, depending on the result, executes the allocated code. This is the typical "If-Then" scenario: if certain conditions are met, then certain code segments will be executed. An alternative to the If statement is the Switch statement: using it, you can compare a fixed initial value with various possibilities. Switch is the right choice when you want to check a particular variable against many different possible values. Aufgaben ======== **ZahlenRaten** --------------- Erstellen sie ein Skript, welches folgende Aufgabe erfüllt: Es muss eine Meldung anzeigen, in der der Benutzer aufgefordert wird, eine Zahl zwischen 1 und 50 einzugeben. Das Skript muss die vom Benutzer eingegebene Zahl mit einer zufällig generierten Zahl vergleichen. Wenn die Zahlen nicht übereinstimmen, muss das Skript eine Meldung anzeigen, in der angegeben wird, ob die geratene Zahl zu hoch oder zu niedrig war, und der Benutzer aufgefordert wird, noch einmal zu raten. Wenn der Benutzer richtig rät, muss das Skript die Zufallszahl sowie die Anzahl der Rateversuche anzeigen. An diesem Punkt ist das Spiel beendet, das Skript muss also auch beendet werden. Siehe dazu auch: http://msdn.microsoft.com/de-de/library/system.random_members.aspx **Dateien kopieren** -------------------- Diese Skripts sollen folgende Aufgaben ausführen: * Durchsuchen des Ordners „C:\Scripts“ und von dessen Unterordnern. * Durchsuchen jedes Ordners nach sämtlichen Textdateien (Dateien mit der Erweiterung „.txt“) und Prüfen des Erstellungsdatums jeder Datei. * Kopieren jeder .txt-Datei, die mehr als 10 Tage zuvor erstellt wurde, in den Ordner „C:\Old“. * Ausgeben des Dateinamens (kein vollständiger Pfad, nur Dateiname) jeder kopierten Datei. * Ausgeben der Anzahl der kopierten Dateien. Lösungen ======== **ZahlenRaten** --------------- .. image:: images/zahlenraten.png .. code-block:: sh $guesses = 0 $low = 1 $high = 50 $a = New-Object Random $a = $a.Next($low,$high) while ($true) { $guess = read-host "Enter a number between 1 and 50: " $guesses++ if ($guess -eq $a) { "Random Number: " + $guess "Number of Guesses: " + $guesses break } elseif ($guess -gt $a) { "Too high" } else { "Too low" } } **Dateien kopieren** -------------------- .. code-block:: sh foreach ($i in Get-ChildItem C:\Scripts -recurse) { if (($i.CreationTime -lt ($(Get-Date).AddDays(-10))) -and ($i.Extension -eq ".txt")) { #Copy-Item $i.FullName C:\old $i.Name $x = $x + 1 } } "Total Files: " + $x .. index:: Bedingung, condition, if, else, if-else, Vergleichsoperator