| | 0

PowerShell: Sprachkonstrukte (Flusssteuerung mit CMDLets) – Part 17.5

4.4.8     Flusssteuerung mit CMDLets

Die Flusssteuerung kann auch mit Hilfe von CMDLets vorgenommen werden. Sie können prinzipiell die gleichen Aufgaben erledigen wie die Sprachkonstrukte, es gibt jedoch einige wichtige Unterschiede. Die am häufigsten für die Flusssteuerung verwendete CMDLets sind ForEach-Object und Where-Object.

4.4.8.1     ForEach-Object

Das ForEach-Objekt CMDLet arbeitet ähnlich wie die Foreach-Schleife. Es wird eine Reihe von Objekten aus einer Collection nacheinander in einem Anweisungsblock abgearbeitet. Der Unterschied zu der Foreach-Schleife besteht darin, dass hier die Objekte erst zu Verarbeitungszeit generiert werden und nach der Verarbeitung/Ausgabe verworfen werden. Die Foreach-Schleife hingegen generiert die komplette Liste der Objekte, bevor die eigentliche Verarbeitung beginnt. In vielen Fällen muss das keine Bedeutung haben, aber bei der Verarbeitung von großen Datenmengen wirkt sich die Foreach-Schleife unter Umständen sehr negativ auf den Systemspeicher aus. Der zweite Unterschied besteht darin, dass die Foreach-Schleife lediglich einen Anweisungsblock verarbeiten kann. ForEach-Object hingegen kann drei solche Blöcke verarbeiten, die eine ähnliche Bedeutung haben wie bei Funktionen (Begin, Process, End; siehe Kapitel 4). Um dies zu veranschaulichen, wird noch mal das vierte Beispiel für die Foreach-Schleife (Kapitel 4.4.3) betrachtet:

1
2
1.  Get-Process iexplore | ForEach-Object {$h=0}{$h+=$_.Handles}{$h}
2236

Auf den ersten Blick fällt die wesentlich kompaktere Schreibweise als bei der Foreach-Schleife auf. Hier wird ebenfalls mit Hilfe des CMDLets Get-Process die Liste aller laufenden Internet Explorer Processe generiert. Der erste Anweisungsblock wird einmalig ausgeführt, bevor das ForEach-Object CMDLet das erste Objekt von der Pipeline empfängt. Der zweite Anweisungsblock wird für jedes übergebene Objekt ausgeführt. Das Objekt selbst wird in der Laufvariablen $_ zwischengespeichert. Der Ausdruck $_.Handles repräsentiert also die Anzahl von Handles für jedes Objekt (ein einzelner Internet Explorer Process). Die Handles werden jeweils auf die Variable $h addiert. Im letzten Anweisungsblock wird anschließend die Summe der Handles ausgegeben. Dieser Block wird ausgeführt, wenn alle übergebenen Objekte verarbeitet wurden.

4.4.8.2     Where-Object

Eine weitere Möglichkeit für die Flusssteuerung stellt das CMDLet Where-Object dar. Es stellt eine Art Filterungsmöglichkeit für die Pipeline. Die Filterung kann über eine oder mehrere Eigenschaften der von der Pipeline übergebenen Objekte erfolgen.

1
2
3
4
5
6
7
8
9
10
11
12
13
1.  Get-EventLog System | Where-Object {$_.EntryType -like "error"}
   Index Time          EntryType   Source                 InstanceID Message
   ----- ----          ---------   ------                 ---------- -------
  136159 Feb 17 10:18  Error       Service Control M...   3221232472 The IBM Access Suppo
  136029 Feb 17 10:17  Error       Service Control M...   3221232488 The Data Transfer Se
  135988 Feb 17 10:08  Error       ipnathlp                    31004 The descrip-tion for
  135987 Feb 17 10:08  Error       ipnathlp                    31004 The descrip-tion for
  135872 Feb 17 09:15  Error       Service Control M...   3221232472 The IBM Access Suppo
  135747 Feb 17 09:06  Error       Service Control M...   3221232488 The Data Transfer Se
  135723 Feb 17 08:43  Error       Service Control M...   3221232504 The Service Control
. . .
2.  Ctrl + C

In diesem Beispiel wird das System-Eventlog nach Fehlermeldungen gefiltert.