关于作业
简短说明
提供有关 PowerShell 后台作业如何在后台运行命令或表达式而不与当前会话交互的信息。
详细说明
本主题说明如何在 PowerShell 中在本地计算机上运行后台作业。 有关在远程计算机上运行后台作业的信息,请参阅 about_Remote_Jobs。
启动后台作业时,即使作业需要较长时间才能完成,命令提示符也会立即返回。 当该作业运行时,你可以继续在此会话中工作而不会发生中断。
作业 CMDLET
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}
还可以使用 Get-Job
cmdlet 获取表示当前会话中启动的作业的对象。 Get-Job
返回 Start-Job 返回的作业对象。
获取作业对象
若要获取表示在当前会话中启动的后台作业的对象,请使用 Get-Job
cmdlet。 如果没有参数, Get-Job
则返回在当前会话中启动的所有作业。
例如,以下命令获取当前会话中的作业。
PS C:> Get-Job
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Running True localhost Get-Process
还可以将作业对象保存在变量中,并在后面的命令中使用它来表示作业。 以下命令获取 ID 为 1 的作业,并将其保存在 $job 变量中。
$job = Get-Job -Id 1
作业对象包含作业的状态,该状态指示作业是否已完成。 已完成作业的状态为“完成”或“失败”。 作业也可能被阻止或正在运行。
Get-Job
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Complete True localhost Get-Process
获取作业的结果
运行后台作业时,结果不会立即显示。
相反,Start-Job cmdlet 返回表示作业的作业对象,但它不包含结果。 若要获取后台作业的结果,请使用 Receive-Job
cmdlet。
以下命令使用 Receive-Job
cmdlet 获取作业的结果。 它使用保存在 $job 变量中的作业对象来标识作业。
Receive-Job -Job $job
Receive-Job cmdlet 返回作业的结果。
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
此外,可以使用重定向运算符 () > 或 Out-File cmdlet 将作业结果保存在文件中。 以下命令使用重定向运算符将作业结果保存在 Results.txt 文件中的 $job 变量中。
Receive-Job -Job $job > results.txt
获取和保留部分作业结果
Receive-Job cmdlet 获取后台作业的结果。 如果作业已完成, 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
若要防止 Receive-Job
删除已返回的作业结果,请使用 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 属性显示作业 2 仍在运行。 如果现在要使用 Receive-Job
cmdlet 获取作业结果,则结果将不完整。 可以 Receive-Job
重复使用 cmdlet 来获取所有结果。 默认情况下,每次使用时,仅获取尚未收到的结果,但可以使用 Receive-Job cmdlet 的 Keep 参数来保留结果,即使已收到结果。
可以将部分结果写入文件,然后在更新的结果到达时追加它们,也可以等待并检查作业的状态。
可以使用 cmdlet 的 Receive-Job
Wait 参数,该参数在作业完成且所有结果可用之前不会返回命令提示符。
还可以使用 Wait-Job
cmdlet 等待作业的任何或所有结果。 Wait-Job
允许等待特定作业、等待所有作业或任何作业完成。
以下命令使用 Wait-Job cmdlet 等待 ID 为 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 变量中。
$job = Start-Job -ScriptBlock {New-Item -Path HKLM:\Software\MyCompany}
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Failed False localhost New-Item -Path HKLM:...
以下命令使用 Reason 属性查找导致作业失败的错误。
$job.ChildJobs[0].JobStateInfo.Reason
在这种情况下,作业失败,因为远程计算机需要显式凭据才能运行命令。 Reason 属性的值为:
连接到远程服务器失败,出现以下错误消息:访问被拒绝。