'How do I sort a string by its numerical value in PowerShell
I'm trying to create a script that will list the servers I need to list along with the latency returned from each server, I need the list to be in ascending or descending order based on ping.
What I've come up with so far has given basically what I want, but if the ping returned is above 100 on one server, the other values are considered to be higher if they start with a value higher than 1.
I understand that I need the ping value returned as an integer, but I haven't been able to figure out exactly how to accomplish that with out removing the server name.
Anyway, here's what I've come up with so far
function TestNetwork {
$global:array = @("<ServerName>:<ipaddress>"; "<ServerName>:<ipaddress>"; "<ServerName>:<ipaddress>")
foreach ($str in $global:array) {
$avg = 0
$server = $($str -split ":")[0]
$PingServer = Test-Connection -Count 3 $server
$avg = ($PingServer | Measure-Object ResponseTime -Average)
$calc = [System.Math]::Round($avg.Average)
$output = "{000} | " -f $($calc) + $server
$Output
}
}
TestNetwork | Sort numerical -Descending `
and here are the results I get
75 | Server 73 | Server 110 | Server
Solution 1:[1]
Here is an alternative to the way you are doing things that will give output that can be sorted and formatted more easily:
function Test-Network
{
$array = ("<ServerName>","<ipaddress>"), ("<ServerName>","<ipaddress>"), ("<ServerName>","<ipaddress>")
$array | ForEach-Object {
[PsCustomObject]@{
AvgResponse = [Math]::Round((Test-Connection -Count 3 $_[0] | Measure-Object ResponseTime -Average).Average)
Server = $_[0]
}
}
}
Test-Network |
Sort-Object AvgResponse -Descending
Output will look like this:
AvgResponse Server
----------- ------
363 server1
12 server2
2 server3
The nice thing about outputting custom objects like this rather than strings is that you can then use further PowerShell techniques on the output, such as sorting, grouping, etc.
Note a couple of other points:
- Unless you intend to use your array outside the function, there is no need to declare it as 'global'
- Unless you really need the names in the format
"<ServerName>:<ipaddress>", consider storing them differently. I've used an array of arrays, which makes it easier to work with in this case as you avoid having to split a string each time. - You should name your functions according to the PowerShell Verb-Noun naming standard, so
Test-Network, rather thanTestNetwork.
Solution 2:[2]
Cast string to integer
TestNetwork | Sort {[int]($_.numerical)} -Descending
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | boxdog |
| Solution 2 | hamletmun |
