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コマンドレットを使用して、リモートコンピューターとの対話型セッションを開始します。 のEnter-PSSessionComputerName パラメーターを使用して、対話型セッションの一時的な接続を確立できます。 または、Session パラメーターを使用して、PowerShell セッション (PSSession) で対話型セッションを実行できます。次のコマンドは、Server01 コンピューター上で対話型セッションを開始します。
C:\PS> Enter-PSSession -computername Server01Server01 コンピューターに接続されていることを示すために、コマンドプロンプトが変更されます。
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 パラメーターを使用すると、ジョブがリモートコンピューター上で実行されている場合でも、ジョブオブジェクトは実際にはローカルコンピューター上に作成されます。 ジョブが完了すると、結果がローカルコンピューターに返されます。
ジョブの名詞を含むコマンドレット (Job コマンドレット) を使用して、任意のコマンドレットによって作成されたすべてのジョブを管理できます。 AsJob パラメーターを持つコマンドレットの多くは、PowerShell リモート処理を使用しないので、リモート処理用に構成されておらず、リモート処理の要件を満たしていないコンピューターでも使用できます。
次のコマンドでは、の
Invoke-CommandAsJob パラメーターを使用して、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 systemAsJob パラメーターが使用されている場合、は
Invoke-Commandを返すのと同じ種類のジョブオブジェクトStart-Jobを返します。 ジョブオブジェクトを変数に保存することも、コマンドをGet-Job使用してジョブを取得することもできます。Location プロパティの値は、Server01 コンピューターでジョブが実行されたことを示しています。
コマンドレットの
Invoke-CommandAsJob パラメーターを使用して開始されたジョブを管理するには、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 (永続的な接続) が必要です。 の
Invoke-CommandComputerName パラメーターを使用して一時的な接続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 コンピューター上に作成され、ジョブは同じコンピューター上で実行されるため、ローカルのバックグラウンドジョブと見なされます。
リモートジョブを管理するには、 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-JobKeep パラメーターを使用して、リモートコンピューター上のジョブキャッシュに結果を保持します。$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 ではありません。
関連項目
フィードバック
フィードバックの送信と表示