次の方法で共有


about_Remote_Jobs

簡単な説明

リモート コンピューターでバックグラウンド ジョブを実行する方法について説明します。

詳しい説明

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

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

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

重要

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

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

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

リモート ジョブ

リモート コンピューターでジョブを実行するには、3 つの異なる方法を使用します。

  • リモート コンピューターで対話型セッションを開始します。 次に、対話型セッションでジョブを開始します。 プロシージャはローカル ジョブの実行と同じですが、すべてのアクションはリモート コンピューターで実行されます。

  • 結果をローカル コンピューターに返すリモート コンピューターでジョブを実行します。 ジョブの結果を収集し、ローカル コンピューター上の中央の場所に保持する場合は、このメソッドを使用します。

  • リモート コンピューターで結果を保持するリモート コンピューターでジョブを実行します。 この方法は、ジョブ データが元のコンピューターでより安全に維持される場合に使用します。

対話型セッションでジョブを開始する

リモート コンピューターとの対話型セッションを開始し、対話型セッション中にジョブを開始できます。 対話型セッションの詳細については、「 about_Remote」および「」を参照してください Enter-PSSession

対話型セッションでジョブを開始する手順は、ローカル コンピューターでバックグラウンド ジョブを開始する手順とほぼ同じです。 ただし、すべての操作は、ローカル コンピューターではなくリモート コンピューターで行われます。

  1. コマンドレットを Enter-PSSession 使用して、リモート コンピューターとの対話型セッションを開始します。 の ComputerName パラメーター Enter-PSSession を使用して、対話型セッションの一時的な接続を確立できます。 または、Session パラメーターを使用して、PowerShell セッション (PSSession) で対話型セッションを実行できます。

    次のコマンドは、Server01 コンピューターで対話型セッションを開始します。

    C:\PS> Enter-PSSession -computername Server01
    

    コマンド プロンプトが変わり、Server01 コンピューターに接続されたことを示します。

    Server01\C:>
    
  2. セッションでリモート ジョブを開始するには、 コマンドレットを Start-Job 使用します。 次のコマンドは、Server01 コンピューター上の Windows PowerShell イベント ログ内のイベントを取得するリモート ジョブを実行します。 コマンドレットは Start-Job 、ジョブを表す オブジェクトを返します。

    このコマンドは、ジョブ オブジェクトを 変数に $job 保存します。

    Server01\C:> $job = Start-Job -scriptblock {
      Get-Eventlog "Windows PowerShell"
    }
    

    ジョブの実行中は、対話型セッションを使用して、他のジョブを含む他のコマンドを実行できます。 ただし、ジョブが完了するまで、対話型セッションを開いたままにする必要があります。 セッションを終了すると、ジョブは中断され、結果は失われます。

  3. ジョブが完了したかどうかを確認するには、変数の値を $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) で実行されているためです。

  4. ジョブの結果を取得するには、 コマンドレットを使用します Receive-Job 。 結果は対話型セッションで表示することも、リモート コンピューター上のファイルに保存することもできます。 次のコマンドは、$job変数内のジョブの結果を取得します。 このコマンドでは、リダイレクト演算子 (>) を使用して、Server01 コンピューター上の PsLog.txt ファイルにジョブの結果を保存します。

    Server01\C:> Receive-Job $job > c:\logs\PsLog.txt
    
  5. 対話型セッションを終了するには、 コマンドレットを使用します Exit-PSSession 。 コマンド プロンプトが変更され、ローカル コンピューター上の元のセッションに戻っていることを示します。

    Server01\C:> Exit-PSSession
    C:\PS>
    
  6. 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 パラメーターを使用すると、ジョブがリモート コンピューターで実行されている場合でも、ジョブ オブジェクトはローカル コンピューター上に実際に作成されます。 ジョブが完了すると、結果がローカル コンピューターに返されます。

Job 名詞 (Job コマンドレット) を含むコマンドレットを使用して、任意のコマンドレットによって作成されたすべてのジョブを管理できます。 AsJob パラメーターを持つコマンドレットの多くは PowerShell リモート処理を使用しないため、リモート処理用に構成されておらず、リモート処理の要件を満たしていないコンピューターでも使用できます。

  1. 次のコマンドでは、 の 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 コンピューターで実行されたことを示しています。

  2. コマンドレットの 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
    
  3. ジョブの結果を取得するには、 コマンドレットを使用します Receive-Job 。 ジョブの結果はジョブ オブジェクトが存在するコンピューターに自動的に返されるため、ローカル Receive-Job コマンドを使用して結果を取得できます。

    次のコマンドでは、 コマンドレットを Receive-Job 使用してジョブの結果を取得します。 セッション ID を使用してジョブを識別します。 このコマンドは、ジョブの結果を $results 変数に保存します。 結果をファイルにリダイレクトすることもできます。

    $results = Receive-Job -id 1
    

リモート コンピューターで結果を保持するリモート ジョブを開始する

リモート コンピューターでコマンドの結果を保持するリモート コンピューターでジョブを開始するには、 コマンドレットを Invoke-Command 使用してリモート コンピューターでコマンドを Start-Job 実行します。 このメソッドを使用すると、複数のコンピューターでジョブを実行できます。

コマンドをリモートで Start-Job 実行すると、ジョブ オブジェクトがリモート コンピューター上に作成され、ジョブの結果はリモート コンピューターで維持されます。 ジョブの観点から見ると、すべての操作はローカルです。 リモート コンピューターでローカル ジョブを管理するためのコマンドをリモートで実行しているだけです。

  1. コマンドレットを 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 します。 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 コンピューター上に作成され、ジョブは同じコンピューター上で実行されるため、ローカル バックグラウンド ジョブと見なされます。

  2. リモート ジョブを管理するには、 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
    
  3. ジョブの結果を取得するには、 コマンドレットを 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 セッションをCreateします。 このセッションでジョブを開始するための を使用 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 ではありません。

こちらもご覧ください