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 oder ThreadJob - 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 Isolierung. Alle 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 Remotingschicht erhöht jedoch den Aufwand, einschließlich objekt serialisieren. Alle Objekte werden serialisiert und deserialisiert, während sie zwischen der übergeordneten Sitzung und der Remotesitzung (Auftrag) übergeben werden. Die Serialisierung großer komplexer Datenobjekte kann große Mengen an Rechen- und Speicherressourcen verbrauchen 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 in 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 Aufwand. Sie verwenden nicht die Remotingschicht oder Serialisierung. Die Ergebnisobjekte werden als Verweise auf Liveobjekte in der aktuellen Sitzung zurückgegeben. Ohne diesen Aufwand werden threadbasierte Aufträge schneller ausgeführt und verwenden weniger Ressourcen als die anderen Auftragstypen.

Wichtig

Die übergeordnete Sitzung, die den Auftrag erstellt hat, überwacht auch den Auftragsstatus und sammelt Pipelinedaten. Der untergeordnete Auftragsvorgang wird vom übergeordneten Prozess beendet, sobald der Auftrag einen abgeschlossenen Zustand 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:

  1. Dient Invoke-Command zum Erstellen von Aufträgen, die in getrennten Sitzungen ausgeführt werden. Weitere Informationen finden Sie unter about_Remote_Jobs.
  2. Wird Start-Process verwendet, 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 - Stoppt 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 einen Invoke-Command beliebigen Auftragbefehl remote ausführen, einschließlich Start-Job.

So starten Sie einen Auftrag 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 ein, den der Auftrag in geschweiften geschweiften Klammern ({}) ausführt. Verwenden Sie den ScriptBlock-Parameter , um den Befehl anzugeben.

Der folgende Befehl startet einen Hintergrundauftrag, 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 der Auftrag eine längere Zeit für den Abschluss benötigt. 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, enthält aber nicht die Auftragsergebnisse.

Sie können das Auftragsobjekt in einer Variablen speichern und 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 im Hintergrundoperator.

Die Verwendung des Hintergrundoperators entspricht funktionell 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 werden alle Aufträge zurückgegeben, 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 ist. Ein abgeschlossener Auftrag weist den Status "Abgeschlossen " oder "Fehlgeschlagen" auf. Ein Auftrag kann auch blockiert oder ausgeführt werden.

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 ihn verwenden, um den Auftrag in einem späteren Befehl darzustellen. Der folgende Befehl ruft den Auftrag mit 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 Receive-Job Cmdlet, um die Ergebnisse eines Hintergrundauftrags 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. Mit dem folgenden Befehl werden die Ergebnisse des Auftrags in der $job Variablen in der $results Variablen gespeichert.

$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 werden alle Auftragsergebnisse angezeigt. Wenn der Auftrag noch ausgeführt wird, erhalten Sie die Ergebnisse, Receive-Job die bisher generiert wurden. Sie können Befehle erneut ausführen Receive-Job , um die verbleibenden Ergebnisse zu erhalten.

Löscht standardmäßig die Ergebnisse aus dem Cache, Receive-Job in dem Auftragsergebnisse gespeichert werden. Wenn Sie erneut ausgeführt werden 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 Parameter Keep , um zu verhindern Receive-Job , dass die zurückgegebenen Auftragsergebnisse gelöscht werden. Die folgenden Befehle zeigen die Auswirkung 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 eine lange Zeit 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. Der Status des Auftrags wird in der Spalte "Status" 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 noch 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 ermöglicht Es Ihnen, auf einen oder mehrere bestimmte Aufträge oder auf alle Aufträge zu warten. Der folgende Befehl verwendet das Wait-Job Cmdlet, um auf einen Auftrag mit ID 10 zu warten.

Wait-Job -ID 10

Daher wird die PowerShell-Eingabeaufforderung unterdrückt, bis der Auftrag abgeschlossen ist.

Sie können auch auf einen vordefinierten Zeitraum warten. Dieser Befehl verwendet den Timeout-Parameter , um die Wartezeit auf 120 Sekunden zu beschränken. Wenn die Zeit abläuft, gibt die Eingabeaufforderung zurück, 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}

Mit dem folgenden Befehl wird der Auftrag beendet. Es verwendet einen Pipelineoperator (|) zum Senden des Auftrags in der $job Variablen an Stop-Job.

$job | Stop-Job

Löschen eines Auftrags

Verwenden Sie das Remove-Job Cmdlet, um einen Hintergrundauftrag zu löschen. Mit dem folgenden Befehl wird der Auftrag in der $job Variablen gelöscht.

Remove-Job -Job $job

Untersuchen eines fehlgeschlagenen Auftrags

Aufträge können aus vielen Gründen fehlschlagen. das Auftragsobjekt eine Reason-Eigenschaft enthält, 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 dazu führte, dass der Auftrag fehlschlug.

$job.ChildJobs[0].JobStateInfo.Reason

In diesem Fall ist der Auftrag fehlgeschlagen, da der Remotecomputer explizite Anmeldeinformationen zum Ausführen des Befehls benötigt hat. Die Reason-Eigenschaft enthält die folgende Meldung:

Fehler beim Herstellen einer Verbindung mit dem Remoteserver mit der folgenden Fehlermeldung: "Der Zugriff wurde verweigert".

Siehe auch