5
$data = @("server1","server2","server3")

foreach ($server in $data) {
    $results = (Test-Connection $server -count 1 | Measure-Object -Property ResponseTime -Average).Average
}

I'm trying to figure out how to take the output of a ForEach and store the results into an array so I may then compare them later. I could not come up with a way to do this yet.

Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
Aaron
  • 3,135
  • 20
  • 51
  • 78
  • 7
    `$results = @( ForEach ( ... ) { ... } )` – user4003407 Feb 07 '17 at 17:39
  • @PetSerAl, whats the difference between `$results = @( foreach ...)` and `$results = foreach ...`, doesn't it return array anyway? also, shouldn't `foreach` return something, for this to work? – 4c74356b41 Feb 07 '17 at 17:57
  • @4c74356b41 `@()` always return array. Even in case of zero or one item. – user4003407 Feb 07 '17 at 17:59
  • so how does a zero length array help compare results? – 4c74356b41 Feb 07 '17 at 18:02
  • @4c74356b41 It helps by eliminating special case, when with zero items PowerShell does not return array by default. – user4003407 Feb 07 '17 at 18:17
  • yes, i understand that, but the goal of this person is to compare the results to something, not get an array, if the `foreach` doesn't return anything, he won't get what he wants, right? – 4c74356b41 Feb 07 '17 at 18:19
  • @4c74356b41 Sorry, I do not understand your point. I can ask it other way: Is any benefit of not using `@()`, apart of saving three keystrokes? My default is to use `@()`, when I expect multiple return from the statement, just to be on safe side, especially in reusable scripts. And, BTW, `compare 1,2,3 @()` vs `compare 1,2,3 $null`. – user4003407 Feb 07 '17 at 18:57
  • welp, I was talking about the fact, that you should actually return some data in the `foreach` loop, else you will always get empty array as a result? his example doesn't return anything, so... he will always get empty array, even if he actually pings something. – 4c74356b41 Feb 07 '17 at 19:01

2 Answers2

3
    $FinalResult = @()
    $data = @("server1","server2","server3")
    foreach ($server in $data) {
        $results = (Test-Connection $server -count 1 | Measure-Object -Property ResponseTime -Average).Average

        $FinalResult += New-Object psobject -Property @{
                        ServerName = $server
                        Result = $result
                        }  
    }
   $FinalResult | Select ServerName, Result | Export-Csv ".\FinalResult.csv" -NoTypeInformation

Please let me know if this snippet doesn't work, i will do the needful.

Ajay Pawar
  • 179
  • 6
  • 1
    This is extremely inefficient because appending creates a new array every single loop, resulting in a time complexity of O(n^2). – Strill Apr 11 '23 at 21:14
1

By doing the ForEach, you're just measuring the value of the property of a scalar (single) object. The average will always be just the value of that property.

Test-Connection will accept an array of names as the -ComputerName parameter, so the ForEach isn't really necessary at all.

 $data = @("server1","server2","server3")

 $results = Test-Connection $data -count 1 | select -ExpandProperty ResponseTime
Myrddin Emrys
  • 42,126
  • 11
  • 38
  • 51
mjolinor
  • 66,130
  • 7
  • 114
  • 135
  • I used the example to get the concept of what I'm doing. I'm not using Test-Connection, but a more larger script, but the concept is the same. Just need to figure out how to store results into an array while having it loop until there's no more inputs. – Aaron Feb 07 '17 at 20:17
  • Then you already have your answer in the comments. Simply redirect the foreach output to a variable, and Powershell will automatically build an array if it returns more than one object. You can force it to be an array using the @() syntax if that's necessary to prevent errors downstream in the case of it not returning multiple objects. – mjolinor Feb 07 '17 at 20:29