about_Remote_Jobs
簡単な説明
リモート コンピューターでバックグラウンド ジョブを実行する方法について説明します。
詳細な説明
PowerShell は、ジョブを介してコマンドとスクリプトを同時に実行します。 同時実行をサポートするために、PowerShell によって提供されるジョブの種類は 3 つあります。
RemoteJob
- コマンドとスクリプトはリモート セッションで実行されます。BackgroundJob
- コマンドとスクリプトは、ローカル コンピューター上の別のプロセスで実行されます。 詳細については、「about_Jobs」を参照してください。PSTaskJob
またはThreadJob
- コマンドとスクリプトは、ローカル コンピューター上の同じプロセス内の別のスレッドで実行されます。 詳細については、「 about_Thread_Jobs」を参照してください。
スクリプトを別のコンピューターまたは別のプロセスでリモートで実行すると、分離性が高い。 リモート ジョブで発生したエラーは、実行中の他のジョブやジョブを開始した親セッションには影響しません。 ただし、リモート処理レイヤーでは、オブジェクトのシリアル化を含むオーバーヘッドが追加されます。 親セッションとリモート (ジョブ) セッションの間で渡されると、すべてのオブジェクトがシリアル化および逆シリアル化されます。 大規模な複雑なデータ オブジェクトのシリアル化では、大量のコンピューティングリソースとメモリ リソースが消費され、ネットワーク経由で大量のデータが転送される可能性があります。
重要
また、ジョブを作成した親セッションは、ジョブの状態を監視し、パイプライン データを収集します。 ジョブの子プロセスは、ジョブが完了した状態に達すると、親プロセスによって終了されます。 親セッションが終了すると、実行中のすべての子ジョブが子プロセスと共に終了します。
この状況を回避するには、次の 2 つの方法があります。
Invoke-Command
を使用して、切断されたセッションで実行されるジョブを作成します。 この記事の detached プロセス セクションを参照してください。Start-Process
を使用して、ジョブではなく新しいプロセスを作成します。 詳細については、「Start-Process」を参照してください。
リモート ジョブ
3 つの異なる方法を使用して、リモート コンピューターでジョブを実行できます。
リモート コンピューターで対話型セッションを開始します。 次に、対話型セッションでジョブを開始します。 プロシージャはローカル ジョブの実行と同じですが、すべてのアクションはリモート コンピューターで実行されます。
結果をローカル コンピューターに返すリモート コンピューターでジョブを実行します。 ジョブの結果を収集し、ローカル コンピューター上の中央の場所に保持する場合は、この方法を使用します。
リモート コンピューターで結果を維持するリモート コンピューターでジョブを実行します。 この方法は、ジョブ データが元のコンピューターでより安全に管理されている場合に使用します。
対話型セッションでジョブを開始する
リモート コンピューターとの対話型セッションを開始し、対話型セッション中にジョブを開始できます。 対話型セッションの詳細については、「 about_Remote」および「 Enter-PSSession
」を参照してください。
対話型セッションでジョブを開始する手順は、ローカル コンピューターでバックグラウンド ジョブを開始する手順とほぼ同じです。 ただし、すべての操作は、ローカル コンピューターではなく、リモート コンピューターで行われます。
Enter-PSSession
コマンドレットを使用して、リモート コンピューターとの対話型セッションを開始します。Enter-PSSession
の ComputerName パラメーターを使用して、対話型セッションの一時的な接続を確立できます。 または、Session パラメーターを使用して、PowerShell セッション (PSSession) で対話型セッションを実行できます。次のコマンドは、Server01 コンピューターで対話型セッションを開始します。
C:\PS> Enter-PSSession -computername Server01
コマンド プロンプトが変わり、Server01 コンピューターに接続されたことを示します。
Server01\C:>
セッションでリモート ジョブを開始するには、
Start-Job
コマンドレットを使用します。 次のコマンドは、Server01 コンピューター上の Windows PowerShell イベント ログのイベントを取得するリモート ジョブを実行します。Start-Job
コマンドレットは、ジョブを表すオブジェクトを返します。このコマンドは、ジョブ オブジェクトを
$job
変数に保存します。Server01\C:> $job = Start-Job -scriptblock { Get-Eventlog "Windows PowerShell" }
ジョブの実行中は、対話型セッションを使用して、他のジョブを含む他のコマンドを実行できます。 ただし、ジョブが完了するまで対話型セッションを開いたままにする必要があります。 セッションを終了すると、ジョブは中断され、結果は失われます。
ジョブが完了したかどうかを確認するには、
$job
変数の値を表示するか、Get-Job
コマンドレットを使用してジョブを取得します。 次のコマンドでは、Get-Job
コマンドレットを使用してジョブを表示します。Server01\C:> Get-Job $job SessionId Name State HasMoreData Location Command --------- ---- ----- ----------- -------- ------- 1 Job1 Complete True localhost Get-Eventlog "Windows...
Get-Job
出力は、ジョブが "localhost" コンピューターで実行されていることを示しています。これは、ジョブが開始され、同じコンピューター (この場合は Server01) で実行されているためです。ジョブの結果を取得するには、
Receive-Job
コマンドレットを使用します。 対話型セッションで結果を表示したり、リモート コンピューター上のファイルに保存したりできます。 次のコマンドは、$job変数内のジョブの結果を取得します。 このコマンドは、リダイレクト演算子 (>
) を使用して、Server01 コンピューター上のPsLog.txt ファイルにジョブの結果を保存します。Server01\C:> Receive-Job $job > c:\logs\PsLog.txt
対話型セッションを終了するには、
Exit-PSSession
コマンドレットを使用します。 コマンド プロンプトが変更され、ローカル コンピューター上の元のセッションに戻っていることを示します。Server01\C:> Exit-PSSession C:\PS>
Server01 コンピューター上の
PsLog.txt
ファイルの内容をいつでも表示するには、別の対話型セッションを開始するか、リモート コマンドを実行します。 この種類のコマンドは、複数のコマンドを使用してPsLog.txt
ファイル内のデータを調査および管理する場合に、PSSession (永続的な接続) で最適に実行されます。 PSSessions の詳細については、 about_PSSessionsを参照してください。次のコマンドでは、
New-PSSession
コマンドレットを使用して、Server01 コンピューターに接続された PSSession を作成し、Invoke-Command
コマンドレットを使用して PSSession でGet-Content
コマンドを実行してファイルの内容を表示します。$s = New-PSSession -computername Server01 Invoke-Command -session $s -scriptblock { Get-Content c:\logs\pslog.txt}
結果をローカル コンピューターに返すリモート ジョブを開始する (AsJob)
コマンドの結果をローカル コンピューターに返すリモート コンピューターでジョブを開始するには、Invoke-Command
コマンドレットなどのコマンドレットの AsJob パラメーターを使用します。
AsJob パラメーターを使用すると、ジョブがリモート コンピューターで実行されている場合でも、ジョブ オブジェクトはローカル コンピューター上に実際に作成されます。 ジョブが完了すると、結果がローカル コンピューターに返されます。
ジョブ名詞 (ジョブ コマンドレット) を含むコマンドレットを使用して、任意のコマンドレットによって作成されたすべてのジョブを管理できます。 AsJob パラメーターを持つコマンドレットの多くは PowerShell リモート処理を使用しないため、リモート処理用に構成されておらず、リモート処理の要件を満たしていないコンピューターでも使用できます。
次のコマンドでは、
Invoke-Command
の AsJob パラメーターを使用して、Server01 コンピューターでジョブを開始します。 ジョブは、システム ログ内のイベントを取得するGet-Eventlog
コマンドを実行します。 JobName パラメーターを使用して、ジョブに表示名を割り当てることができます。Invoke-Command -computername Server01 -scriptblock { Get-Eventlog system} -AsJob
コマンドの結果は、次の出力例のようになります。
SessionId Name State HasMoreData Location Command --------- ---- ----- ----------- -------- ------- 1 Job1 Running True Server01 Get-Eventlog system
AsJob パラメーターを使用すると、
Invoke-Command
は、Start-Job
が返すのと同じ種類のジョブ オブジェクトを返します。 ジョブ オブジェクトを変数に保存することも、Get-Job
コマンドを使用してジョブを取得することもできます。Location プロパティの値は、ジョブが Server01 コンピューターで実行されたことを示しています。
Invoke-Command
コマンドレットの AsJob パラメーターを使用して開始されたジョブを管理するには、Job コマンドレットを使用します。 リモート ジョブを表すジョブ オブジェクトはローカル コンピューター上にあるため、リモート コマンドを実行してジョブを管理する必要はありません。ジョブが完了したかどうかを確認するには、
Get-Job
コマンドを使用します。 次のコマンドは、現在のセッションで開始されたすべてのジョブを取得します。Get-Job
リモート ジョブは現在のセッションで開始されたため、ローカル
Get-Job
コマンドによってジョブが取得されます。 ジョブ オブジェクトの State プロパティは、コマンドが正常に完了したことを示します。SessionId Name State HasMoreData Location Command --------- ---- ----- ----------- -------- ------- 1 Job1 Completed True Server01 Get-Eventlog system
ジョブの結果を取得するには、
Receive-Job
コマンドレットを使用します。 ジョブの結果はジョブ オブジェクトが存在するコンピューターに自動的に返されるため、ローカルReceive-Job
コマンドを使用して結果を取得できます。次のコマンドでは、
Receive-Job
コマンドレットを使用してジョブの結果を取得します。 セッション ID を使用してジョブを識別します。 このコマンドは、ジョブの結果を $results 変数に保存します。 結果をファイルにリダイレクトすることもできます。$results = Receive-Job -id 1
リモート コンピューターで結果を保持するリモート ジョブを開始する
リモート コンピューターでコマンドの結果を保持するリモート コンピューターでジョブを開始するには、 Invoke-Command
コマンドレットを使用して、リモート コンピューターで Start-Job
コマンドを実行します。 このメソッドを使用して、複数のコンピューターでジョブを実行できます。
Start-Job
コマンドをリモートで実行すると、リモート コンピューターにジョブ オブジェクトが作成され、ジョブの結果がリモート コンピューターに保持されます。
ジョブの観点からは、すべての操作はローカルです。 リモート コンピューターでローカル ジョブを管理するコマンドをリモートで実行しているだけです。
リモート コンピューターで
Start-Job
コマンドを実行するには、Invoke-Command
コマンドレットを使用します。このコマンドには PSSession (永続的な接続) が必要です。
Invoke-Command
の ComputerName パラメーターを使用して一時的な接続を確立すると、ジョブ オブジェクトが返されるときに、Invoke-Command
コマンドは完了と見なされます。 その結果、一時的な接続が閉じられ、ジョブが取り消されます。次のコマンドでは、
New-PSSession
コマンドレットを使用して、Server01 コンピューターに接続されている PSSession を作成します。 このコマンドは、PSSession を$s
変数に保存します。$s = New-PSSession -computername Server01
次のコマンドでは、
Invoke-Command
コマンドレットを使用して PSSession でStart-Job
コマンドを実行します。Start-Job
コマンドとGet-Eventlog
コマンドは中かっこで囲まれています。Invoke-Command -session $s -scriptblock { Start-Job -scriptblock {Get-Eventlog system}}
結果は次のサンプル出力のようになります。
Id Name State HasMoreData Location Command -- ---- ----- ----------- -------- ------- 2 Job2 Running True Localhost Get-Eventlog system
Start-Job
コマンドをリモートで実行すると、Invoke-Command
は、Start-Job
が返すのと同じ種類のジョブ オブジェクトを返します。 ジョブ オブジェクトを変数に保存することも、Get-Job
コマンドを使用してジョブを取得することもできます。Location プロパティの値は、ジョブが Server01 コンピューターで実行された場合でも、ジョブがローカル コンピューター ("LocalHost" と呼ばれます) で実行されたことを示しています。 ジョブ オブジェクトは Server01 コンピューター上に作成され、ジョブは同じコンピューター上で実行されるため、ローカルのバックグラウンド ジョブと見なされます。
リモート ジョブを管理するには、 Job コマンドレットを使用します。 ジョブ オブジェクトはリモート コンピューター上にあるため、リモート コマンドを実行してジョブの結果を取得、停止、待機、または取得する必要があります。
ジョブが完了したかどうかを確認するには、
Invoke-Command
コマンドを使用して、Server01 コンピューターに接続されている PSSession でGet-Job
コマンドを実行します。Invoke-Command -session $s -scriptblock {Get-Job}
このコマンドによって返されるのは、ジョブ オブジェクトです。 ジョブ オブジェクトの State プロパティは、コマンドが正常に完了したことを示します。
SessionId Name State HasMoreData Location Command --------- ---- ----- ----------- -------- ------- 2 Job2 Completed True LocalHost Get-Eventlog system
ジョブの結果を取得するには、
Invoke-Command
コマンドレットを使用して、Server01 コンピューターに接続されている PSSession でReceive-Job
コマンドを実行します。次のコマンドでは、
Receive-Job
コマンドレットを使用してジョブの結果を取得します。 セッション ID を使用してジョブを識別します。 このコマンドは、ジョブの結果を$results
変数に保存します。Receive-Job
の Keep パラメーターを使用して、リモート コンピューター上のジョブ キャッシュに結果を保持します。$results = Invoke-Command -session $s -scriptblock { Receive-Job -SessionId 2 -Keep }
また、ローカル コンピューターまたはリモート コンピューター上のファイルに結果をリダイレクトすることもできます。 次のコマンドでは、リダイレクト演算子を使用して、結果を Server01 コンピューター上のファイルに保存します。
Invoke-Command -session $s -command { Receive-Job -SessionId 2 > c:\logs\pslog.txt }
デタッチされたプロセスとして実行する方法
前述のように、親セッションが終了すると、実行中のすべての子ジョブが子プロセスと共に終了します。 ローカル コンピューターでリモート処理を使用して、現在の PowerShell セッションにアタッチされていないジョブを実行できます。
ローカル コンピューターに新しい PowerShell セッションを作成します。 このセッションでジョブを開始する Invoke-Command
を使用します。 Invoke-Command
を使用すると、リモート セッションを切断し、親セッションを終了できます。 後で、新しい PowerShell セッションを開始し、以前に切断されたセッションに接続して、ジョブの監視を再開できます。 ただし、元の PowerShell セッションに返されたデータは、そのセッションが終了すると失われます。 再接続すると、切断後に生成された新しいデータ オブジェクトのみが返されます。
# Create remote session on local machine
PS> $session = New-PSSession -cn localhost
# Start remote job
PS> $job = Invoke-Command -Session $session -ScriptBlock { 1..60 | % { sleep 1; "Output $_" } } -AsJob
PS> $job
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 RemoteJob Running True localhost 1..60 | % { sleep 1; ...
# Disconnect the job session
PS> Disconnect-PSSession $session
Id Name Transport ComputerName ComputerType State ConfigurationName Availability
-- ---- --------- ------------ ------------ ----- ----------------- ------------
1 Runspace1 WSMan localhost RemoteMachine Disconnected Microsoft.PowerShell None
PS> $job
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 RemoteJob Disconnected True localhost 1..60 | % { sleep 1;
# Reconnect the session to a new job object
PS> $jobNew = Receive-PSSession -Session $session -OutTarget Job
PS> $job | Wait-Job | Receive-Job
Output 9
Output 10
Output 11
...
この例では、ジョブは引き続き親 PowerShell セッションにアタッチされます。
ただし、親セッションは、 Invoke-Command
が実行された元の PowerShell セッションではありません。
関連項目
PowerShell