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 開始され、同じコンピューター (この場合は Server01) で実行されているため、ジョブが "localhost" コンピューターで実行されていることが出力に示されます。

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

ジョブ名詞 (ジョブ コマンドレット) を含むコマンドレットを使用して、任意のコマンドレットによって作成されたすべてのジョブを管理できます。 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 します。 コマンドと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 コンピューター上に作成され、ジョブは同じコンピューター上で実行されるため、ローカルのバックグラウンド ジョブと見なされます。

  2. リモート ジョブを管理するには、ジョブ コマンドレットを使用します。 ジョブ オブジェクトはリモート コンピューター上にあるため、リモート コマンドを実行してジョブの結果を取得、停止、待機、または取得する必要があります。

    ジョブが完了したかどうかを確認するには、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
    
  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 セッションを作成します。 このセッションでジョブを開始するために使用 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 ではありません。

関連項目