---
title: Parallel Execution in PowerShell 7+
tags: [powershell, parallelism, threading, jobs, performance, ps7]
---

# Parallel Execution in PowerShell 7+

One of the most significant improvements in PowerShell 7 is the native support for easy parallel execution. This guide covers how to speed up your scripts by running tasks concurrently.

**Parent Topic:** [[programming/PowerShell/Scripting|PowerShell Scripting and Programming]]
**Related:** [[programming/PowerShell/PowerShell|PowerShell Comprehensive Guide]]

## 1. ForEach-Object -Parallel

In Windows PowerShell (5.1), running loops in parallel required complex runspace management or heavy background jobs. PowerShell 7 introduces the `-Parallel` parameter to the standard `ForEach-Object` cmdlet.

### Basic Usage

```powershell
$numbers = 1..10

$numbers | ForEach-Object -Parallel {
    # This block runs in a separate thread
    Write-Host "Processing $_ on thread $([System.Threading.Thread]::CurrentThread.ManagedThreadId)"
    Start-Sleep -Seconds 1
} -ThrottleLimit 5
```

*   **`-Parallel`**: The script block to run for each object.
*   **`-ThrottleLimit`**: Limits the number of threads running at once (Default is 5).

### Passing Variables (The `using:` Scope)

Variables from your main script are not automatically available inside the parallel block. You must use the `$using:` scope modifier.

```powershell
$prefix = "File_"
$files = 1..5

$files | ForEach-Object -Parallel {
    $name = "$($using:prefix)$_"
    New-Item -Path "C:\Temp\$name.txt" -ItemType File -Force
}
```

## 2. Thread Jobs

`Start-ThreadJob` is a module (included in PS 7) that creates background jobs running on threads within the current process, rather than separate processes. This is much lighter on memory and faster to start than standard jobs.

```powershell
# Start a job
$job = Start-ThreadJob -ScriptBlock {
    param($name)
    Start-Sleep -Seconds 2
    return "Hello, $name"
} -ArgumentList "World"

# Wait for it to finish and get the result
$result = Receive-Job -Job $job -Wait -AutoRemoveJob
Write-Host $result
```

## 3. Performance Comparison

| Feature | Mechanism | Overhead | Use Case |
| :--- | :--- | :--- | :--- |
| `ForEach-Object -Parallel` | Runspaces (Threads) | Low | Processing lists of items (files, users, API calls). |
| `Start-ThreadJob` | Runspaces (Threads) | Low | Running a single long-running task in the background. |
| `Start-Job` | Processes | High | Isolation required; legacy compatibility. |

## 4. Thread Safety Warning

When running in parallel, multiple threads might try to write to the same file or variable simultaneously.

*   **File Writes**: Avoid writing to the same file from multiple threads. Instead, return the data to the main thread and write it there.
*   **Console Output**: `Write-Host` is generally thread-safe in PS 7, but output order is not guaranteed.

**Correct Pattern (Return to Main Thread):**

```powershell
$results = $servers | ForEach-Object -Parallel {
    # Do work
    $status = Test-Connection -ComputerName $_ -Count 1 -Quiet
    # Return object
    [PSCustomObject]@{ Server = $_; Online = $status }
}

# Export results sequentially
$results | Export-Csv -Path "results.csv" -NoTypeInformation
```

---
Return to [[programming/PowerShell/Scripting|PowerShell Scripting and Programming]]