about_Remote_Jobs

簡短描述

描述如何在遠端電腦上執行作業。

詳細描述

PowerShell 會透過作業同時執行命令和腳本。 PowerShell 提供的作業類型有三種,可支援並行。

  • RemoteJob - 命令和文稿會在遠程會話中執行。
  • BackgroundJob - 命令和文稿會在本機計算機上的個別進程中執行。 如需詳細資訊,請參閱 about_Jobs
  • PSTaskJobThreadJob - 命令和文稿會在本機計算機上相同進程的個別線程中執行。 如需詳細資訊,請參閱 about_Thread_Jobs

從遠端執行文本,在個別的計算機上或在個別進程中,提供絕佳的隔離。 遠端作業中發生的任何錯誤都不會影響其他執行中作業或啟動作業的父會話。 不過,遠端層會增加額外負荷,包括物件串行化。 所有物件都會在父會話與遠端 (job) 工作階段之間傳遞時串行化和還原串行化。 大型複雜數據物件的串行化可能會耗用大量的計算和記憶體資源,並跨網路傳輸大量數據。

重要

建立作業的父會話也會監視作業狀態並收集管線數據。 作業子進程會在作業達到完成狀態后,由父進程終止。 如果父會話終止,則所有執行中的子作業都會連同其子進程一起終止。

有兩種方式可解決這種情況:

  1. 用來 Invoke-Command 建立在中斷聯機會話中執行的作業。 請參閱本文的 中斷連結程式 一節。
  2. 使用 Start-Process 來建立新的進程,而不是作業。 如需詳細資訊,請參閱 Start-Process

遠端作業

您可以使用三種不同的方法,在遠端電腦上執行作業。

  • 在遠端電腦上啟動互動式會話。 然後在互動式會話中啟動作業。 雖然所有動作都是在遠端電腦上執行,但程式與執行本機作業相同。

  • 在遠端電腦上執行作業,將結果傳回至本機電腦。 當您想要收集作業的結果,並將其保留在本機計算機上的中央位置時,請使用此方法。

  • 在遠端電腦上執行作業,以在遠端電腦上維護其結果。 在原始電腦上更安全地維護作業數據時,請使用此方法。

在互動式會話中啟動作業

您可以使用遠端電腦啟動互動式會話,然後在互動式會話期間啟動作業。 如需互動式工作階段的詳細資訊,請參閱 about_Remote,請參閱 Enter-PSSession

在互動式會話中啟動作業的程式幾乎與在本機計算機上啟動背景工作的程式完全相同。 不過,所有作業都會發生在遠端電腦上,而不是本機計算機。

  1. Enter-PSSession使用 Cmdlet 來啟動遠端電腦的互動式作業階段。 您可以使用的 Enter-PSSession ComputerName 參數來建立互動式工作階段的暫時連線。 或者,您可以使用 Session 參數在 PowerShell 會話中執行互動式會話(PSSession)。

    下列命令會在 Server01 計算機上啟動互動式工作階段。

    C:\PS> Enter-PSSession -computername Server01
    

    命令提示字元會變更,以顯示您現在已連線到 Server01 計算機。

    Server01\C:>
    
  2. 若要在會話中啟動遠端作業,請使用 Start-Job Cmdlet。 下列命令會執行遠端作業,以取得 Server01 電腦上的 Windows PowerShell 事件記錄檔中的事件。 Cmdlet 會 Start-Job 傳回代表作業的物件。

    此命令會將作業物件儲存在變數中 $job

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

    當作業執行時,您可以使用互動式會話來執行其他命令,包括其他作業。 不過,您必須讓互動式會話保持開啟,直到作業完成為止。 如果您結束會話,作業會中斷,結果會遺失。

  3. 若要了解作業是否已完成,請顯示變數的值 $job ,或使用 Get-Job Cmdlet 來取得作業。 下列命令會 Get-Job 使用 Cmdlet 來顯示作業。

    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 Cmdlet。 您可以在互動式會話中顯示結果,或將它們儲存至遠端電腦上的檔案。 下列命令會取得 $job 變數中作業的結果。 此命令會使用重新導向運算符 (>) 將作業的結果儲存在 Server01 電腦上的 PsLog.txt 檔案中。

    Server01\C:> Receive-Job $job > c:\logs\PsLog.txt
    
  5. 若要結束互動式會話,請使用 Exit-PSSession Cmdlet。 命令提示字元會變更,以顯示您回到本機電腦上的原始會話。

    Server01\C:> Exit-PSSession
    C:\PS>
    
  6. 若要隨時檢視 Server01 計算機上的檔案內容 PsLog.txt ,請啟動另一個互動式會話,或執行遠端命令。 如果您想要使用數個命令來調查和管理檔案中的數據 PsLog.txt ,這種命令最好在 PSSession 中執行(持續性連線)。 如需 PSSessions 的詳細資訊,請參閱 about_PSSessions

    下列命令會 New-PSSession 使用 Cmdlet 來建立 連接到 Server01 計算機的 PSSession ,並使用 Invoke-Command Cmdlet 在 PSSession 中執行 Get-Content 命令來檢視檔案的內容。

    $s = New-PSSession -computername Server01
    Invoke-Command -session $s -scriptblock {
      Get-Content c:\logs\pslog.txt}
    

啟動遠端作業,將結果傳回至本機電腦 (AsJob)

若要在將命令結果傳回至本機計算機的遠端電腦上啟動作業,請使用 Cmdlet 的 AsJob 參數,例如 Invoke-Command Cmdlet。

當您使用 AsJob 參數時,即使作業是在遠端電腦上執行,仍會在本機電腦上實際建立作業物件。 當作業完成時,結果會傳回至本機計算機。

您可以使用包含 Job 名詞 (Job Cmdlet) 的 Cmdlet 來管理任何 Cmdlet 所建立的任何作業。 許多具有 AsJob 參數的 Cmdlet 都未使用 PowerShell 遠端功能,因此您甚至可以在未設定遠端處理且不符合遠端處理需求的電腦上使用它們。

  1. 下列命令會使用Invoke-Command AsJob 參數,在 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. 若要使用 Cmdlet 的 AsJob 參數來管理啟動的 Invoke-Command 作業,請使用 Job Cmdlet。 因為代表遠端作業的作業對象位於本機電腦上,因此您不需要執行遠端命令來管理作業。

    若要判斷作業是否完成,請使用 Get-Job 命令。 下列命令會取得目前會話中啟動的所有作業。

    Get-Job
    

    由於遠端作業已在目前的會話中啟動,因此本機 Get-Job 命令會取得作業。 作業物件的 State 屬性會顯示命令已順利完成。

    SessionId   Name   State      HasMoreData   Location   Command
    ---------   ----   -----      -----------   --------   -------
    1           Job1   Completed  True          Server01   Get-Eventlog system
    
  3. 若要取得作業的結果,請使用 Receive-Job Cmdlet。 由於作業結果會自動傳回至作業物件所在的計算機,因此您可以使用本機 Receive-Job 命令取得結果。

    下列命令會 Receive-Job 使用 Cmdlet 來取得作業的結果。 它會使用會話標識碼來識別作業。 此命令會將作業結果儲存在 $results 變數中。 您也可以將結果重新導向至檔案。

    $results = Receive-Job -id 1
    

啟動遠端作業,以在遠端電腦上保留結果

若要在遠端電腦上啟動讓命令結果保持在遠端電腦上的作業,請使用 Invoke-Command Cmdlet 在遠端電腦上執行 Start-Job 命令。 您可以使用此方法在多部電腦上執行作業。

當您從遠端執行 Start-Job 命令時,會在遠端電腦上建立作業物件,並在遠端電腦上維護作業結果。 從作業的觀點來看,所有作業都是本機作業。 您只是在遠端執行命令,以管理遠端電腦上的本機作業。

  1. Invoke-Command使用 Cmdlet 在遠端電腦上執行Start-Job命令。

    此命令需要 PSSession (持續性連線)。 如果您使用的 Invoke-Command ComputerName 參數來建立暫存連接, Invoke-Command 則會在傳回作業物件時將命令視為完成。 因此,暫時連接已關閉,並取消作業。

    下列命令會 New-PSSession 使用 Cmdlet 來建立連線到 Server01 計算機的 PSSession。 命令會將 PSSession 儲存在 變數中 $s

    $s = New-PSSession -computername Server01
    

    下一個Start-Job命令會Invoke-Command使用 Cmdlet 在 PSSession 中執行命令。 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 屬性的值會顯示作業在本機計算機上執行,稱為 「LocalHost」,即使作業在 Server01 計算機上執行也一樣。 由於作業物件是在 Server01 計算機上建立,而且作業會在相同電腦上執行,因此會被視為本機背景工作。

  2. 若要管理遠端作業,請使用 Job Cmdlet。 因為作業物件位於遠端電腦上,您必須執行遠端命令,以取得、停止、等候或擷取作業結果。

    若要查看作業是否完成,請使用 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 Cmdlet 在連接到 Server01 計算機的 PSSession 中執行 Receive-Job 命令。

    下列命令會 Receive-Job 使用 Cmdlet 來取得作業的結果。 它會使用會話標識碼來識別作業。 此命令會將作業結果儲存在變數中 $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會話。

另請參閱