| | 0

PowerShell: Sprachkonstrukte (Switch Anweisung) – Part 17.6

4.4.9     Switch Anweisung

Die Switch Anweisung ersetzt in ihrer einfachsten Form mehrere IF-Abfragen. Durch unterschiedliche Schalter kann die Switch Anweisung jedoch wesentlich mehr. Die Syntax lautet wie folgt:

Switch <Options>                                  Switch Schlüsselwort mit optionalen Parametern
 (    
<Pipeline>                                                Pipeline zum Testen
)    
{    
<Pattern1> {<StatementList1>}    Anweisungsblock für „pattern1“
<Pattern2> {<StatementList2>}    Anweisungsblock für „pattern2“
. . .                                                                  . . .
<Default> {<StatementList>}          Anweisungsblock für sonstige Fälle
}   

In jedem Durchlauf werden die Anweisungsblöcke für alle Suchmuster (Pattern) ausgeführt, unabhängig davon, wie viele davon mit der Pipeline übereinstimmen. Der Anweisungsblock bei „Default“ wird nur dann ausgeführt, wenn es sonst keine Übereinstimmungen gegeben hat. Pattern kann auch einen Ausdruck beinhalten, der zur Laufzeit ausgewertet wird.

Die Switch Anweisung kann explizit für die Verarbeitung von Dateiinhalten verwendet werden. In diesem Fall ändert sich die Syntax wie folgt:

Switch <Options> -file                         Switch Schlüsselwort mit optionalen Parametern
 (    
<Filename>                                              Pipeline zum Testen
)    
{    
<Pattern1> {<StatementList1>}     Anweisungsblock für „pattern1“
<Pattern2> {<StatementList2>}     Anweisungsblock für „pattern2“
. . .                                                                  . . .
<Default> {<StatementList>}          Anweisungsblock für sonstige Fälle
}

Die Optionen (<Options>) können folgende Werte annehmen:

Name der Option Bedeutung
-Regex Wenn die zu prüfende Pipeline ein String ist, wird es wie eine Regular Expression behandelt. –Wildcard und –Exact werden deaktiviert. Wenn die Pipeline kein String ist, wird –Regex ignoriert.
-Wildcard Wenn die zu prüfende Pipeline ein String ist, sind Vergleiche mit Wildcards möglich. –Regex und –Exact werden deaktiviert. Wenn die Pipeline kein String ist, wird –Wildcard ignoriert.
-Exact Wen die zu prüfende Pipeline ein String ist, ist eine genaue Übereinstimmung notwendig. –Wildcard und –Regex werden deaktiviert. Wenn die Pipeline kein String ist, wird –Exact ignoriert
-Casesensitiv Erzwingt einen Vergleich unter Beachtung der Groß-/Kleinschreibung.

Tabelle 4 3: Optionen für die Switch Anweisung.

Eine schöne und praktische Anwendung für die Switch Anweisung ist die Funktion Log-Message von HK, geringfügig überarbeitet von MG:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
################################################
#   Name:   Log-Message
#   Description:
#       Writes a message to the console and/or in to the logfile
#       Based on: first release of Helge Klein, sepago GmbH
#   Requirements:
#       None
#   Author:
#       Marius Gawenda, sepago GmbH, Marius.Gawenda@sepago.de
#   Version: 1.0
#   Change history:
#       05.08.2010: first release
1.  Function Global:Log-Message(
2.      [Parameter(Mandatory=$true)]
3.      [String] $Msg,
4.      [Parameter(Mandatory=$true)]
5.      [String] $Severity,
6.      [Switch] $NoLogFile
7.  )
8.  {
9.      $sNow = $([System.DateTime]::Now).ToString()
10.     Foreach ($sMessage in ($Msg.Split("`n")))
11.     {
12.         $sSeverity = ""
13.         Switch ($Severity)
14.         {
15.             1 {$sSeverity = "INFORMATION:";$FColor="gray"}
16.             2 {$sSeverity = "WARNING:    ";$FColor="yellow"}
17.             3 {$sSeverity = "ERROR:      ";$FColor="red"}
18.             4 {$sSeverity = "############";$FColor="green"}
19.                 Default {$sSeverity = „“}
20.         }
21.         $sOut = "$sNow $sSeverity $sMessage"
22.     }
23.     If (-not $Script:NoLogFile) {Add-Content $LogFile $sOut}
24.     Write-host $sOut -fore $FColor

Codelisting 4 1: Funktion Log-Message.

Die Switch Anweisung (Zeile 13 im Codelisting 4 1) untersucht den Wert der Variablen $Severity, welcher an die Funktion beim Aufruf übergeben wird. Bei einer Übereinstimmung wird die Variable $sSeverity und die Vordergrundfarbe ($FColor) entsprechend gesetzt. Anschließend wird das aktuelle Datum, Uhrzeit, Wichtigkeit und die eigentliche Nachricht auf dem Bildschirm und/oder in die Logdatei ausgegeben. Das Ergebnis kann dann wie folgt aussehen:

1
2
3
4
5
6
7
8
9
10
11
24.08.2010 10:43:01 WARNING:     The external command (netsh) did not completed in time
24.08.2010 10:43:01 WARNING:     DHCP reservation for client Client_3_lana already exists.
24.08.2010 10:43:01 WARNING:     DNS entry for client Client_3_lana already exists.
24.08.2010 10:43:16 WARNING:     The external command (netsh) did not completed in time
24.08.2010 10:43:16 WARNING:     DHCP reservation for client Client_3_lanb already exists.
24.08.2010 10:43:16 WARNING:     DNS entry for client Client_3_lanb already exists.
24.08.2010 10:43:40 SEPARATOR    #########################################################
24.08.2010 10:43:40 INFORMATION: Starting proccessing
24.08.2010 10:44:16 SEPARATOR    #########################################################
24.08.2010 10:44:16 INFORMATION: Starting proccessing
24.08.2010 10:44:31 WARNING:     The external command (netsh) did not completed in time

Die Switch Anweisung initiiert zur Laufzeit eine Laufvariable mit dem Namen $Switch. In dieser Variablen werden die Inhalte der Pipeline zwischengespeichert und im Switch Block verwendet. Bei jedem Durchlauf kann der aktuelle Wert mit $Switch.Current abgefragt werden. Die $Switch Variable hat folgende Eigenschaften und Methoden:

1
2
3
4
5
6
7
8
9
10
11
12
   TypeName: System.Array+SZArrayEnumerator
Name        MemberType Definition
----        ---------- ----------
Clone       Method     System.Object Clone()
Equals      Method     bool Equals(System.Object obj)
GetHashCode Method     int GetHashCode()
GetType     Method     type GetType()
MoveNext    Method     bool MoveNext()
Reset       Method     System.Void Reset()
ToString    Method     string ToString()
Current     Property   System.Object Current {get;}

Mit $Switch.MoveNext kann der dem aktuellen Datensatz folgende erreicht werden. Wenn als Pattern eine Anweisung verwendet wird, wird während der Auswertung das aktuelle Objekt in der Laufvariable $_ gespeichert. So kann in Bedingungen darauf zugegriffen werden.
Schließlich können in der Switch Anweisung auch Regular Expressions verwendet werden. Folgendes Beispiel zeigt die Verwendung der Switch Anweisung für die Verarbeitung von Dateien:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1.  $cW=$cE=$cS=$cC=0
2.  Switch -Regex -File .\NISRV32_ADM-NI-WTSSERVICE_11.LOG {
3.  >> 'Warning[ ]' {$cw++}
4.  >> 'Error[ ]' {$cE++}
5.  >> '-->st' {$cS++}
6.  >> '!-db:'{$cc++}
7.  >> }
8.  >>
9.  $cW
151
10. $cE
0
11. $cS
6
12. $cC
1260

Zunächst werden einige Variablen initialisiert (Zeile 1). Die Switch Anweisung soll Regular Expressions unterstützen und die Pipe aus einer NetInstall Logdatei empfangen. In dem Datenstrom wird nach Warnungen, Fehlern, ausgeführten Skripten und nach erkannten Komponenten in der Datenbank gesucht. Bei einem Treffer wird die jeweilige Variable inkrementiert. Anschließend werden die Inhalte der Variablen ausgegeben.

Auch mit Hilfe der Switch Anweisung können die Namen der installierten Skripte ausgegeben werden:

1
2
3
4
5
6
7
1.  Switch -Regex -File .\NISRV32_ADM-NI-WTSSERVICE_11.LOG {'(.*)(-->st.* )(".*)' { $Matches[3]}}
“00_Install_User_Environment“
“11_User_HomeDirCheck (bei jeder Anmeldung)“
“12_User_ProfileConfig (bei jeder Anmeldung)“
“13_User_ProfileConfig (einmal)“
“14_User_PathConfig (AI-Takt f?r SNW-Benutzer)“
“ZZ_Last_Project_of_User_Environment“

In dem gesuchten Muster werden mit den runden Klammern Teile (Tokens) der Treffer markiert, auf die später zugegriffen werden kann. Die Variable $Matches beinhaltet bei Übereinstimmung die einzelnen Tokens. Das gewünschte Token kann dann über ein Index angesprochen werden (hier: 3).

Eine Übersicht aller Artikel dieser Windows PowerShell Blogserie findet ihr hier.

Zurück zu Part 17.5 – Sprachkonstrukte (Flusssteuerung mit CMDLets)

Weiter zu Part 17.7 – Sprachkonstrukte (Trap Anweisung, Throw Anweisung)