Testing Network Bandwidth with PowerShell and iPerf
One of the first steps to diagnose network issues, especially nowadays when so many people are working from home, is to run a speed test. Testing speed by going visiting one of the many speed tests sites is useful, but what if you want to automate the process of testing speed? What if you have an RMM that enables you to run scripts directly from the RMM console, like Atera?
Enter iPerf, a super handy throughput testing tool to run bandwidth tests from command line. I like iPerf over some other tools, because it is entirely run from a single EXE. No need for Python or anything else installed to be able to run it.
Once you download and unpack the iPerf binary, it's easy to run a test. Just open command prompt, navigate to where the iPerf binary is and run it against a iPerf server. Since it can be tricky to get access to the public servers listed on the iPerf website, I spun up my own server in Azure to test against:
> iperf3.exe --client iperf.cageops.com --port 5210
Connecting to host iperf.cageops.com, port 5210
[ 4] local 192.168.86.115 port 31659 connected to 20.51.231.242 port 5210
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.01 sec 512 KBytes 4.17 Mbits/sec
[ 4] 1.01-2.02 sec 256 KBytes 2.08 Mbits/sec
[ 4] 2.02-3.00 sec 512 KBytes 4.25 Mbits/sec
[ 4] 3.00-4.02 sec 640 KBytes 5.17 Mbits/sec
[ 4] 4.02-5.02 sec 768 KBytes 6.26 Mbits/sec
[ 4] 5.02-6.01 sec 896 KBytes 7.44 Mbits/sec
[ 4] 6.01-7.01 sec 512 KBytes 4.21 Mbits/sec
[ 4] 7.01-8.01 sec 512 KBytes 4.19 Mbits/sec
[ 4] 8.01-9.00 sec 768 KBytes 6.32 Mbits/sec
[ 4] 9.00-10.01 sec 768 KBytes 6.22 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-10.01 sec 6.00 MBytes 5.03 Mbits/sec sender
[ 4] 0.00-10.01 sec 5.88 MBytes 4.93 Mbits/sec receiver
iperf Done.
The output of iPerf is pretty easy top understand. The default options run for 10 seconds and gives you the running average every second. At the end, you can see the final result. The confusing part that I ran into initially was that I expected it to give me both my download and upload speed. Running the default options effectively shows you your upload speed.
To get an accurate download speed, you just need to add the --reverse
option, which sends data from the server to your PC:
> iperf3.exe --client iperf.cageops.com --port 5210 --reverse
Connecting to host iperf.cageops.com, port 5210
Reverse mode, remote host iperf.cageops.com is sending
[ 4] local 192.168.86.115 port 31689 connected to 20.51.231.242 port 5210
[ ID] Interval Transfer Bandwidth
...
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 14.6 MBytes 61.1 Mbits/sec 0 sender
[ 4] 0.00-10.00 sec 12.8 MBytes 53.5 Mbits/sec receiver
This is closer to what I expect, but still not quite right. The last thing I figured out with iPerf is that unlike most web browsers, iPerf defaults to run single threaded, meaning that it is not utilizing all the benefits of our modern fancy CPUs.
Lucky for us, all we have to do is add the --parallel N
option with however many threads we want to run. I've found 10 threads to be a nice amount that doesn't overwhelm the CPU:
iperf3 --client iperf.cageops.com --port 5210 --reverse --parallel 10
...
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 41.1 MBytes 34.4 Mbits/sec 1 sender
[ 4] 0.00-10.00 sec 38.8 MBytes 32.5 Mbits/sec receiver
[ 6] 0.00-10.00 sec 35.5 MBytes 29.8 Mbits/sec 0 sender
[ 6] 0.00-10.00 sec 33.4 MBytes 28.0 Mbits/sec receiver
[ 8] 0.00-10.00 sec 37.0 MBytes 31.0 Mbits/sec 19 sender
[ 8] 0.00-10.00 sec 34.8 MBytes 29.2 Mbits/sec receiver
[ 10] 0.00-10.00 sec 36.6 MBytes 30.7 Mbits/sec 23 sender
[ 10] 0.00-10.00 sec 34.4 MBytes 28.8 Mbits/sec receiver
[ 12] 0.00-10.00 sec 39.8 MBytes 33.4 Mbits/sec 1 sender
[ 12] 0.00-10.00 sec 37.5 MBytes 31.5 Mbits/sec receiver
[ 14] 0.00-10.00 sec 36.7 MBytes 30.8 Mbits/sec 25 sender
[ 14] 0.00-10.00 sec 34.5 MBytes 29.0 Mbits/sec receiver
[ 16] 0.00-10.00 sec 40.5 MBytes 33.9 Mbits/sec 0 sender
[ 16] 0.00-10.00 sec 38.2 MBytes 32.0 Mbits/sec receiver
[ 18] 0.00-10.00 sec 35.3 MBytes 29.6 Mbits/sec 0 sender
[ 18] 0.00-10.00 sec 34.3 MBytes 28.8 Mbits/sec receiver
[ 20] 0.00-10.00 sec 37.6 MBytes 31.5 Mbits/sec 0 sender
[ 20] 0.00-10.00 sec 35.4 MBytes 29.7 Mbits/sec receiver
[ 22] 0.00-10.00 sec 39.7 MBytes 33.3 Mbits/sec 0 sender
[ 22] 0.00-10.00 sec 37.7 MBytes 31.6 Mbits/sec receiver
[SUM] 0.00-10.00 sec 380 MBytes 318 Mbits/sec 69 sender
[SUM] 0.00-10.00 sec 359 MBytes 301 Mbits/sec receiver
Whoa! That's a lot more output. The output now shows the total of each thread and then the sum of all of the threads at the bottom. ~300Mbps is what I expect to see with my ISP.
So now for a bonus script that you can run from your RMM tool of choice to get your download and upload speed without ever having to actually remote into the end PC.
###
# Author: Dave Long <dlong@cagedata.com>
# Gets an bandwidth test using iPerf3. Sum is the download speed of computer.
###
$iPerfDownload = "https://iperf.fr/download/windows/iperf-3.1.3-win64.zip"
$DownloadLocation = Join-Path $env:TEMP "iperf.zip"
$iPerfPath = Join-Path $env:TEMP "iperf"
if (!(Test-Path $iPerfPath)) {
Invoke-WebRequest -Uri $iPerfDownload -OutFile $DownloadLocation
Expand-Archive -Path $DownloadLocation -DestinationPath $iPerfPath
}
Set-Location (Join-Path $iPerfPath "iperf-3.1.3-win64")
$Download = & .\iperf3.exe --client iperf.cageops.com --port 5210 --parallel 10 --reverse
if (($Download | Select-Object -Last 1) -eq "iperf Done.") {
Write-Host "Download Speed"
$Download | Select-Object -Last 4 | Select-Object -First 2 | Write-Host
} else {
Write-Host "iPerf failed to get download speed."
}
$Upload = & .\iperf3.exe --client iperf.cageops.com --port 5210 --parallel 10
if (($Upload | Select-Object -Last 1) -eq "iperf Done.") {
Write-Host "Upload Speed"
$Upload | Select-Object -Last 4 | Select-Object -First 2 | Write-Host
} else {
Write-Host "iPerf failed to get upload speed."
}
Stay tuned for my next post on how to test network speeds across a local network by running the iPerf server locally.