about_Job_Details

简短说明

提供有关本地和远程计算机上的后台作业的详细信息。

详细说明

本主题介绍后台作业的概念,并提供有关后台作业在 PowerShell 中工作原理的技术信息。

本主题是对 about_Jobsabout_Thread_Jobsabout_Remote_Jobs 主题的补充。

关于后台作业

后台作业以异步方式运行命令或表达式。 它可能会运行 cmdlet、函数、脚本或任何其他基于命令的任务。 它设计为运行需要较长时间的命令,但你可以使用它在后台运行任何命令。

同步命令运行时,PowerShell 命令提示符将取消,直到命令完成。 但后台作业不会禁止显示 PowerShell 提示。 用于启动后台作业的命令将返回作业对象。 提示会立即返回,以便在后台作业运行时处理其他任务。

但是,启动后台作业时,即使作业运行非常快,也不会立即获得结果。 返回的作业对象包含有关作业的有用信息,但不包含作业结果。 必须运行单独的命令才能获取作业结果。 还可以运行命令来停止作业、等待作业完成以及删除作业。

为使后台作业的计时与其他命令无关,每个后台作业在其自己的 PowerShell 会话中运行。 但这可以是一个临时连接,其创建目的只是运行作业,然后就会销毁,或者也可以是可用于运行多个相关作业或命令的持久性 PSSession

使用作业 cmdlet

使用 Start-Job 命令在本地计算机上启动后台作业。 Start-Job 将返回作业对象。 还可以使用 Get-Job cmdlet 获取代表本地计算机上启动的作业的对象。

若要获取作业结果,请使用 Receive-Job 命令。 如果作业未完成,Receive-Job 将返回部分结果。 还可以使用 Wait-Job cmdlet 禁止显示命令提示,直到会话中启动的一个或多个作业完成。

若要停止后台作业,请使用 Stop-Job cmdlet。 若要删除作业,请使用 Remove-Job cmdlet。

有关 cmdlet 工作原理的详细信息,请参阅每个 cmdlet 的帮助主题,并查看 about_Jobs

在远程计算机上启动后台作业

可以在本地或远程计算机上创建和管理后台作业。 若要远程运行后台作业,请使用 cmdlet 的 AsJob 参数(如 Invoke-Command),或使用 Invoke-Command cmdlet 远程运行 Start-Job 命令。 还可以在交互式会话中启动后台作业。

有关远程后台作业的详细信息,请参阅 about_Remote_Jobs

子作业

每个后台作业由一个父作业和一个或多个子作业组成。 在使用 Start-JobInvoke-CommandAsJob 参数启动的作业中,父作业是管理者。 它不运行任何命令或返回任何结果。 这些命令实际上由子作业运行。 使用其他 cmdlet 启动的作业可能以不同的方式工作。

子作业存储在父作业对象的 ChildJobs 属性中。 ChildJobs 属性可以包含一个或多个子作业对象。 子作业对象具有与父作业不同的 NameIDInstanceId,便于你单独或作为单元管理父作业和子作业。

若要获取作业的父作业和子作业,请使用 Get-Job cmdlet 的 IncludeChildJobs 参数。 IncludeChildJob 参数是在 Windows PowerShell 3.0 中引入的。

PS> Get-Job -IncludeChildJob

Id Name   PSJobTypeName State      HasMoreData   Location    Command
-- ----   ------------- -----      -----------   --------    -------
1  Job1   RemoteJob     Failed     True          localhost   Get-Process
2  Job2                 Completed  True          Server01    Get-Process
3  Job3                 Failed     False         localhost   Get-Process

若要获取父作业以及仅具有特定 State 值的子作业,请使用 Get-Job cmdlet 的 ChildJobState 参数。 ChildJobState 参数是在 Windows PowerShell 3.0 中引入的。

PS> Get-Job -ChildJobState Failed

Id Name   PSJobTypeName State      HasMoreData   Location    Command
-- ----   ------------- -----      -----------   --------    -------
1  Job1   RemoteJob     Failed     True          localhost   Get-Process
3  Job3                 Failed     False         localhost   Get-Process

若要在所有版本的 PowerShell 上获取作业的子作业,请使用父作业的 ChildJob 属性。

PS> (Get-Job Job1).ChildJobs

Id Name   PSJobTypeName State      HasMoreData   Location    Command
-- ----   ------------- -----      -----------   --------    -------
2  Job2                 Completed  True          Server01    Get-Process
3  Job3                 Failed     False         localhost   Get-Process

还可以在子作业上使用 Get-Job 命令,如以下命令所示:

PS> Get-Job Job3

Id Name   PSJobTypeName State      HasMoreData   Location    Command
-- ----   ------------- -----      -----------   --------    -------
3  Job3                 Failed     False         localhost   Get-Process

子作业的配置取决于用于启动作业的命令。

  • 使用 Start-Job 在本地计算机上启动作业时,该作业由承担管理责任的父作业和运行命令的子作业组成。

  • 使用 Invoke-CommandAsJob 参数在一台或多台计算机上启动作业时,该作业由承担管理责任的父作业和每台计算机上运行的每个作业的子作业组成。

  • 使用 Invoke-Command 在一个或多个远程计算机上运行 Start-Job 命令时,结果与在每台远程计算机上运行的本地命令相同。 该命令将为每台计算机返回一个作业对象。 作业对象由承担管理责任的父作业和一个运行命令的子作业组成。

父作业可代表所有子作业。 在管理父作业时,也在管理关联的子作业。 例如,如果停止父作业,所有子作业都会停止。 如果获取父作业的结果,则会获取所有子作业的结果。

但是,你也可以单独管理子作业。 如果要调查作业问题或仅获取使用 Invoke-CommandAsJob 参数启动的多个子作业之一的结果,这非常有用。

以下命令使用 Invoke-CommandAsJob 参数在本地计算机和两台远程计算机上启动后台作业。 该命令将作业保存在 $j 变量中。

PS> $j = Invoke-Command -ComputerName localhost, Server01, Server02 `
-Command {Get-Date} -AsJob

$j 中显示作业的 Name 和 ChildJob 属性时,它显示该命令返回了一个作业对象,其中包含三个子作业,每台计算机各一个。

PS> $j | Format-List Name, ChildJobs

Name      : Job3
ChildJobs : {Job4, Job5, Job6}

显示父作业时,它显示作业失败。

PS> $j

Id Name   PSJobTypeName State      HasMoreData   Location
-- ----   ------------- -----      -----------   --------
3  Job3   RemotingJob   Failed     False         localhost,Server...

但是,运行获取子作业的 Get-Job 命令时,输出显示只有一个子作业失败。

PS> Get-Job -IncludeChildJobs

Id  Name   PSJobTypeName State      HasMoreData   Location    Command
--  ----   ------------- -----      -----------   --------    -------
3   Job3   RemotingJob   Failed     False         localhost,Server...
4   Job4                 Completed  True          localhost   Get-Date
5   Job5                 Failed     False         Server01    Get-Date
6   Job6                 Completed  True          Server02    Get-Date

若要获取所有子作业的结果,请使用 Receive-Job cmdlet 获取父作业的结果。 但也可以获取特定子作业的结果,如以下命令中所示。

PS> Receive-Job -Name Job6 -Keep | Format-Table ComputerName,
>> DateTime -AutoSize
ComputerName DateTime
------------ --------
Server02     Thursday, March 13, 2008 4:16:03 PM

PowerShell 后台作业的子作业功能可让你更好地控制所运行的作业。

作业类型

PowerShell 支持不同任务的不同类型作业。 从 Windows PowerShell 3.0 开始,开发人员可以编写“作业源适配器”,以向 PowerShell 添加新的作业类型,并在模块中包含作业源适配器。 导入模块时,可以在会话中使用新的作业类型。

例如,PSScheduledJob 模块添加计划作业,PSWorkflow 模块添加工作流作业。

自定义作业类型可能与标准 PowerShell 后台作业明显不同。 例如,计划的作业保存在磁盘上;它们不只存在于特定会话中。 工作流作业可以暂停和恢复。

用于管理自定义作业的 cmdlet 取决于作业类型。 有些可以使用标准作业 cmdlet,例如 Get-JobStart-Job。 另一些则附带仅管理特定类型作业的专用 cmdlet。 有关自定义作业类型的详细信息,请参阅有关作业类型的帮助主题。

若要查找作业的作业类型,请使用 Get-Job cmdlet。 Get-Job 为不同类型的作业返回不同的作业对象。 Get-Job 返回的作业对象的 PSJobTypeName 属性值表示作业类型。

下表列出了 PowerShell 附带的作业类型。

工作类型 说明
BackgroundJob 开始使用 Start-Job cmdlet。
RemoteJob 开始使用 AsJob 参数
Invoke-Command cmdlet。
PSWorkflowJob 开始使用工作流的 AsJob 参数。
PSScheduledJob 作业触发器启动的计划作业的实例。
CIMJob 开始使用 cmdlet 的 AsJob 参数,从
CDXML 模块。
WMIJob 开始使用 cmdlet 的 AsJob 参数,从
WMI 模块。
PSEventJob 使用 Register-ObjectEvent 创建并
使用 Action 参数指定操作。

注意:在使用 Get-Job cmdlet 获取特定类型的作业之前,请验证添加作业类型的模块已导入当前会话。 否则,Get-Job 无法获取该类型的作业。

示例

以下命令将创建本地后台作业、远程后台作业、工作流作业和计划作业。 然后,它使用 Get-Job cmdlet 获取作业。 Get-Job 无法获取计划作业,但可获取任何已启动的计划作业实例。

在本地计算机上启动后台作业。

PS> Start-Job -Name LocalData {Get-Process}

Id Name        PSJobTypeName   State   HasMoreData   Location   Command
-- ----        -------------   -----   -----------   --------   -------
2  LocalData   BackgroundJob   Running        True   localhost  Get-Process

启动在远程计算机上运行的后台作业。

PS> Invoke-Command -ComputerName Server01 {Get-Process} `
-AsJob -JobName RemoteData

Id  Name        PSJobTypeName  State   HasMoreData   Location   Command
--  ----        -------------  -----   -----------   --------   -------
2   RemoteData  RemoteJob      Running        True   Server01   Get-Process

创建计划作业

PS>  Register-ScheduledJob -Name ScheduledJob -ScriptBlock `
 {Get-Process} -Trigger (New-JobTrigger -Once -At "3 PM")

Id         Name            JobTriggers     Command       Enabled
--         ----            -----------     -------       -------
1          ScheduledJob    1               Get-Process   True

创建工作流。

PS> workflow Test-Workflow {Get-Process}

将工作流作为作业运行。


PS> Test-Workflow -AsJob -JobName TestWFJob

Id  Name       PSJobTypeName   State   HasMoreData   Location   Command
--  ----       -------------   -----   -----------   --------   -------
2   TestWFJob  PSWorkflowJob   NotStarted     True   localhost  Get-Process

获取作业。 Get-Job 命令无法获取计划作业,但可获取启动的计划作业实例。

PS> Get-Job

Id  Name         PSJobTypeName  State     HasMoreData  Location  Command
--  ----         -------------  -----     -----------  --------  -------
2   LocalData    BackgroundJob  Completed True         localhost Get-Process
4   RemoteData   RemoteJob      Completed True         Server01  Get-Process
6   TestWFJob    PSWorkflowJob  Completed True         localhost WorkflowJob
8   ScheduledJob PSScheduledJob Completed True         localhost Get-Process

若要获取计划作业,请使用 Get-ScheduledJob cmdlet。

PS> Get-ScheduledJob

Id         Name            JobTriggers     Command       Enabled
--         ----            -----------     -------       -------
1          ScheduledJob    1               Get-Process   True

另请参阅