Search

Run Parallel Jobs in PowerShell

One of the most valuable things I have picked up about PowerShell has been how to run parallel tasks pre-PowerShell 7. PowerShell 7 offers ForEach-Object Parallel which is fantastic, but when you are dealing with clients, you can’t always rely on them having or wanting to update to PowerShell 7.

This method still works with PowerShell 7, so you can’t go wrong here! This template will get you started in running your code in parallel. Keep in mind, that script blocks in PowerShell are not aware of variables in the script, you have to pass them to the script block as arguments & parameters. You can use this to run parallel processes, tasks, whole scripts, etc! I have set the value to 2 parallel jobs at most by default. As soon as one of the parallel processes is complete, it will start the next item in the queue, always keeping two jobs or “threads” (these are not actual threads, just a similar concept).

# Array of items to later add to queue
$array_queue_items = @("item-1", "item-2", "item-3", "item-4")

# How many parallel jobs to have running at once
$parallel = 2

# Function to run jobs
function RunJobFromQueue
{
    if ( $queue.Count -gt 0)
    {
		$scriptBlock
		{
			#Code to run in parallel here
		}
    }
		# The background jobs will be labeled with this string. Helpful for troubleshooting and general identification of this script
		$Identifier = "parallel-script-$(New-Guid)"
		
		# Assign the Start-Job command and all arguments to the $job variable
        $job = Start-Job -Name $Identifier -ScriptBlock $scriptBlock1 # -ArgumentList $arg1, $arg2, $arg3 if you need arguments
		
		# Magic. Resgisters and unregisters events to keep the queue progressing
        Register-ObjectEvent -InputObject $job -EventName StateChanged -SourceIdentifier $Identifier -Action { RunJobFromQueue; Unregister-Event $eventsubscriber.SourceIdentifier; Remove-Job $eventsubscriber.SourceIdentifier } | Out-Null
    }
}

# Create a synchronized queue
$queue = [System.Collections.Queue]::Synchronized( (New-Object System.Collections.Queue) )

# Add each item in the $array_queue_items to the queue
foreach ($item in $array_queue_items)
{
    $queue.Enqueue($item)
}

# Controls how many parallel jobs to kick off. If $parallel is 2, it will process 2 queue items in succession. When one finishes, the next will automatically start
for ( $i = 0; $i -lt $Parallel; $i++ )
{
    RunJobFromQueue
}

Also, remember that each new job will start in the default PowerShell location C:\Users\<username>. You may have to pass the directory you want your jobs to run in (say for logging) as a parameter & argument.

Share the Post:

Related Posts

PNG Press – Convert all those annoying .webp files quickly

PNG Press is a lightweight desktop application built using .NET Core 8. It features a simple drag-and-drop interface designed to convert one or multiple images to PNG format with ease. This project was born out of my own necessity for a straightforward image conversion tool, and I’m excited to finally share it with you.

Read More

Yu-Gi-Oh! Rarity Collection 2 Set Overview

The Yu-Gi-Oh! TCG set Rarity Collection 2 is getting mixed reviews to say the least. I’ve consulted with the Millennium items and searched the labyrinth of Atem’s mind to find this Yu-Gi-Oh! set’s stats, metrics, and other neat insights, let’s go!

Read More