The essentials
Quick reference
One focused task per row. Jump to the related section for complete, working examples.
| Use | Syntax | Examples |
|---|---|---|
| Start process job | $job = Start-Job -Name 'Inventory' -ScriptBlock { Get-Process |
Select-Object -First 5 } | View examples |
| Pass explicit arguments | Start-Job -ScriptBlock { param($Path) Get-Item `
-LiteralPath $Path } -ArgumentList `
'C:/Data/report.csv' | View examples |
| Start thread job | Start-ThreadJob -Name 'FastRead' -ScriptBlock { Get-Date `
} | View examples |
| List jobs | Get-Job |
Select-Object Id, Name, State, HasMoreData, Location | View examples |
| Inspect child jobs | $job.ChildJobs |
Select-Object Id, Name, State, Location, HasMoreData | View examples |
| Wait with timeout | Wait-Job -Job $job -Timeout 60 | View examples |
| Wait for any job | Wait-Job -Job $jobs -Any -Timeout 30 | View examples |
| Receive available output | Receive-Job -Job $job | View examples |
| Read output non-destructively | Receive-Job -Job $job -Keep | View examples |
| Wait and receive | Receive-Job -Job $job -Wait -AutoRemoveJob | View examples |
| Start remote job | $job = Invoke-Command -ComputerName `
'server01','server02' -ScriptBlock { Get-Date } -AsJob `
-ThrottleLimit 2 | View examples |
| Find failed child jobs | $job.ChildJobs |
Where-Object State -eq 'Failed' |
Format-List Location, JobStateInfo, Error | View examples |
| Stop a running job | Stop-Job -Job $job | View examples |
| Remove completed job | Remove-Job -Job $job | View examples |
| Remove finished jobs | Get-Job |
Where-Object State -in 'Completed','Failed','Stopped' |
Remove-Job | View examples |
PowerShell jobs make work asynchronous; they do not make it persistent, idempotent, or safe. Process jobs isolate execution and serialize their output, thread jobs share the caller's process, and remote jobs depend on session and transport choices. Bound concurrency, pass explicit input, preserve every output stream, impose timeouts, and design cancellation and cleanup before launching work. Jobs run with the privileges and access of their execution context.
Step by step
Detailed examples
Choose isolation deliberately and pass immutable inputs
Start-Job uses a child process, so output is serialized and most live object methods are unavailable after return. Thread jobs are faster and return live objects, but an unhandled native crash or process-wide mutation can affect the caller. Neither job type survives its owning PowerShell process by default. Pass approved values through parameters rather than depending on ambient location, variables, credentials, or mapped drives.
$path = 'C:/Data/report.csv'
$job = Start-Job -Name 'InspectReport' -ArgumentList $path -ScriptBlock {
param([string]$LiteralPath)
Get-Item -LiteralPath $LiteralPath -ErrorAction Stop | Select-Object FullName, Length, LastWriteTimeUtc
} Track state by object identity, including child jobs
Job numeric IDs are scoped to the current session; InstanceId is globally unique but still refers to an in-memory repository entry. Aggregate remote jobs contain child jobs whose Location and errors identify individual targets. A Completed state means execution ended, not that business validation succeeded, while HasMoreData indicates buffered stream records remain.
$job | Select-Object Id, InstanceId, Name, State, HasMoreData, Location
$job.ChildJobs | Select-Object Id, InstanceId, Name, State, HasMoreData, Location
$job | Format-List JobStateInfo, StatusMessage Bound every wait and handle incomplete work
Wait-Job blocks only until the selected terminal-state condition or timeout; a timeout returns no completed job for that selection and does not cancel execution. Retain the original job objects, distinguish completed, failed, stopped, disconnected, and still-running states, then apply an explicit retry or cancellation policy. Avoid tight polling loops.
$completed = Wait-Job -Job $job -Timeout 60
if (-not $completed) {
Write-Warning 'The job exceeded 60 seconds; reviewing before cancellation.'
$job | Select-Object Id, Name, State, Location
}
$job.ChildJobs | Group-Object State | Select-Object Name, Count Receive output once and preserve all diagnostic streams
Receive-Job normally drains available output; -Keep permits rereading at the cost of retaining memory. Output includes stream records in arrival order, and remoting adds provenance properties. Capture results only after deciding how errors, warnings, verbose, information, and progress records will be retained. Never infer success solely from nonempty success output.
$results = Receive-Job -Job $job -Keep -ErrorVariable jobErrors -WarningVariable jobWarnings
$results | Export-Clixml -LiteralPath './job-results.clixml'
$jobErrors | Format-List FullyQualifiedErrorId, CategoryInfo, TargetObject, Exception
$job.ChildJobs | Select-Object Location, State, HasMoreData Throttle remote jobs and preserve target attribution
Invoke-Command -AsJob returns immediately and creates child jobs for each target. ThrottleLimit bounds simultaneous remote operations, not application load after a command starts. Authentication, endpoint configuration, serialization, and disconnected-session behavior still apply. Roll out read-only probes first, then small batches with per-host idempotency and rollback.
$targets = 'server01','server02'
$job = Invoke-Command -ComputerName $targets -ThrottleLimit 2 -AsJob -ScriptBlock {
[pscustomobject]@{ ComputerName = $env:COMPUTERNAME; Time = Get-Date; PSVersion = $PSVersionTable.PSVersion.ToString() }
}
Wait-Job -Job $job -Timeout 60 | Out-Null
Receive-Job -Job $job -Keep Make cancellation and cleanup explicit
Stop-Job requests that execution stop but cannot undo files written, requests sent, or other external side effects. Design job bodies to be idempotent and cancellation-safe. Receive or archive required output before Remove-Job, which deletes the repository object and buffered data. Clean up terminal jobs to prevent memory growth in long-running consoles.
if ($job.State -eq 'Running') {
$job | Select-Object Id, Name, State, Location
Stop-Job -Job $job
Wait-Job -Job $job -Timeout 15 | Out-Null
}
Receive-Job -Job $job -Keep -ErrorVariable finalErrors | Export-Clixml './final-job-output.clixml'
Remove-Job -Job $job Sources and further reading
References
Authoritative documentation used to verify and expand this cheat sheet.
Help us improve
Found a typo or missing example?
Tell us what would make this cheat sheet clearer, more complete, or more useful.



