How can I create jobs that yield results as they complete? How can I create jobs that yield results as they complete? powershell powershell

How can I create jobs that yield results as they complete?


Sounds like the PSRemotingJob.StateChanged Event might work for you. Something like this:

$global:results = [System.Collections.ArrayList]::new()# create action scriptblock for eventhandling$onJobFinish = {    # only run action if job has terminated    if ($Event.Sender.State -in @('Completed', 'Failed', 'Stopped', 'Suspended', 'Disconnected')) {        $localResults = $Event.Sender | Receive-Job        # immediately send output to screen        $localResults | Out-Host        # also add output to collection to work with later        $global:results.Add($localResults) | Out-Null    }}Invoke-Command -Session $sessions -ScriptBlock {    $computerName = [System.Net.Dns]::GetHostName()    $firstMillionPrimes = Sum-FirstMillionPrimes    Write-Output "$computerName - $firstMillionPrimes"} -AsJob |     Select-Object -ExpandProperty ChildJobs | ForEach-Object {    # Register our action to run wheneven a child job's state changes        Register-ObjectEvent -InputObject $_ -EventName 'StateChanged' -Action $onJobFinish    }Start-Job -ScriptBlock { Sum-FirstMillionPrimes } | Select-Object -ExpandProperty ChildJobs | ForEach-Object {    # Register our action to run wheneven a child job's state changes    Register-ObjectEvent -InputObject $_ -EventName 'StateChanged' -Action $onJobFinish}# access all results that have been received thus far$global:results | Format-Table

Update

You can also do something like this where you just add all the jobs to a single collection and perform a loop while they are running/have data. You can output data as it is available this way instead of having to wait for job completion.

$jobs = @()$jobs += Invoke-Command -ScriptBlock $sb -ComputerName $computers -AsJob$jobs += Start-Job -ScriptBlock $sb2$jobs += Start-ThreadJob -ScriptBlock $sb3$results = [System.Collections.ArrayList]::new()while ($jobs | Where-Object {         $_.State -notin @('Completed', 'Failed', 'Stopped', 'Suspended', 'Disconnected')     }) {    $localData = $jobs | Receive-Job    $localData | Format-Table    $results.Add($localData) | Out-Null    Start-Sleep -Seconds 1}# Add one more collection of data for good measure$localData = $jobs | Receive-Job$localData | Format-Table$results.Add($localData) | Out-Null