about_Jobs
Kurze Beschreibung
Enthält Informationen dazu, wie PowerShell-Hintergrundaufträge einen Befehl oder Ausdruck im Hintergrund ausführen, ohne mit der aktuellen Sitzung zu interagieren.
Lange Beschreibung
PowerShell führt Befehle und Skripts gleichzeitig über Aufträge aus. Es gibt drei Auftragstypen, die von PowerShell bereitgestellt werden, um Parallelität zu unterstützen.
RemoteJob
– Befehle und Skripts werden in einer Remotesitzung ausgeführt. Weitere Informationen finden Sie unter about_Remote_Jobs.BackgroundJob
– Befehle und Skripts werden in einem separaten Prozess auf dem lokalen Computer ausgeführt.PSTaskJob
oderThreadJob
: Befehle und Skripts werden in einem separaten Thread innerhalb desselben Prozesses auf dem lokalen Computer ausgeführt. Weitere Informationen finden Sie unter about_Thread_Jobs.
Das Remote ausführen von Skripts auf einem separaten Computer oder in einem separaten Prozess bietet eine hervorragende Isolation. Fehler, die im Remoteauftrag auftreten, wirken sich nicht auf andere ausgeführte Aufträge oder die übergeordnete Sitzung aus, die den Auftrag gestartet hat. Die Remotingebene führt jedoch zu Mehraufwand, einschließlich Objektserialisierung. Alle Objekte werden serialisiert und deserialisiert, wenn sie zwischen der übergeordneten Sitzung und der Remotesitzung (Auftragssitzung) übergeben werden. Die Serialisierung großer komplexer Datenobjekte kann große Mengen an Compute- und Arbeitsspeicherressourcen beanspruchen und große Datenmengen über das Netzwerk übertragen.
Threadbasierte Aufträge sind nicht so robust wie Remote- und Hintergrundaufträge, da sie im selben Prozess auf verschiedenen Threads ausgeführt werden. Wenn ein Auftrag einen kritischen Fehler aufweist, der den Prozess abstürzt, werden alle anderen Aufträge im Prozess beendet.
Threadbasierte Aufträge erfordern jedoch weniger Mehraufwand. Sie verwenden weder die Remotingebene noch die Serialisierung. Die Ergebnisobjekte werden als Verweise auf Liveobjekte in der aktuellen Sitzung zurückgegeben. Ohne diesen Mehraufwand werden threadbasierte Aufträge schneller ausgeführt und verbrauchen weniger Ressourcen als die anderen Auftragstypen.
Wichtig
Die übergeordnete Sitzung, die den Auftrag erstellt hat, überwacht auch den Auftrag status und sammelt Pipelinedaten. Der untergeordnete Auftragsprozess wird vom übergeordneten Prozess beendet, sobald der Auftrag den Status "Abgeschlossen" erreicht hat. Wenn die übergeordnete Sitzung beendet wird, werden alle ausgeführten untergeordneten Aufträge zusammen mit ihren untergeordneten Prozessen beendet.
Es gibt zwei Möglichkeiten, diese Situation zu umgehen:
- Verwenden Sie
Invoke-Command
zum Erstellen von Aufträgen, die in getrennten Sitzungen ausgeführt werden. Weitere Informationen finden Sie unter about_Remote_Jobs. - Verwenden Sie
Start-Process
, um einen neuen Prozess anstelle eines Auftrags zu erstellen. Weitere Informationen finden Sie unter Start-Process.
Die Auftrags-Cmdlets
Start-Job
– Startet einen Hintergrundauftrag auf einem lokalen Computer.Get-Job
– Ruft die Hintergrundaufträge ab, die in der aktuellen Sitzung gestartet wurden.Receive-Job
– Ruft die Ergebnisse von Hintergrundaufträgen ab.Stop-Job
– Beendet einen Hintergrundauftrag.Wait-Job
– Unterdrückt die Eingabeaufforderung, bis ein oder alle Aufträge abgeschlossen sind.Remove-Job
– Löscht einen Hintergrundauftrag.Invoke-Command
– Der AsJob-Parameter erstellt einen Hintergrundauftrag auf einem Remotecomputer. Sie können verwendenInvoke-Command
, um jeden Auftragsbefehl remote auszuführen, einschließlichStart-Job
.
Starten eines Auftrags auf dem lokalen Computer
Verwenden Sie das Start-Job
Cmdlet, um einen Hintergrundauftrag auf dem lokalen Computer zu starten.
Um einen Start-Job
Befehl zu schreiben, schließen Sie den Befehl, den der Auftrag ausführt, in geschweifte Klammern ({}
) ein. Verwenden Sie den ScriptBlock-Parameter , um den Befehl anzugeben.
Mit dem folgenden Befehl wird ein Hintergrundauftrag gestartet, der einen Get-Process
Befehl auf dem lokalen Computer ausführt.
Start-Job -ScriptBlock {Get-Process}
Wenn Sie einen Hintergrundauftrag starten, wird die Eingabeaufforderung sofort zurückgegeben, auch wenn die Ausführung des Auftrags länger dauert. Sie können ohne Unterbrechung in der Sitzung weiterarbeiten, während der Auftrag abgeschlossen wird.
Der Start-Job
Befehl gibt ein Objekt zurück, das den Auftrag darstellt. Das Auftragsobjekt enthält nützliche Informationen zum Auftrag, aber nicht die Auftragsergebnisse.
Sie können das Auftragsobjekt in einer Variablen speichern und es dann mit den anderen Job-Cmdlets verwenden, um den Hintergrundauftrag zu verwalten. Der folgende Befehl startet ein Auftragsobjekt und speichert das resultierende Auftragsobjekt in der $job
Variablen.
$job = Start-Job -ScriptBlock {Get-Process}
Ab PowerShell 6.0 können Sie den Hintergrundoperator (&
) am Ende einer Pipeline verwenden, um einen Hintergrundauftrag zu starten. Weitere Informationen finden Sie unter Hintergrundoperator.
Die Verwendung des Hintergrundoperators entspricht funktional der Verwendung des Start-Job
Cmdlets im vorherigen Beispiel.
$job = Get-Process &
Abrufen von Auftragsobjekten
Das Get-Job
Cmdlet gibt Objekte zurück, die die Hintergrundaufträge darstellen, die in der aktuellen Sitzung gestartet wurden. Ohne Parameter gibt alle Aufträge zurück, Get-Job
die in der aktuellen Sitzung gestartet wurden.
Get-Job
Das Auftragsobjekt enthält den Status des Auftrags, der angibt, ob der Auftrag abgeschlossen wurde. Ein abgeschlossener Auftrag hat den Status Abgeschlossen oder Fehler. Ein Auftrag kann auch blockiert oder ausgeführt sein.
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Complete True localhost Get-Process
Sie können das Auftragsobjekt in einer Variablen speichern und verwenden, um den Auftrag in einem späteren Befehl darzustellen. Der folgende Befehl ruft den Auftrag mit der ID 1 ab und speichert ihn in der $job
Variablen.
$job = Get-Job -Id 1
Abrufen der Ergebnisse eines Auftrags
Wenn Sie einen Hintergrundauftrag ausführen, werden die Ergebnisse nicht sofort angezeigt. Verwenden Sie das Cmdlet, um die Ergebnisse eines Hintergrundauftrags Receive-Job
abzurufen.
Im folgenden Beispiel ruft das Receive-Job
Cmdlet die Ergebnisse des Auftrags mithilfe des Auftragsobjekts in der $job
Variablen ab.
Receive-Job -Job $job
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
668 7 2672 6168 104 32.26 488 csrss
...
Sie können die Ergebnisse eines Auftrags in einer Variablen speichern. Der folgende Befehl speichert die Ergebnisse des Auftrags in der $job
Variablen in der $results
Variablen.
$results = Receive-Job -Job $job
Abrufen und Beibehalten von Teilauftragsergebnissen
Das Receive-Job
Cmdlet ruft die Ergebnisse eines Hintergrundauftrags ab. Wenn der Auftrag abgeschlossen ist, Receive-Job
ruft alle Auftragsergebnisse ab. Wenn der Auftrag noch ausgeführt wird, Receive-Job
ruft die ergebnisse ab, die bisher generiert wurden. Sie können Befehle erneut ausführen Receive-Job
, um die restlichen Ergebnisse zu erhalten.
Standardmäßig löscht die Ergebnisse aus dem Cache, Receive-Job
in dem auftragsergebnisse gespeichert werden. Wenn Sie erneut ausführen Receive-Job
, erhalten Sie nur die neuen Ergebnisse, die nach der ersten Ausführung eingetroffen sind.
Die folgenden Befehle zeigen die Ergebnisse der Receive-Job
Befehle, die ausgeführt werden, bevor der Auftrag abgeschlossen ist.
C:\PS> Receive-Job -Job $job
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
C:\PS> Receive-Job -Job $job
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
68 3 2632 664 29 0.36 1388 ccmsetup
749 22 21468 19940 203 122.13 3644 communicator
905 7 2980 2628 34 197.97 424 csrss
1121 25 28408 32940 174 430.14 3048 explorer
Verwenden Sie den Keep-Parameter , um zu verhindern Receive-Job
, dass die zurückgegebenen Auftragsergebnisse gelöscht werden. Die folgenden Befehle zeigen die Auswirkungen der Verwendung des Keep-Parameters auf einen Auftrag, der noch nicht abgeschlossen ist.
C:\PS> Receive-Job -Job $job -Keep
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
C:\PS> Receive-Job -Job $job -Keep
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
68 3 2632 664 29 0.36 1388 ccmsetup
749 22 21468 19940 203 122.13 3644 communicator
905 7 2980 2628 34 197.97 424 csrss
1121 25 28408 32940 174 430.14 3048 explorer
Warten auf die Ergebnisse
Wenn Sie einen Befehl ausführen, der lange dauert, können Sie die Eigenschaften des Auftragsobjekts verwenden, um zu bestimmen, wann der Auftrag abgeschlossen ist. Der folgende Befehl verwendet das Get-Job
-Objekt, um alle Hintergrundaufträge in der aktuellen Sitzung abzurufen.
Get-Job
Die Ergebnisse werden in einer Tabelle angezeigt. Die status des Auftrags wird in der Spalte Zustand angezeigt.
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Complete True localhost Get-Process
2 Job2 BackgroundJob Running True localhost Get-EventLog -Log ...
3 Job3 BackgroundJob Complete True localhost dir -Path C:\* -Re...
In diesem Fall zeigt die State-Eigenschaft an, dass Auftrag 2 weiterhin ausgeführt wird. Wenn Sie das Receive-Job
Cmdlet verwenden würden, um die Auftragsergebnisse jetzt abzurufen, wären die Ergebnisse unvollständig. Sie können das Receive-Job
Cmdlet wiederholt verwenden, um alle Ergebnisse abzurufen. Verwenden Sie die State-Eigenschaft , um zu bestimmen, wann der Auftrag abgeschlossen ist.
Sie können auch den Wait-Parameter des Receive-Job
Cmdlets verwenden. Wenn Sie diesen Parameter verwenden, gibt das Cmdlet die Eingabeaufforderung erst zurück, wenn der Auftrag abgeschlossen ist und alle Ergebnisse verfügbar sind.
Sie können das Wait-Job
Cmdlet auch verwenden, um auf ein oder alle Ergebnisse des Auftrags zu warten. Wait-Job
können Sie auf einen oder mehrere bestimmte Aufträge oder auf alle Aufträge warten.
Der folgende Befehl verwendet das Wait-Job
Cmdlet, um auf einen Auftrag mit der ID 10 zu warten.
Wait-Job -ID 10
Daher wird die PowerShell-Eingabeaufforderung unterdrückt, bis der Auftrag abgeschlossen ist.
Sie können auch einen vordefinierten Zeitraum warten. Dieser Befehl verwendet den Timeoutparameter , um die Wartezeit auf 120 Sekunden zu begrenzen. Wenn die Zeit abläuft, wird die Eingabeaufforderung zurückgegeben, aber der Auftrag wird weiterhin im Hintergrund ausgeführt.
Wait-Job -ID 10 -Timeout 120
Beenden eines Auftrags
Verwenden Sie das Stop-Job
Cmdlet, um einen Hintergrundauftrag zu beenden. Mit dem folgenden Befehl wird ein Auftrag gestartet, um jeden Eintrag im Systemereignisprotokoll abzurufen. Das Auftragsobjekt wird in der $job
Variablen gespeichert.
$job = Start-Job -ScriptBlock {Get-EventLog -Log System}
Der folgende Befehl beendet den Auftrag. Es verwendet einen Pipelineoperator (|
), um den Auftrag in der $job
Variablen an zu Stop-Job
senden.
$job | Stop-Job
Löschen eines Auftrags
Verwenden Sie das Remove-Job
Cmdlet, um einen Hintergrundauftrag zu löschen. Der folgende Befehl löscht den Auftrag in der $job
Variablen.
Remove-Job -Job $job
Untersuchen eines fehlgeschlagenen Auftrags
Aufträge können aus vielen Gründen fehlschlagen. das Auftragsobjekt enthält eine Reason-Eigenschaft , die Informationen zur Ursache des Fehlers enthält.
Im folgenden Beispiel wird ein Auftrag ohne die erforderlichen Anmeldeinformationen gestartet.
$job = Start-Job -ScriptBlock {New-Item -Path HKLM:\Software\MyCompany}
Get-Job $job
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Failed False localhost New-Item -Path HKLM:...
Überprüfen Sie die Reason-Eigenschaft , um den Fehler zu finden, der zum Fehlschlagen des Auftrags geführt hat.
$job.ChildJobs[0].JobStateInfo.Reason
In diesem Fall ist der Auftrag fehlgeschlagen, weil der Remotecomputer explizite Anmeldeinformationen benötigt, um den Befehl auszuführen. Die Reason-Eigenschaft enthält die folgende Meldung:
Fehler beim Herstellen einer Verbindung mit dem Remoteserver mit folgender Fehlermeldung: "Zugriff verweigert".