Powershell – Use Speedtest CLI to Monitor Broadband speeds – Part 1

Powershell – Use Speedtest CLI to Monitor Broadband speeds – Part 1

After having some speed issues I wanted to create a script to document these into an easy to access table that I could see what was happening. So rather than reinventing the wheel, Ookla offer a Python application that will display your internet speeds from the commandline… if thats your wish; and in my case, it was!

My main wants in this were:

  • Create a PowerShell script to get the information I wanted
  • Output the results to a CSV
  • Use scheduled Tasks to run the script hourly
  • Upload the results to a local web server and display in a HTML table

So to do this I first of all found a script online and set about butchering it… that can be found here!

While this script was complete it didnt suit exactly what I wanted to do. Especially when using the JSON files.

First as with the majority of my scipts I set my working directory so that I’m not looking all over the place for any source files required.

[powershell]
Push-LocationĀ (Split-PathĀ -pathĀ $MyInvocation.MyCommand.DefinitionĀ -Parent)
[/powershell]

The next notable part is lifted from the script above for the installation of the CLI module:

[powershell]
# Check for Speedtest CLI install, if not exist, download and install.
# Replace the Download URL to where you’ve uploaded the ZIP file yourself. We will only download this file once.
# Latest version can be found at: https://www.speedtest.net/nl/apps/cli
Write-Host "Checking for Speedtest CLI…" -ForegroundColor Black -BackgroundColor Green
$DownloadURL = "https://bintray.com/ookla/download/download_file?file_path=ookla-speedtest-1.0.0-win64.zip"
$DownloadLocation = "$($Env:ProgramData)\SpeedtestCLI"
try {
$TestDownloadLocation = Test-Path $DownloadLocation
if (!$TestDownloadLocation) {
Write-Host "Does not Exist, retreiving…" -ForegroundColor Black -BackgroundColor Yellow
new-item $DownloadLocation -ItemType Directory -force
Invoke-WebRequest -Uri $DownloadURL -OutFile "$($DownloadLocation)\speedtest.zip"
Expand-Archive "$($DownloadLocation)\speedtest.zip" -DestinationPath $DownloadLocation -Force
}
}
catch {
write-host "The download and extraction of SpeedtestCLI failed. Error: $($_.Exception.Message)" -ForegroundColor Black -BackgroundColor Red
exit 1
}
[/powershell]

We want to get the information from the command to append into a CSV in the format that we want:

[powershell]
# Get Speedtest Data Append to CSV
Write-Host "Running Speedtest…" -ForegroundColor Black -BackgroundColor Green
$SpeedtestResults = & "$($DownloadLocation)\speedtest.exe" –format=csv
$SpeedtestResults >> c:\Speedtests\SpeedTestsNonFormatted.csv
[/powershell]

This displays the speeds in bytes, I wanted this to be closer to MB, as my lowly broadband connection hasn’t gotten to the GB levels yet, and I’m not willing to pay for it!
So I create a PSObject to be read the last line in from this CSV and format the output to the final CSV. I have also dropped some columns from the CSV as I feel they are not needed.

[powershell]
Write-Host "Amending Formatting…" -ForegroundColor Black -BackgroundColor Green
# Format the bytes to MB
$csv = Import-Csv c:\Speedtests\SpeedTestsNonFormatted.csv | Select-Object -Last 1 | ForEach-Object {
[PSCustomObject]@{
‘Date and Time’ = $date
‘Server Name’ = $_.’server name’
‘Server ID’ = $_.’server ID’
‘Latency’ = $_.latency
‘Jitter’ = $_.jitter
‘Packet Loss’ = $_.’packet loss’
‘Download’ = [math]::round($_.download/1MB,2)*10
‘Upload’ = [math]::round($_.upload/1MB,2)*10
‘Download Bytes’ = [math]::round($_.’download bytes’/1MB,2)*10
‘Upload Bytes’ = [math]::round($_.’upload bytes’/1MB,2)*10

}
} | Export-Csv c:\SpeedTests\Speedtest.csv -Append -NoClobber -NoTypeInformation
[/powershell]

And thats it, we have our CSV to do what we will with! I will include what I done with this in another post.

The complete script can be found below:

[powershell]

# SpeedTest Script to record Internet speeds on an hourly basis via a scheduled task
# and record to a CSV file, that can be uploaded to a web server and displayed into
# a HTML Table.

# Loosly adapted from: https://www.cyberdrain.com/monitoring-with-powershell-monitoring-internet-speeds/

# Set Working Dir
Push-LocationĀ (Split-PathĀ -pathĀ $MyInvocation.MyCommand.DefinitionĀ -Parent)

$date = Get-Date -Format dd-MM-yyyy_HH:mm

# Check for Speedtest CLI install, if not exist, download and install.
# Replace the Download URL to where you’ve uploaded the ZIP file yourself. We will only download this file once.
# Latest version can be found at: https://www.speedtest.net/nl/apps/cli
Write-Host "Checking for Speedtest CLI…" -ForegroundColor Black -BackgroundColor Green
$DownloadURL = "https://bintray.com/ookla/download/download_file?file_path=ookla-speedtest-1.0.0-win64.zip"
$DownloadLocation = "$($Env:ProgramData)\SpeedtestCLI"
try {
$TestDownloadLocation = Test-Path $DownloadLocation
if (!$TestDownloadLocation) {
Write-Host "Does not Exist, retreiving…" -ForegroundColor Black -BackgroundColor Yellow
new-item $DownloadLocation -ItemType Directory -force
Invoke-WebRequest -Uri $DownloadURL -OutFile "$($DownloadLocation)\speedtest.zip"
Expand-Archive "$($DownloadLocation)\speedtest.zip" -DestinationPath $DownloadLocation -Force
}
}
catch {
write-host "The download and extraction of SpeedtestCLI failed. Error: $($_.Exception.Message)" -ForegroundColor Black -BackgroundColor Red
exit 1
}
# Check for Non Formatted CSV, if its not there create it
Write-Host "Checking if CSV Exists, continuing…" -ForegroundColor Black -BackgroundColor Yellow
If(Test-Path c:\Speedtests\SpeedTestsNonFormatted.csv){
Write-Host "CSV Exists, continuing…" -ForegroundColor Black -BackgroundColor Green
}
else{
Write-Host "Creating CSV File and Headers" -ForegroundColor Black -BackgroundColor Yellow
‘"Server name","Server id","Latency","Jitter","Packet loss","Download","Upload","Download bytes","Upload bytes"’ > c:\Speedtests\SpeedTestsNonFormatted.csv}

# Get Speedtest Data Append to CSV
Write-Host "Running Speedtest…" -ForegroundColor Black -BackgroundColor Green
$SpeedtestResults = & "$($DownloadLocation)\speedtest.exe" –accept-gdpr –accept-license –format=csv
$SpeedtestResults >> c:\Speedtests\SpeedTestsNonFormatted.csv

Write-Host "Amending Formatting…" -ForegroundColor Black -BackgroundColor Green
# Format the bytes to MB
$csv = Import-Csv c:\Speedtests\SpeedTestsNonFormatted.csv | Select-Object -Last 1 | ForEach-Object {
[PSCustomObject]@{
‘Date and Time’ = $date
‘Server Name’ = $_.’server name’
‘Server ID’ = $_.’server ID’
‘Latency’ = $_.latency
‘Jitter’ = $_.jitter
‘Packet Loss’ = $_.’packet loss’
‘Download’ = [math]::round($_.download/1MB,2)*10
‘Upload’ = [math]::round($_.upload/1MB,2)*10
‘Download Bytes’ = [math]::round($_.’download bytes’/1MB,2)*10
‘Upload Bytes’ = [math]::round($_.’upload bytes’/1MB,2)*10

}
} | Export-Csv c:\SpeedTests\Speedtest.csv -Append -NoClobber -NoTypeInformation

[/powershell]

3 Comments

  1. Dan Tartaglia

    Hi,
    When I run your code, Speedtest.csv only has the date and server data. The rest is blank or 0. SpeedTestsNonFormatted.csv has the ā€˜speedtestā€™ data though. Iā€™m new with Powershell but do you know why this is happening?
    Thanks!

    • Niall

      Hi Dan,

      Let me check the code, I’ve had a few issues with the formatting on the site let me check it and get back to you!

    • Niall

      Dan I have updated the code to include –accept-gdpr –accept-license, hopefully this should solve your issue šŸ™‚

Leave a Reply to Dan Tartaglia Cancel reply

Your email address will not be published. Required fields are marked *