關於遠端作業
簡短描述
描述如何在遠端電腦上執行作業。
詳細描述
PowerShell 會透過作業同時執行命令和腳本。 PowerShell 提供的作業類型有三種,可支援並行存取。
RemoteJob
- 命令和文稿會在遠程會話中執行。BackgroundJob
- 命令和文稿會在本機計算機上的個別進程中執行。 如需詳細資訊,請參閱 about_Jobs。PSTaskJob
或ThreadJob
- 命令和文稿會在本機計算機上相同進程的個別線程中執行。 如需詳細資訊,請參閱 about_Thread_Jobs。
從遠端執行腳本,在個別機器或個別程式中,提供絕佳的隔離。 遠端作業中發生的任何錯誤都不會影響其他執行中作業或啟動作業的父會話。 不過,遠端層會增加額外負荷,包括物件串行化。 所有物件都會串行化和還原串行化,因為它們會在父會話與遠端 (作業之間傳遞) 會話。 串行化大型複雜數據物件可能會耗用大量的計算和記憶體資源,並跨網路傳輸大量數據。
重要
建立作業的父會話也會監視作業狀態並收集管線數據。 當作業達到完成狀態時,父進程就會終止作業子進程。 如果父會話終止,所有執行中的子作業都會與其子進程一起終止。
有兩種方式可以解決此問題:
- 用來
Invoke-Command
建立在中斷聯機會話中執行的作業。 請參閱本文的 中斷連結處理程式 一節。 - 使用
Start-Process
來建立新的進程,而不是作業。 如需詳細資訊,請參閱 Start-Process。
遠端作業
您可以使用三種不同的方法,在遠端電腦上執行作業。
在遠端電腦上啟動互動式會話。 然後在互動式會話中啟動作業。 雖然所有動作都是在遠端電腦上執行,但程式與執行本機作業相同。
在遠端電腦上執行作業,將結果傳回至本機電腦。 當您想要收集作業的結果,並將其維護在本機電腦上的中央位置時,請使用此方法。
在遠端電腦上執行作業,以在遠端電腦上維護其結果。 在原始電腦上更安全地維護作業數據時,請使用這個方法。
在互動式會話中啟動作業
您可以使用遠端電腦啟動互動式會話,然後在互動式會話期間啟動作業。 如需互動式工作階段的詳細資訊,請參閱about_Remote,請參閱 Enter-PSSession
。
在互動式會話中啟動作業的程式幾乎與在本機計算機上啟動背景工作的程式完全相同。 不過,所有作業都會發生在遠端電腦上,而不是本機計算機。
Enter-PSSession
使用 Cmdlet 來啟動與遠端電腦的互動式作業階段。 您可以使用的Enter-PSSession
ComputerName 參數來建立互動式工作階段的暫時連線。 或者,您可以使用 Session 參數在 PowerShell 會話中執行互動式會話, (PSSession) 。下列命令會在 Server01 計算機上啟動互動式工作階段。
C:\PS> Enter-PSSession -computername Server01
命令提示字元會變更,以顯示您現在已連線到 Server01 計算機。
Server01\C:>
若要在會話中啟動遠端作業,請使用
Start-Job
Cmdlet。 下列命令會執行遠端作業,以取得 Server01 計算機上 Windows PowerShell 事件記錄檔中的事件。 Cmdlet 會Start-Job
傳回代表作業的物件。此命令會將作業物件儲存在變數中
$job
。Server01\C:> $job = Start-Job -scriptblock { Get-Eventlog "Windows PowerShell" }
當作業執行時,您可以使用互動式會話來執行其他命令,包括其他作業。 不過,您必須讓互動式會話保持開啟,直到作業完成為止。 如果您結束會話,作業會中斷,且結果會遺失。
若要了解作業是否完成,請顯示變數的值
$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) 。若要取得作業的結果,請使用
Receive-Job
Cmdlet。 您可以在互動式會話中顯示結果,或將它們儲存到遠端電腦上的檔案。 下列命令會取得$job變數中作業的結果。 此命令會使用重新導向運算子 (>
) ,將作業的結果儲存在 Server01 計算機上的 PsLog.txt 檔案中。Server01\C:> Receive-Job $job > c:\logs\PsLog.txt
若要結束互動式會話,請使用
Exit-PSSession
Cmdlet。 命令提示字元會變更,以顯示您回到本機電腦上的原始會話。Server01\C:> Exit-PSSession C:\PS>
若要隨時檢視 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 名詞的 Cmdlet (Job Cmdlet) 來管理任何 Cmdlet 所建立的任何作業。 許多具有 AsJob 參數的 Cmdlet 都不會使用 PowerShell 遠端處理,因此即使在未設定遠端處理且不符合遠端處理需求的電腦上,您也能使用這些 Cmdlet。
下列命令會使用的
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 計算機上執行。
若要使用 Cmdlet 的
Invoke-Command
AsJob 參數來管理啟動的作業,請使用 Job Cmdlet。 由於代表遠端作業的作業對象位於本機電腦上,因此您不需要執行遠端命令來管理作業。若要判斷作業是否完成,請使用
Get-Job
命令。 下列命令會取得目前會話中啟動的所有作業。Get-Job
由於遠端作業已在目前的會話中啟動,所以本機
Get-Job
命令會取得作業。 作業物件的 State 屬性會顯示命令已順利完成。SessionId Name State HasMoreData Location Command --------- ---- ----- ----------- -------- ------- 1 Job1 Completed True Server01 Get-Eventlog system
若要取得作業的結果,請使用
Receive-Job
Cmdlet。 因為作業結果會自動傳回作業物件所在的計算機,所以您可以使用本機Receive-Job
命令來取得結果。下列命令會
Receive-Job
使用 Cmdlet 來取得作業的結果。 它會使用會話標識碼來識別作業。 此命令會將作業結果儲存在 $results 變數中。 您也可以將結果重新導向至檔案。$results = Receive-Job -id 1
啟動遠端作業,以在遠端電腦上保留結果
若要在遠端電腦上啟動讓命令結果保持在遠端電腦上的作業,請使用 Invoke-Command
Cmdlet 在遠端電腦上執行 Start-Job
命令。 您可以使用這個方法在多部電腦上執行作業。
當您從遠端執行 Start-Job
命令時,作業物件會在遠端電腦上建立,並在遠端電腦上維護作業結果。
從作業的觀點來看,所有作業都是本機作業。 您只是在遠端執行命令,以管理遠端電腦上的本機作業。
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
命令來取得作業。請注意, [位置] 屬性的值會顯示作業在本機計算機上執行,稱為 “LocalHost”,即使作業在 Server01 計算機上執行也一樣。 由於作業物件是在 Server01 計算機上建立,且作業會在相同電腦上執行,因此會被視為本機背景工作。
若要管理遠端作業,請使用 作業 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
若要取得作業的結果,請使用
Invoke-Command
Cmdlet 在連接到 Server01 計算機的 PSSession 中執行Receive-Job
命令。下列命令會
Receive-Job
使用 Cmdlet 來取得作業的結果。 它會使用會話標識碼來識別作業。 此命令會將作業結果儲存在變數中$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 工作階段的作業。
Create 本機電腦上的新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會話。