Asynchronous processing in PowerShell script nodes

The easiest way to set up asynchronous processing in PowerShell script nodes is to use jobs. PowerShell has native commands for launching scripts as background jobs, and you can then wait for the jobs to complete and gather all of your results together. Note that if the parent script runs into an error or exception, the jobs will terminate when the script terminates automatically. 

Here is a generic sample that demonstrates that in action, including passing in credentials to the job so that the job can do the work that it needs to do. 

Sample Script

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 # The work that you want each job to do $scriptBlock = { # In here, you reference variables that are defined outside of the script block # by using the "using:" qualifier # Turn debug messages on and allow debug messages to be sent back to Cloudbridge $DebugPreference = [System.Management.Automation.ActionPreference]::Continue Set-Variable -Name sessionvars -Value $using:sessionvars # Once you do this, you can use the credential like normal in the job $creds = $using.creds # Do whatever the job was intended to do in parallel Get-Service -Name $using:serviceName } # The RunAs credential used to do the work so that we can reference it inside jobs $creds = Get-Credential # Start the jobs to gather the data; in this case, we're creating a job for every # letter of the alphabet, so that we can retrieve services that start with that # letter in separate jobs $jobs = [System.Collections.ArrayList]::new() foreach ($letter in [char[]]'abcdefghijklmnopqrstuvwxyz') { $serviceName = "${letter}*" $null = $jobs.Add(Start-Job -ScriptBlock $scriptBlock) } # When uncommented, the code below will send debug messages from jobs to # the script log, if there are any to send <# $null = Wait-Job -Job $jobs foreach($job in $jobs) { foreach($childJob in $job.ChildJobs) { foreach($debugRecord in $childJob.Debug) { Write-Debug $debugRecord.Message } } } #> # Jobs add several properties that should be removed from the output $jobPropertyList = @('PSComputerName','PSShowComputerName','PSSourceJobInstanceId','RunspaceId') # Retrieve the job data, removing the job properties in the process $output = [System.Collections.ArrayList]::new() foreach ($record in Receive-Job -Job $jobs -Wait -AutoRemoveJob) { foreach ($jobProperty in $jobPropertyList) { $record.PSObject.Properties.Remove($jobProperty) } $null = $output.Add($record) } # Now send the output back to Cloudbridge $output