PowerShell – Parallele Verarbeitung als Job

Im Normalfall werden Befehle von der PowerShell (und auch sonst im Scripting) sequentiell abgearbeitet. Das bedeutet ein Befehl nach dem anderen. Je nachdem, wie lange eine Aufgabe dauert, kann das zu immensen Wartezeiten führen. Zusätzlich ist in dieser Wartezeit ist die PowerShell nicht zu nutzen. Sie müssen warten, bis die Aufgabe(n) abgearbeitet sind.

Die PowerShell bietet die Möglichkeit der parallelen Verarbeitung von Aufgaben, in dem Sie diese als Job starten. Die Verarbeitung wird in diesem Fall in den Hintergrund geschoben. Somit können Sie nach dem Start des Jobs einfach weiterarbeiten. Wie sieht so etwas aus?


Ein einfaches Beispiel zur Verarbeitung im Hintergrund.

Sie führen ein rekursives Get-ChildItem für das Windows Verzeichnis aus. Das kann schon mal einige Zeit in Anspruch nehmen.

PS Work:\> Get-ChildItem $env:windir -Recurse

Wenn Sie nun den gleichen Vorgang als Job starten, wird dieser im Hintergrund ausgeführt und Sie können direkt weiterarbeiten. Den Status des Jobs prüfen Sie mit Get-Job.

Über den Status Running erkennen Sie, dass der Job noch läuft. Wenn dieser Status nun auf Completed wechselt, ist der Job abgeschlossen.

Sie können sich dann das Ergebnis ausgeben lassen, in einer Variablen ablegen oder über Piping weiterverarbeiten. Achten Sie dabei darauf, dass diese Ausgabe nur einmal möglich ist. Es sei denn, Sie verwenden den Parameter Keep. Ohne diesen Parameter wird das Ergebnis nach der Ausgabe gelöscht.


Ein weiteres Anwendungsbeispiel ist die parallele Verarbeitung.

Nehmen wir an, Sie möchten einen IP Bereich nach verfügbaren Adressen per Ping scannen. Wir sprechen vom Bereich 192.168.0.110 -192.168.0.120. Das nimmt einige Zeit in Anspruch, weil jeder Test einzeln nacheinander durchgeführt wird.

Wenn Sie die gleiche Aufgabe als Job definieren, werden alle Tests parallel durchgeführt und benötigen so nur einen Bruchteil der Zeit. Im Bespiel Test-Connection gibt es schon den Parameter AsJob. Damit wird das CMDLet auch ohne den Aufruf Start-Job direkt als Job gestartet. Es gibt eine Reihe von CMDLets, die diesen Prameter unterstützen. Eine Liste erhalten sie über

Get-Help * -Parameter AsJob

Im konkreten Beispiel lässt sich die Zeitersparnis genau berechnen. Der Test-Connection Aufruf hat einen Timeout von 4 Sekunden. Wenn also alle IPs nacheinander getestet werden, ergibt sich so für alle nicht erreichbaren Adressen X eine Zeitdauer von X * 4 Sekunden + der Zeit für die erreichbaren Adressen. Wohingegen bei der Parallelverarbeitung die ganze Verarbeitung nur maximal 4 Sekunden dauert.

Achten Sie in dem Beispiel darauf, dass die Ausgabe lange dauern kann, wenn Sie nicht per select die Einschränkung auf die Eigenschaften Address und Responsetime  vornehmen. Das hat nichts mit dem Job zu tun, sondern liegt darin begründet, dass die Objekte beim Anzeigen den Computernamen auflösen und damit erst den zuständigen DNS Server befragen.

Sie können einzelne oder alle Jobs jederzeit mit dem CMDLet Remove-Job löschen. Sollte ein Job noch nicht abgearbeitet sein, kann dieser mit dem Parameter Force zum Abbruch gezwungen werden.