PowerShell-Jobs

Allgemeine Infos

PowerShell-Jobs führen Befehle aus, ohne die Konsole zu blockieren. Es gibt drei Arten: BackgroundJob (Start-Job, eigener Prozess auf dem lokalen Rechner), RemoteJob (Ausführung in einer Remote-Sitzung, etwa Invoke-Command -AsJob) und ThreadJob bzw. PSTaskJob (eigener Thread im selben Prozess).

Seit PowerShell 7.0 gibt es ForEach-Object -Parallel, das Pipeline-Objekte parallel in eigenen Runspaces verarbeitet. Seit PowerShell 6.0 startet der Operator & am Zeilenende einen Hintergrundjob, gleichwertig zu Start-Job.

Abgrenzung: Jobs leben nur so lange wie die startende Sitzung. Schließt Du sie, enden auch alle laufenden Kindjobs. Für dauerhafte oder zeitgesteuerte Ausführung sind geplante Aufgaben oder Azure Automation gedacht.

Funktionsweise & Details

Die Varianten im Vergleich:

  1. Start-Job startet einen eigenen Prozess. Die Isolation ist hoch, ein Absturz betrifft andere Jobs nicht. Alle Objekte werden aber serialisiert, das kostet Zeit.
  2. Start-ThreadJob (Modul ThreadJob) nutzt Threads im selben Prozess. Ohne Serialisierung ist das deutlich schneller, Standard-ThrottleLimit ist 5. Ein schwerer Fehler kann aber den gesamten Prozess und damit alle Jobs beenden.
  3. ForEach-Object -Parallel führt den Scriptblock je Objekt in einem Runspace aus, Standard-ThrottleLimit ist 5. Seit 7.1 werden Runspaces aus einem Pool wiederverwendet. Variablen des Aufrufers erreichst Du mit $using:. Mit -AsJob entsteht ein Job-Objekt mit einem Kindjob pro Scriptblock.
  4. Verwaltung: Get-Job zeigt Status (Running, Completed, Failed, Blocked), Receive-Job holt Ergebnisse (ohne -Keep werden sie dabei gelöscht), Wait-Job wartet, Stop-Job und Remove-Job räumen auf.
  5. Fehlerursachen findest Du in $job.ChildJobs[0].JobStateInfo.Reason.

Vorteile & Nutzen

  • Zeitersparnis bei Wartezeiten: Netzwerkabfragen oder API-Aufrufe gegen viele Ziele laufen parallel statt nacheinander
  • Freie Konsole: Lange Aufgaben laufen im Hintergrund, Du arbeitest weiter
  • Wählbare Isolation: Prozess-Jobs für Robustheit, Thread-Jobs für Geschwindigkeit
  • Steuerbare Last: ThrottleLimit verhindert, dass Server oder APIs mit Anfragen überlastet werden

Praxisbeispiel

Ein Filialist mit 70 Standorten prüft wöchentlich die Erreichbarkeit und Firmware-Version der Router in allen Filialen per REST-Abfrage. Nacheinander dauerte das über eine Stunde, weil jede Abfrage auf Timeouts wartete. Der Admin stellt auf ForEach-Object -Parallel mit -ThrottleLimit 10 um und übergibt die API-Zugangsdaten per $using:. Die Prüfung läuft jetzt in wenigen Minuten, die Ergebnisse sammelt das Skript in einer CSV.

Worauf sollte man achten?

  • -Parallel nicht für triviale Aufgaben verwenden, der Aufwand für Runspaces kann das Skript laut Microsoft deutlich langsamer machen
  • Gemeinsam genutzte Objekte nur mit threadsicheren Typen wie System.Collections.Concurrent ändern
  • Die Ausgabereihenfolge paralleler Läufe ist nicht garantiert, Ergebnisse bei Bedarf nachträglich sortieren
  • Receive-Job ohne -Keep löscht Ergebnisse, beim Debuggen -Keep verwenden
  • Fertige Jobs mit Remove-Job entfernen, sonst wächst der Speicherbedarf der Sitzung

Fazit

Jobs und -Parallel beschleunigen Skripte, die auf Netzwerk oder APIs warten. Wähle Thread-basierte Varianten für Tempo und Start-Job, wenn Isolation wichtiger ist.