| | 0

PowerShell: Sprachkonstrukte (Foreach- und While Schleife) – Part 17.3

4.4.3     Foreach-Schleife

Die Foreach-Schleife eignet sich, im Gegensatz zur For-Schleife, für die Verarbeitung von Sammlungen (Collections), welche eine unbekannte Anzahl von Elementen aufweisen. Für jedes Element der Sammlung kann innerhalb der Foreach-Schleife ein Anweisungsblock ausgeführt werden.

Foreach   
 (   
Foreach Schlüsselwort
<Varlable> 
In   
SchleifenvariableIn
Schlüsselwort
<Pipeline>  
)   
{   
Pipeline zur Verarbeitung
<StatementList>  
}
Anweisungsblock

Es gilt an dieser Stelle noch einen Namenskonflikt aufzulösen. Es existiert standardmäßig ein Alias mit dem Namen „Foreach“. Dieser ist für das Cmdlet Foreach-Objekt definiert. Wenn die Shell das Wort „Foreach“ am Anfang einer Zeile erkennt, wird das als das Schlüsselwort der Foreach-Schleife behandelt. Wird es hingegen irgendwo anders gefunden, handelt es sich um das Cmdlet.

Beim Durchlaufen der Foreach-Schleife wird der Schleifenvariable jeweils ein Objekt aus der Sammlung (Pipeline) zugewiesen. Über diese Variable kann das Objekt dann im Anweisungsblock angesprochen werden. Die Pipeline selbst wird nicht „stückweise“ verarbeitet, wie das beim Senden an einen weiteren Befehl der Fall wäre, sondern wird komplett ausgeführt und erst dann abgearbeitet.

Beispiele:

1
2
3
4
5
6
7
8
9
10
11
12
1.  Foreach ($s in Get-Service){if ((Get-ItemProperty -Path HKLM:\system\CurrentControlSet\services\$($s.Name) -Name start).start -eq 2 -and $($s.Status) -ne "running") {$s.DisplayName}}
Microsoft .NET Framework NGEN v4.0.30319_X86
Microsoft .NET Framework NGEN v4.0.30319_X64
Google Update Service (gupdate)
Lenovo Microphone Mute
Net Driver HPZ12
Software Protection
Windows Biometric Service
2.  $Total=0
3.  ForEach ($P In Get-Process){If ($($p.Name) -like "iexplore"){$Total+=$p.Handles}}
4.  $Ttotal
4136

 

Das erste Beispiel soll auf der Konsole diejenigen Dienste ausgeben, welche automatisch starten sollen, jedoch zur Zeit nicht laufen. Dieses Beispiel ist auch ein Beispiel für eine gewisse Inkonsequenz des Befehls Get-Service: dort fehlt die Information über die Startart! Aus diesem Grund wird hier einfach der entsprechende Registry Eintrag für den jeweils verarbeiteten Dienst ausgewertet. Die Quelle besteht aus der Sammlung aller Dienste, die auf dem Computer installiert sind (Get-Service). Im Anweisungsblock wird zunächst nach der Startart des Dienstes in der Registry geschaut. Dabei wird direkt der interne Name des Dienstes (Rückgabe von Get-Service) für den Pfad verwendet ($s.Name). Der Wert zwei steht für den automatischen Start des Dienstes. Gib es an dieser Stelle einen Treffer, wird weiter der gegenwärtige Status des Dienstes überprüft. Ist dieser ungleich „running“ wird der Name (DisplayName) des Dienstes auf der Konsole ausgegeben.

Das zweite Beispiel erledigt die gleiche Aufgabe, wie das letzte Beispiel für die For-Schleife.

 

4.4.4     While Schleife

Die While Schleife ist eine konditionale Schleife, d.h. sie wird durch eine logische Bedingung gesteuert.

While
 (   
While Schlüsselwort
<Pipeline>
)
Pipeline zum Testen
{   
<StatementList>
Anweisungsblock
}   

Der Anweisungsblock wird solange ausgeführt, solange der Test der Pipeline den Wert
$True ergibt. Der Test wird durchgeführt, bevor die While Schleife den Anweisungsblock ausführt. In der Regel sollte der Anweisungsblock Code enthalten, welcher sich auf die Testbedingung auswirkt, da sonst eine Endlosschleife entstehen kann.

 

Beispiele:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1.  While (Get-ChildItem){Write-Host "... still running..."}
... still running...
... still running...
... still running...
... still running...
... still running...
...
2.  Ctrl + C
3.  While ((Get-ChildItem).Count -ne $Null){Remove-Item -path @(Get-ChildItem)[0];Write-Host "Removing $(@(Get-ChildItem)[0])"}
Removing CheckProcess.cmd
Removing Files.vbs
Removing log - Copy.log
Removing log.log
Removing t.cmd

Das erste Beispiel stellt eine Endlosschleife dar, wenn das aktuelle Verzeichnis nicht leer ist! Dann liefert nämlich Get-ChildItem den Wert $True zurück. Solange sich also der Inhalt des aktuellen Verzeichnisses nicht von außen verändert, wird die Schleife niemals enden, da im Anweisungsblock keinerlei Dateioperationen durchgeführt werden. Auf der Konsole kann die Schleife mit der Tastenkombination Ctrl + C unterbrochen werden.

Das zweite Beispiel ist nicht unbedingt zum Nachahmen gedacht, es werden hier aktiv Dateien gelöscht! Die  zu testende Pipeline hat den Wert $True, wenn das aktuelle Verzeichnis Dateien enthält. Im Anweisungsblock befinden sich zwei Kommandos (durch Semikolon getrennt). Das erste Kommando löscht die erste gefundene Datei im aktuellen Verzeichnis (was genau sich unter @(Get-ChildItem)[0] verbirgt, wird im Kapitel 5.1 näher beschrieben). Das zweite Kommando im Anweisungsblock gibt den Namen der gerade gelöschten Datei auf dem Bildschirm aus. Die Schleife endet, wenn die letzte Datei gelöscht wurde.

 

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

Zurück zu Part 17.2 –  Sprachkonstrukte (For-Schleife)

Weiter zu Part 17.4 – Sprachkonstrukte (Do/While Schleife, Do/Until Schleife)