关于招聘

简短说明

提供有关 PowerShell 后台作业如何在后台运行命令或表达式而不与当前会话交互的信息。

详细说明

本主题介绍如何在本地计算机上的 PowerShell 中运行后台作业。 有关在远程计算机上运行后台作业的信息,请参阅 about_Remote_Jobs

启动后台作业时,即使作业需要较长时间才能完成,命令提示符也会立即返回。 任务运行时,你可以在会话中不受干扰地继续工作。

作业 cmdlet

Cmdlet (命令行工具) DESCRIPTION
Start-Job 在本地计算机上启动后台作业。
Get-Job 获取在
当前会话。
Receive-Job 获取后台作业的结果。
Stop-Job 停止后台作业。
Wait-Job 禁止命令提示符,直到一个或所有作业都
完成。
Remove-Job 删除后台作业。
Invoke-Command AsJob 参数将任何命令作为后台运行
job 在远程计算机上。 您还可以使用
Invoke-Command 要远程运行任何 job 命令,
包括 Start-Job 命令。

如何在本地计算机上启动作业

若要在本地计算机上启动后台作业,请使用 Start-Job cmdlet。

要编写 Start-Job 命令,请将作业运行的命令括在大括号 ( { } ) 中。 使用 ScriptBlock 参数指定命令。

以下命令启动一个后台作业,该作业在本地计算机上运行 Get-Process 命令。

Start-Job -ScriptBlock {Get-Process}

Start-Job 命令返回一个表示作业的对象。 job 对象包含有关作业的有用信息,但不包含 job 结果。

将 job 对象保存在变量中,然后将其与其他 Job cmdlet 一起使用来管理后台作业。 以下命令启动一个 job 对象,并将生成的 job 对象保存在 $job 变量中。

$job = Start-Job -ScriptBlock {Get-Process}

您还可以使用 Get-Job cmdlet 获取表示当前会话中启动的作业的对象。 Get-Job 返回 Start-Job 返回的相同 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

您还可以将 job 对象保存在变量中,并在以后的命令中使用它来表示 job。 以下命令获取 ID 为 1 的作业并将其保存在 $job 变量中。

$job = Get-Job -Id 1

作业对象包含作业的状态,该状态指示作业是否已完成。 已完成的作业的状态为 “Complete” 或 “Failed”。 作业也可能被阻止或正在运行。

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 将作业结果保存在文件中。 以下命令使用 redirection 运算符将作业结果保存在 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

结果显示在表中。 任务的状态将显示在 State (状态) 列中。

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 变量中。

$job = Start-Job -ScriptBlock {Get-EventLog -Log System}

以下命令停止作业。 它使用管道运算符 (|) 将 $job 变量 Stop-Job中的作业发送到 。

$job | Stop-Job

删除作业

若要删除后台作业,请使用 Remove-Job cmdlet。 以下命令将删除 $job 变量中的作业。

Remove-Job -Job $job

调查失败的作业

要找出作业失败的原因,请使用 job 对象的 Reason 子属性。

以下命令在没有所需凭证的情况下启动作业。 它将 job 对象保存在 $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 属性的值为:

连接到远程服务器失败,并显示以下错误消息:Access is denied。

另请参阅

关于远程工作

about_Job_Details

关于远程

about_PSSessions

Start-Job (开始任务)

获取作业

接收-作业

停止作业

等待任务

删除作业

调用命令