about_Jobs

簡単な説明

PowerShell バックグラウンド ジョブが、現在のセッションと対話せずにバックグラウンドでコマンドまたは式を実行する方法に関する情報を提供します。

詳細な説明

PowerShell は、ジョブを介してコマンドとスクリプトを同時に実行します。 同時実行をサポートするために、PowerShell によって提供されるジョブの種類は 3 つあります。

  • RemoteJob - コマンドとスクリプトはリモート セッションで実行されます。 詳細については、about_Remote_Jobsを参照してください
  • BackgroundJob - コマンドとスクリプトは、ローカル コンピューター上の別のプロセスで実行されます。
  • PSTaskJob または ThreadJob - コマンドとスクリプトは、ローカル コンピューター上の同じプロセス内の別のスレッドで実行されます。 詳細については、「about_Thread_Jobs」を参照してください

スクリプトを別のコンピューターまたは別のプロセスでリモートで実行すると、優れた分離性が提供されます。 リモート ジョブで発生したエラーは、実行中の他のジョブや、ジョブを開始した親セッションには影響しません。 ただし、リモート処理レイヤーでは、オブジェクトのシリアル化を含むオーバーヘッドが追加されます。 親セッションとリモート (ジョブ) セッションの間で渡されると、すべてのオブジェクトがシリアル化および逆シリアル化されます。 大規模な複雑なデータ オブジェクトのシリアル化では、大量のコンピューティングリソースとメモリ リソースが消費され、ネットワーク経由で大量のデータが転送される可能性があります。

スレッド ベースのジョブは、異なるスレッドで同じプロセスで実行されるため、リモート ジョブやバックグラウンド ジョブほど堅牢ではありません。 1 つのジョブでプロセスがクラッシュする重大なエラーが発生した場合、プロセス内の他のすべてのジョブが終了します。

ただし、スレッド ベースのジョブのオーバーヘッドは少なくなります。 リモート処理レイヤーやシリアル化は使用しません。 結果オブジェクトは、現在のセッションのライブ オブジェクトへの参照として返されます。 このオーバーヘッドがなければ、スレッドベースのジョブの実行速度が速くなり、他のジョブの種類よりも使用するリソースが少なくなります。

重要

また、ジョブを作成した親セッションは、ジョブの状態を監視し、パイプライン データを収集します。 ジョブの子プロセスは、ジョブが完了した状態に達すると、親プロセスによって終了されます。 親セッションが終了すると、実行中のすべての子ジョブが子プロセスと共に終了します。

この状況を回避するには、次の 2 つの方法があります。

  1. 切断されたセッションで実行されるジョブを作成するために使用 Invoke-Command します。 詳細については、「about_Remote_Jobs」を参照してください
  2. ジョブではなく新しいプロセスを作成するために使用 Start-Process します。 詳細については、「Start-Process」を参照してください。

ジョブ コマンドレット

  • Start-Job - ローカル コンピューターでバックグラウンド ジョブを開始します。
  • Get-Job - 現在のセッションで開始されたバックグラウンド ジョブを取得します。
  • Receive-Job - バックグラウンド ジョブの結果を取得します。
  • Stop-Job - バックグラウンド ジョブを停止します。
  • Wait-Job - 1 つまたはすべてのジョブが完了するまで、コマンド プロンプトを抑制します。
  • Remove-Job - バックグラウンド ジョブを削除します。
  • Invoke-Command- AsJob パラメーターは、リモート コンピューターにバックグラウンド ジョブを作成します。 を含むStart-Job任意のジョブ コマンドをリモートで実行するために使用Invoke-Commandできます。

ローカル コンピューターでジョブを開始する方法

ローカル コンピューターでバックグラウンド ジョブを開始するには、コマンドレットを Start-Job 使用します。

コマンドを Start-Job 記述するには、ジョブが実行するコマンドを中かっこ ({}) で囲みます。 ScriptBlock パラメーターを使用してコマンドを指定します。

次のコマンドは、ローカル コンピューターでコマンドを Get-Process 実行するバックグラウンド ジョブを開始します。

Start-Job -ScriptBlock {Get-Process}

バックグラウンド ジョブを開始すると、ジョブの完了に時間がかかる場合でも、コマンド プロンプトはすぐに返されます。 ジョブの実行中は、中断されることなく引き続きセッションで作業できます。

このコマンドは Start-Job 、ジョブを表すオブジェクトを返します。 ジョブ オブジェクトにはジョブに関する有用な情報が含まれていますが、ジョブの結果は含まれません。

ジョブ オブジェクトを変数に保存し、他 の Job コマンドレットと共に使用してバックグラウンド ジョブを管理できます。 次のコマンドは、ジョブ オブジェクトを開始し、結果のジョブ オブジェクトを変数に $job 保存します。

$job = Start-Job -ScriptBlock {Get-Process}

PowerShell 6.0 以降では、パイプラインの末尾にあるバックグラウンド演算子 (&) を使用してバックグラウンド ジョブを開始できます。 詳細については、バックグラウンド演算子を参照してください

バックグラウンド演算子の使用は、前の例のコマンドレットの Start-Job 使用と機能的に同等です。

$job = Get-Process &

ジョブ オブジェクトの取得

コマンドレットは Get-Job 、現在のセッションで開始されたバックグラウンド ジョブを表すオブジェクトを返します。 パラメーターを指定しない場合は、 Get-Job 現在のセッションで開始されたすべてのジョブを返します。

Get-Job

ジョブ オブジェクトには、ジョブが終了したかどうかを示すジョブの状態が含まれています。 完了したジョブの状態 が [完了] または [失敗] です。 ジョブがブロックまたは実行中である場合もあります。

Id  Name  PSJobTypeName State      HasMoreData  Location   Command
--  ----  ------------- -----      -----------  --------   -------
1   Job1  BackgroundJob Complete   True         localhost  Get-Process

ジョブ オブジェクトを変数に保存し、それを使用して後のコマンドでジョブを表すことができます。 次のコマンドは、ID 1 のジョブを取得し、変数に $job 保存します。

$job = Get-Job -Id 1

ジョブの結果の取得

バックグラウンド ジョブを実行すると、結果はすぐには表示されません。 バックグラウンド ジョブの結果を取得するには、コマンドレットを Receive-Job 使用します。

次の例では、コマンドレットは Receive-Job 、変数内のジョブ オブジェクトを使用してジョブの結果を $job 取得します。

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
...

ジョブの結果を変数に保存できます。 次のコマンドは、ジョブの結果を変数$results$job保存します。

$results = Receive-Job -Job $job

部分的なジョブ結果の取得と保持

このコマンドレットは Receive-Job 、バックグラウンド ジョブの結果を取得します。 ジョブが完了した場合は、 Receive-Job すべてのジョブ結果を取得します。 ジョブがまだ実行されている場合は、 Receive-Job これまでに生成された結果を取得します。 コマンドをもう一度実行Receive-Jobして、再メイン結果を取得できます。

既定では、 Receive-Job ジョブの結果が格納されているキャッシュから結果を削除します。 再度実行すると、最初の実行 Receive-Job 後に到着した新しい結果のみが取得されます。

次のコマンドは、ジョブが完了する前に実行されたコマンドの Receive-Job 結果を示しています。

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

Keep パラメーターを使用して、返されるジョブの結果が削除されないようにReceive-Jobします。 次のコマンドは、まだ完了していないジョブで Keep パラメーターを使用した場合の効果を示しています。

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

結果を待機しています

完了に時間がかかるコマンドを実行する場合は、ジョブ オブジェクトのプロパティを使用して、ジョブが完了したタイミングを判断できます。 次のコマンドでは、オブジェクトを Get-Job 使用して、現在のセッションのすべてのバックグラウンド ジョブを取得します。

Get-Job

結果はテーブルに表示されます。 ジョブの状態が [状態] 列に表示されます。

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...

この場合、State プロパティはジョブ 2 がまだ実行されていることを示します。 コマンドレットを使用 Receive-Job してジョブの結果を今すぐ取得する場合、結果は不完全になります。 コマンドレットを Receive-Job 繰り返し使用して、すべての結果を取得できます。 State プロパティを使用して、ジョブが完了したタイミングを確認します。

コマンドレットの Wait パラメーターを Receive-Job 使用することもできます。 このパラメーターを使用すると、ジョブが完了し、すべての結果が使用可能になるまで、コマンドレットはコマンド プロンプトを返しません。

コマンドレットを Wait-Job 使用して、ジョブの結果の一部またはすべてを待機することもできます。 Wait-Job では、1 つ以上の特定のジョブまたはすべてのジョブを待機できます。 次のコマンドでは、コマンドレットをWait-Job使用して ID 10 のジョブを待機します。

Wait-Job -ID 10

その結果、PowerShell プロンプトはジョブが完了するまで抑制されます。

また、所定の期間待機することもできます。 このコマンドでは、Timeout パラメーターを使用して待機を 120 秒に制限します。 時間が経過すると、コマンド プロンプトが返されますが、ジョブはバックグラウンドで引き続き実行されます。

Wait-Job -ID 10 -Timeout 120

ジョブの停止

バックグラウンド ジョブを停止するには、コマンドレットを Stop-Job 使用します。 次のコマンドは、システム イベント ログ内のすべてのエントリを取得するジョブを開始します。 ジョブ オブジェクトを変数に $job 保存します。

$job = Start-Job -ScriptBlock {Get-EventLog -Log System}

次のコマンドはジョブを停止します。 パイプライン演算子 (|) を使用して変数内$jobStop-Jobのジョブを送信します。

$job | Stop-Job

ジョブの削除

バックグラウンド ジョブを削除するには、コマンドレットを Remove-Job 使用します。 次のコマンドは、変数内のジョブを $job 削除します。

Remove-Job -Job $job

失敗したジョブの調査

ジョブは、さまざまな理由で失敗する可能性があります。 ジョブ オブジェクトには、エラーの 原因に関する情報を含む Reason プロパティが含まれています。

次の例では、必要な資格情報なしでジョブを開始します。

$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:...

Reason プロパティを調べて、ジョブの失敗の原因となったエラーを見つけます。

$job.ChildJobs[0].JobStateInfo.Reason

この場合、リモート コンピューターでコマンドを実行するために明示的な資格情報が必要なため、ジョブは失敗しました。 Reason プロパティには、次のメッセージが含まれています。

リモート サーバーへの接続が失敗し、"アクセスが拒否されました" というエラー メッセージが表示されました。

関連項目