Skip to content

Instantly share code, notes, and snippets.

@nicholasdille
Created September 8, 2015 08:03
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save nicholasdille/6fcfb6fadc67c1df3cfb to your computer and use it in GitHub Desktop.
Save nicholasdille/6fcfb6fadc67c1df3cfb to your computer and use it in GitHub Desktop.
Process a queue of objects using PowerShell jobs
function Invoke-Queue {
[CmdletBinding()]
[OutputType([System.Management.Automation.Job[]])]
param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[System.Object[]]
$InputObject
,
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[scriptblock]
$Scriptblock
,
[Parameter()]
[ValidateNotNullOrEmpty()]
[System.Object[]]
$ArgumentList
,
[Parameter()]
[ValidateNotNullOrEmpty()]
[int]
$ThrottleLimit = 32
,
[Parameter()]
[ValidateNotNullOrEmpty()]
[int]
$Delay = 2
,
[switch]
$Wait
,
[switch]
$ShowProgress
,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]
$ProgressActivityMessage = 'Processed input objects'
)
Begin {
Write-Verbose ('[{0}] Initializing variables' -f $MyInvocation.MyCommand)
$Jobs = @()
$InputIndex = 0
if ($Wait) {
Write-Verbose ('[{0}] Setting <ThrottleLimit> to 1 because <Wait> was specified.' -f $MyInvocation.MyCommand)
$ThrottleLimit = 1
}
Write-Verbose ('[{0}] Processing {1} objects' -f $MyInvocation.MyCommand, $InputObject.Count)
}
Process {
while ($InputIndex -lt $InputObject.Count) {
Write-Debug ('[{0}] InputIndex={1} JobCount={2} RunningJobCount={3}' -f $MyInvocation.MyCommand, $InputIndex, $Jobs.Count, ($Jobs | Get-Job | Where-Object {$_.State -ieq 'Running'}).Count)
if ($Jobs.Count -lt $ThrottleLimit -or ($Jobs | Get-Job | Where-Object {$_.State -ieq 'Running'}).Count -lt $ThrottleLimit) {
Write-Verbose ('[{0}] New job for parameter index {1}' -f $MyInvocation.MyCommand, $InputIndex)
$Job = Start-Job -ScriptBlock $Scriptblock -Name $InputObject[$InputIndex].ToString() -ArgumentList (@($InputObject[$InputIndex]) + $ArgumentList)
$Jobs += $Job
Write-Progress -Activity $ProgressActivityMessage -Status "Invoked $($InputObject[$InputIndex].ToString())" -PercentComplete ($Jobs.Count / $InputObject.Count * 100)
if ($Wait) {
Write-Output ('[{0}] Receiving output for job <{1}>' -f $MyInvocation.MyCommand, $Job.Name)
$Job | Receive-Job -Wait
}
++$InputIndex
} else {
Write-Debug ('[{0}] Waiting for a job to finish' -f $MyInvocation.MyCommand)
Start-Sleep -Seconds $Delay
}
}
Write-Verbose ('[{0}] All input objects are being processed' -f $MyInvocation.MyCommand)
Write-Progress -Activity $ProgressActivityMessage -Completed
$Jobs
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment