about_Jobs
簡短描述
提供PowerShell背景作業如何在背景中執行命令或表達式,而不需與目前會話互動的相關信息。
詳細描述
PowerShell 會透過作業同時執行命令和腳本。 PowerShell 提供的作業類型有三種,可支援並行。
RemoteJob
- 在遠端工作階段上執行的命令和腳稿。 如需詳細資訊,請參閱 about_Remote_Jobs。BackgroundJob
- 命令和文稿會在本機計算機上的個別進程中執行。PSTaskJob
或ThreadJob
- 命令和文稿會在本機計算機上相同進程的個別線程中執行。 如需詳細資訊,請參閱 about_Thread_Jobs。
從遠端執行文本,是在個別的計算機上或在個別進程中,提供絕佳的隔離。 遠端作業中發生的任何錯誤都不會影響其他執行中作業或啟動作業的父會話。 不過,遠端層會增加額外負荷,包括物件串行化。 所有物件都會在父會話與遠端 (job) 工作階段之間傳遞時串行化和還原串行化。 大型複雜數據物件的串行化可能會耗用大量的計算和記憶體資源,並跨網路傳輸大量數據。
線程型作業不像遠端和背景工作那麼強固,因為它們在不同的線程上在同一個進程中執行。 如果某個作業發生嚴重錯誤而損毀進程,則進程中的所有其他作業都會終止。
不過,線程型作業需要較少的額外負荷。 它們不會使用遠端層或串行化。 結果物件會以目前會話中即時對象的參考傳回。 若沒有此額外負荷,線程型作業的執行速度會更快,且使用的資源比其他作業類型少。
重要
建立作業的父會話也會監視作業狀態並收集管線數據。 作業子進程會在作業達到完成狀態后,由父進程終止。 如果父會話終止,則所有執行中的子作業都會連同其子進程一起終止。
有兩種方式可解決這種情況:
- 用來
Invoke-Command
建立在中斷聯機會話中執行的作業。 如需詳細資訊,請參閱 about_Remote_Jobs。 - 使用
Start-Process
來建立新的進程,而不是作業。 如需詳細資訊,請參閱 Start-Process。
作業 Cmdlet
Start-Job
- 在本機計算機上啟動背景工作。Get-Job
- 取得在目前會話中啟動的背景工作。Receive-Job
- 取得背景工作的結果。Stop-Job
- 停止背景工作。Wait-Job
- 隱藏命令提示字元,直到一或所有作業完成為止。Remove-Job
- 刪除背景工作。Invoke-Command
- AsJob 參數會在遠端電腦上建立背景工作。 您可以使用Invoke-Command
遠端執行任何作業指令,包括Start-Job
。
如何在本機計算機上啟動作業
若要在本機計算機上啟動背景工作,請使用 Start-Job
Cmdlet。
若要撰寫 Start-Job
命令,請以大括弧 ({}
) 括住作業執行的命令。 使用 ScriptBlock 參數來指定命令。
下列命令會啟動在本機計算機上執行 Get-Process
命令的背景作業。
Start-Job -ScriptBlock {Get-Process}
當您啟動背景工作時,即使作業需要較長的時間才能完成,命令提示字元仍會立即傳回。 工作執行時,您可以在工作階段中繼續工作,而不需中斷。
此命令 Start-Job
會傳回代表作業的物件。 作業物件包含作業的實用資訊,但不包含作業結果。
您可以將作業物件儲存在變數中,然後將它與其他 Job Cmdlet 搭配使用,以管理背景工作。 下列命令會啟動作業物件,並將產生的作業物件儲存在變數中 $job
。
$job = Start-Job -ScriptBlock {Get-Process}
從 PowerShell 6.0 開始,您可以使用管線結尾的背景運算子 (&
) 來啟動背景作業。 如需詳細資訊,請參閱 背景運算元。
使用背景運算子的功能相當於使用 Start-Job
上一個範例中的 Cmdlet。
$job = Get-Process &
取得作業物件
Cmdlet 會 Get-Job
傳回物件,代表在目前會話中啟動的背景工作。 如果沒有參數, Get-Job
則會傳回目前會話中啟動的所有作業。
Get-Job
作業物件包含作業的狀態,指出作業是否已完成。 已完成的作業狀態為 [完成] 或 [失敗]。 作業可能也會 遭到 封鎖或 執行。
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Complete True localhost Get-Process
您可以將作業物件儲存在變數中,並在稍後的命令中使用它來表示作業。 下列命令會取得標識碼為 1 的作業,並將它儲存在 變數中 $job
。
$job = Get-Job -Id 1
取得作業的結果
當您執行背景作業時,結果不會立即出現。 若要取得背景工作的結果,請使用 Receive-Job
Cmdlet。
下列範例會 Receive-Job
使用 變數中的 $job
job物件,Cmdlet取得作業的結果。
Receive-Job -Job $job
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
668 7 2672 6168 104 32.26 488 csrss
...
您可以將作業的結果儲存在變數中。 下列命令會將作業的結果儲存在 $job
變數中 $results
。
$results = Receive-Job -Job $job
取得和保留部分作業結果
Cmdlet Receive-Job
會取得背景工作的結果。 如果作業已完成, Receive-Job
則取得所有作業結果。 如果作業仍在執行中, Receive-Job
則取得到目前為止已產生的結果。 您可以再次執行 Receive-Job
命令,以取得剩餘的結果。
根據預設, Receive-Job
會從儲存作業結果的快取中刪除結果。 當您再次執行 Receive-Job
時,只會取得第一次執行之後抵達的新結果。
下列命令會顯示在作業完成之前執行的命令結果 Receive-Job
。
C:\PS> Receive-Job -Job $job
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
C:\PS> Receive-Job -Job $job
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
68 3 2632 664 29 0.36 1388 ccmsetup
749 22 21468 19940 203 122.13 3644 communicator
905 7 2980 2628 34 197.97 424 csrss
1121 25 28408 32940 174 430.14 3048 explorer
使用 Keep 參數來防止Receive-Job
刪除傳回的作業結果。 下列命令顯示對尚未完成之作業使用 Keep 參數的效果。
C:\PS> Receive-Job -Job $job -Keep
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
C:\PS> Receive-Job -Job $job -Keep
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
68 3 2632 664 29 0.36 1388 ccmsetup
749 22 21468 19940 203 122.13 3644 communicator
905 7 2980 2628 34 197.97 424 csrss
1121 25 28408 32940 174 430.14 3048 explorer
等候結果
如果您執行需要很長的時間才能完成的命令,您可以使用作業對象的屬性來判斷作業何時完成。 下列命令會 Get-Job
使用 物件來取得目前會話中的所有背景工作。
Get-Job
結果會出現在數據表中。 作業的狀態會出現在 [狀態 ] 資料行中。
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Complete True localhost Get-Process
2 Job2 BackgroundJob Running True localhost Get-EventLog -Log ...
3 Job3 BackgroundJob Complete True localhost dir -Path C:\* -Re...
在此情況下, State 屬性會顯示 Job 2 仍在執行中。 如果您要使用 Receive-Job
Cmdlet 立即取得作業結果,結果將會不完整。 您可以重複使用 Receive-Job
Cmdlet 來取得所有結果。 使用 State 屬性來判斷作業完成的時間。
您也可以使用 Cmdlet 的 Receive-Job
Wait 參數。 使用此參數時,Cmdlet 不會傳回命令提示字元,直到作業完成且所有結果都可供使用。
您也可以使用 Wait-Job
Cmdlet 來等候作業的任何或所有結果。 Wait-Job
可讓您等候一或多個特定作業,或等候所有作業。
下列命令會Wait-Job
使用 Cmdlet 來等候標識碼為 10 的作業。
Wait-Job -ID 10
因此,PowerShell 提示會隱藏,直到作業完成為止。
您也可以等候預先決定的時間。 此命令使用 Timeout 參數將等候限制為 120 秒。 當時間到期時,命令提示字元會傳回,但工作會繼續在背景中執行。
Wait-Job -ID 10 -Timeout 120
停止作業
若要停止背景工作,請使用 Stop-Job
Cmdlet。 下列命令會啟動作業,以取得系統事件記錄檔中的每個專案。 它會將作業物件儲存在變數中 $job
。
$job = Start-Job -ScriptBlock {Get-EventLog -Log System}
下列命令會停止作業。 它會使用管線運算子 (|
) 將變數中的 $job
作業傳送至 Stop-Job
。
$job | Stop-Job
刪除作業
若要刪除背景工作,請使用 Remove-Job
Cmdlet。 下列命令會刪除 變數中的 $job
作業。
Remove-Job -Job $job
調查失敗的工作
作業可能會因為許多原因而失敗。 作業物件包含 Reason 屬性,其中包含失敗原因的相關信息。
下列範例會啟動沒有必要認證的作業。
$job = Start-Job -ScriptBlock {New-Item -Path HKLM:\Software\MyCompany}
Get-Job $job
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Failed False localhost New-Item -Path HKLM:...
檢查 Reason 屬性,找出導致作業失敗的錯誤。
$job.ChildJobs[0].JobStateInfo.Reason
在此情況下,作業失敗,因為遠端計算機需要明確的認證才能執行命令。 Reason 屬性包含下列訊息:
連線到遠端伺服器失敗,並出現下列錯誤訊息:「拒絕存取」。