about_Remote_Jobs
簡単な説明
リモート コンピューターでジョブを実行する方法について説明します。
詳細な説明
PowerShell は、ジョブを介してコマンドとスクリプトを同時に実行します。 同時実行をサポートするために、PowerShell によって提供されるジョブの種類は 3 つあります。
RemoteJob
- コマンドとスクリプトはリモート セッションで実行されます。BackgroundJob
- コマンドとスクリプトは、ローカル コンピューター上の別のプロセスで実行されます。 詳細については、「about_Jobs」を参照してください。PSTaskJob
またはThreadJob
- コマンドとスクリプトは、ローカル コンピューター上の同じプロセス内の別のスレッドで実行されます。 詳細については、「about_Thread_Jobs」を参照してください。
スクリプトを別のコンピューターまたは別のプロセスでリモートで実行すると、分離性が高い。 リモート ジョブで発生したエラーは、実行中の他のジョブやジョブを開始した親セッションには影響しません。 ただし、リモート処理レイヤーでは、オブジェクトのシリアル化を含むオーバーヘッドが追加されます。 親セッションとリモート (ジョブ) セッションの間で渡されると、すべてのオブジェクトがシリアル化および逆シリアル化されます。 大規模な複雑なデータ オブジェクトのシリアル化では、大量のコンピューティングリソースとメモリ リソースが消費され、ネットワーク経由で大量のデータが転送される可能性があります。
重要
また、ジョブを作成した親セッションは、ジョブの状態を監視し、パイプライン データを収集します。 ジョブの子プロセスは、ジョブが完了した状態に達すると、親プロセスによって終了されます。 親セッションが終了すると、実行中のすべての子ジョブが子プロセスと共に終了します。
この状況を回避するには、次の 2 つの方法があります。
- 切断されたセッションで実行されるジョブを作成するために使用
Invoke-Command
します。 この記事の デタッチされたプロセス のセクションを参照してください。 - ジョブではなく新しいプロセスを作成するために使用
Start-Process
します。 詳細については、「Start-Process」を参照してください。
リモート ジョブ
3 つの異なる方法を使用して、リモート コンピューターでジョブを実行できます。
リモート コンピューターで対話型セッションを開始します。 次に、対話型セッションでジョブを開始します。 プロシージャはローカル ジョブの実行と同じですが、すべてのアクションはリモート コンピューターで実行されます。
結果をローカル コンピューターに返すリモート コンピューターでジョブを実行します。 ジョブの結果を収集し、ローカル コンピューター上の中央の場所にメインする場合は、このメソッドを使用します。
リモート コンピューターで結果をメインするリモート コンピューターでジョブを実行します。 この方法は、ジョブ データが元のコンピューターにメイン安全に保存されている場合に使用します。
対話型セッションでジョブを開始する
リモート コンピューターとの対話型セッションを開始し、対話型セッション中にジョブを開始できます。 対話型セッションの詳細については、「 about_Remote」を参照してください Enter-PSSession
。
対話型セッションでジョブを開始する手順は、ローカル コンピューターでバックグラウンド ジョブを開始する手順とほぼ同じです。 ただし、すべての操作は、ローカル コンピューターではなく、リモート コンピューターで行われます。
コマンドレットを
Enter-PSSession
使用して、リモート コンピューターとの対話型セッションを開始します。 ComputerName パラメーターEnter-PSSession
を使用して、対話型セッションの一時的な接続を確立できます。 または、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
開始され、同じコンピューター (この場合は Server01) で実行されているため、ジョブが "localhost" コンピューターで実行されていることが出力に示されます。ジョブの結果を取得するには、コマンドレットを
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
内容をいつでも表示するには、別の対話型セッションを開始するか、リモート コマンドを実行します。 この種類のコマンドは、ファイル内のデータを調査および管理するために複数のコマンドを使用する場合に、PSSession (永続的な接続) で最適にPsLog.txt
実行されます。 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)
コマンドの結果をローカル コンピューターに返すリモート コンピューターでジョブを開始するには、コマンドレットなどのコマンドレットの AsJob パラメーターをInvoke-Command
使用します。
AsJob パラメーターを使用すると、ジョブがリモート コンピューターで実行されている場合でも、ジョブ オブジェクトはローカル コンピューターに実際に作成されます。 ジョブが完了すると、結果がローカル コンピューターに返されます。
ジョブ名詞 (ジョブ コマンドレット) を含むコマンドレットを使用して、任意のコマンドレットによって作成されたすべてのジョブを管理できます。 AsJob パラメーターを持つコマンドレットの多くは PowerShell リモート処理を使用しないため、リモート処理用に構成されておらず、リモート処理の要件を満たしていないコンピューターでも使用できます。
次のコマンドでは、 AsJob パラメーター
Invoke-Command
を使用して 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 コンピューターで実行されたことを示しています。
コマンドレットの AsJob パラメーターを使用して開始されたジョブを
Invoke-Command
管理するには、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
リモートで実行すると、リモート コンピューターにジョブ オブジェクトが作成され、ジョブの結果がリモート コンピューターにメインされます。
ジョブの観点からは、すべての操作はローカルです。 リモート コンピューターでローカル ジョブを管理するコマンドをリモートで実行しているだけです。
コマンドレットを
Invoke-Command
使用して、Start-Job
リモート コンピューターでコマンドを実行します。このコマンドには PSSession (永続的な接続) が必要です。 ComputerName パラメーター
Invoke-Command
を使用して一時的な接続を確立すると、Invoke-Command
ジョブ オブジェクトが返されるときにコマンドが完了したと見なされます。 その結果、一時的な接続が閉じられ、ジョブが取り消されます。次のコマンドでは、このコマンドレットを
New-PSSession
使用して、Server01 コンピューターに接続されている PSSession を作成します。 このコマンドは、PSSession を変数に$s
保存します。$s = New-PSSession -computername Server01
次のコマンドでは、コマンドレットを
Invoke-Command
使用して PSSession でコマンドを実行Start-Job
します。 コマンドとGet-Eventlog
コマンドはStart-Job
中かっこで囲まれています。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 コンピューター上に作成され、ジョブは同じコンピューター上で実行されるため、ローカルのバックグラウンド ジョブと見なされます。
リモート ジョブを管理するには、ジョブ コマンドレットを使用します。 ジョブ オブジェクトはリモート コンピューター上にあるため、リモート コマンドを実行してジョブの結果を取得、停止、待機、または取得する必要があります。
ジョブが完了したかどうかを確認するには、Server01 コンピューターに接続されている PSSession でコマンドを実行
Get-Job
するコマンドを使用Invoke-Command
します。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
保存します。 Keep パラメーターReceive-Job
を使用して、リモート コンピューター上のジョブ キャッシュに結果を保持します。$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 セッションにアタッチされます。
ただし、親セッションは、実行された元の PowerShell セッション Invoke-Command
ではありません。
関連項目
PowerShell