次の方法で共有


about_Remote_Jobs

簡単な説明

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

詳細な説明

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

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

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

重要

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

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

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

リモート ジョブ

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

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

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

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

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

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

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

  1. Enter-PSSession コマンドレットを使用して、リモート コンピューターとの対話型セッションを開始します。 Enter-PSSessionの ComputerName パラメーターを使用して、対話型セッションの一時的な接続を確立できます。 または、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 ファイルの内容をいつでも表示するには、別の対話型セッションを開始するか、リモート コマンドを実行します。 この種類のコマンドは、複数のコマンドを使用して 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 リモート処理を使用しないため、リモート処理用に構成されておらず、リモート処理の要件を満たしていないコンピューターでも使用できます。

  1. 次のコマンドでは、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 system
    

    AsJob パラメーターを使用すると、Invoke-Commandは、Start-Jobが返すのと同じ種類のジョブ オブジェクトを返します。 ジョブ オブジェクトを変数に保存することも、 Get-Job コマンドを使用してジョブを取得することもできます。

    Location プロパティの値は、ジョブが Server01 コンピューターで実行されたことを示しています。

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

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

    $results = Receive-Job -id 1
    

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

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

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

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

  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 変数に保存します。 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 セッションではありません。

関連項目