Skip to main content

PowerShell 7.0 added a new parameter set to the ForEach-Object cmdlet. The new parameters allow you to run script blocks in parallel threads as PowerShell jobs. You can pipe data to ForEach-Object -Parallel. The data is passed to the script block that is run in parallel. The -AsJob parameter creates jobs objects for each of the parallel threads.

# Using ForEach-Object -Parallel -AsJob
#
# PowerShell 7.0 added a new parameter set to the ForEach-Object cmdlet.
# The new parameters allow you to run script blocks in parallel threads as PowerShell jobs.
#
# You can pipe data to ForEach-Object -Parallel. The data is passed to the
# script block that is run in parallel. The -AsJob parameter creates jobs
# objects for each of the parallel threads.
#
# The ForEach-Object -Parallel command returns a PSTaskJob object that contains
# child jobs for each piped input value. The job object contains useful
# information about the child jobs running status. It collects the results
# of the child jobs as the results are being generated.
#
# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_thread_jobs?view=powershell-7.4#using-foreach-object--parallel--asjob

function ForEachParallel()
{
    Write-Host "ForEachParallel`n-------------------------" -ForegroundColor Cyan

    $sw = [Diagnostics.Stopwatch]::StartNew()

    $job = (1..5 | ForEach-Object -Parallel {
            Start-Sleep -Seconds 1
            Write-Output $_
        } -AsJob)

    $job | Receive-Job -Wait -AutoRemoveJob

    $sw.Stop()
    $sw.Elapsed | Select-Object -Property TotalSeconds | Format-List
    # TotalSeconds : 1.2810485
}

function ForEachNoParallelism()
{
    Write-Host "ForEachNoParallelism`n-------------------------" -ForegroundColor Cyan

    $sw = [Diagnostics.Stopwatch]::StartNew()

    1..5 | ForEach-Object {
        Start-Sleep -Seconds 1
        Write-Output $_
    }

    $sw.Stop()
    $sw.Elapsed | Select-Object -Property TotalSeconds | Format-List
    # TotalSeconds : 5.0066153
}

ForEachParallel
ForEachNoParallelism