Search code examples
powershellforeachparallel-processingparallel.foreach

Powershell 7 -> ForEach -Parallel in a Function does not return anything when the result is added to the array


I need to use Powershell 7 Parallel looping feature in this function but when using ForEach loop, I cannot take the result and put it into the array at the end and I do not undestand why.

Any ideas?

Function Get-ResponseFromParallelPings($activeHops) {
    $ArrayOfObjects = @()

    $activeHops | ForEach-Object -Parallel {
        $count = 5
        $LatencyNumber = 0
        $SuccessNumber = 0
        $Answer = Test-Connection -count $count -targetname $_.Name -delay 1

        foreach ($a in $Answer) {
            $LatencyNumber += $a.Latency / $count
            if ($a.Status -eq "Success") {
                $IncreaseBy = 100 / $count
                $SuccessNumber += $IncreaseBy
            }        
        }  
        $myObject = [PSCustomObject]@{
            DestinationIP  = $_.Name
            AverageLatency = $LatencyNumber
            Success        = $SuccessNumber 
        }
        $arrayOfObjects += $myObject # <- This line does not work for me.
    }
    return $arrayOfObjects
}

Solution

  • The problem here is that threads running in parallel have to alter the same array. There are methods to make that happen, but in this case it is enough to just emit $myobject from the function. I removed the array and the code to add $myObject to the array.

    When the function is called the array is created automatically, so the result is the same.

    Function Get-ResponseFromParallelPings($activeHops) {
        $activeHops | ForEach-Object -Parallel {
            $count = 5
            $LatencyNumber = 0
            $SuccessNumber = 0
            $Answer = Test-Connection -count $count -targetname $_.Name -delay 1
    
            foreach ($a in $Answer) {
                $LatencyNumber += $a.Latency / $count
                if ($a.Status -eq "Success") {
                    $IncreaseBy = 100 / $count
                    $SuccessNumber += $IncreaseBy
                }        
            }  
            $myObject = [PSCustomObject]@{
                DestinationIP  = $_.Name
                AverageLatency = $LatencyNumber
                Success        = $SuccessNumber 
            }
            $myObject
        }
    }