约 1957 字

约 10 分钟

#后台作业

后台作业(job)让命令在后台运行,当前会话可以继续执行其他操作。作业适合耗时较长、无需立即拿到结果的任务,例如批量复制文件或查询多台主机。

#创建作业

Start-Job 使用脚本块创建作业:

> $job = Start-Job -ScriptBlock {
    Get-Process | Sort-Object CPU -Descending | Select-Object -First 3
}

也可以用 -FilePath 运行脚本文件。需要向脚本块传参时使用 -ArgumentList,并在脚本块中通过 $args 或 param() 接收:

> $job = Start-Job -ScriptBlock {
    param($path)
    Get-ChildItem -Path $path
} -ArgumentList '/tmp'

#查看与接收结果

Get-Job 列出当前会话中的作业及其状态:

> Get-Job

Receive-Job 获取作业产生的输出:

> Receive-Job -Id 1
> Receive-Job -Job $job -Keep
  • 默认情况下,Receive-Job 读取后会把结果从作业中移除。
  • 使用 -Keep 可以保留结果,便于再次读取。

#等待与停止

Wait-Job 等待作业完成,可以设置超时:

> Wait-Job -Id 1
> Wait-Job -Job $job -Timeout 60

Stop-Job 停止正在运行的作业:

> Stop-Job -Id 1

Remove-Job 删除作业对象,释放资源:

> Remove-Job -Id 1
> Get-Job | Remove-Job

作业完成后不会自动从列表中消失,通常应先 Receive-Job,再 Remove-Job。

#作业与进程的区别

  • 作业由 PowerShell 管理,状态包括 Running、Completed、Failed、Stopped 等。
  • 后台作业默认在独立的 PowerShell 子进程中运行,因此不能直接访问父会话的变量和函数。
  • 作业输出在跨进程传递时会被序列化,可能丢失部分类型信息。
  • 进程是操作系统的概念;作业是 PowerShell 层面的封装,一个作业通常对应一个子进程。
  • 作业只存在于创建它的会话中,关闭会话后作业随之结束。

若需在父会话中访问变量,可在脚本块中使用 $using: 前缀:

> $name = 'pwsh'
> Start-Job -ScriptBlock { Get-Process -Name $using:name }

#线程作业

Start-ThreadJob 在同一个进程内用线程运行任务,启动更快、开销更小,并且可以直接共享父会话的对象:

> $job = Start-ThreadJob -ScriptBlock { 1 + 1 }
> Receive-Job -Job $job

ThreadJob 模块通常随 PowerShell 7 一起提供;若不可用,可先安装并导入该模块。线程作业不适合运行可能崩溃或需要强隔离的代码。

#推荐阅读

更新: 2026/11/2

作者: planc

创建: 2026/11/2