Internet speed test in Powershell

Ever wanted to run an internet speed test in Powershell? It’s actually pretty straight forward to do, with a basic download and a little bit of (automated) maths you can run download/upload speed tests in Powershell. The scripts can then be modified to alert you if your speed doesn’t meet your minimum expected speed.

 

There are two scripts below. The first will run a download and an upload speed test then output the results in the power shell window. The second will do the same, but also email the specified email address if the results are below your set minimum speed – this can then be run on schedule so you’ll be notified of any degraded performance, ideal for monitoring problematic connections.

 

Both examples are capable of running via a proxy server, however if you don’t want to use the proxy option, simply comment out the lines labelled by putting # at the beginning of the line or delete them completely.

Basic Download/Upload Speed Test Script
#FILE TO DOWNLOAD
$downloadurl = "URL TO TEST DOWNLOAD FILE"
$UploadURL = "URL TO TEST UPLOAD LOCATION"

#SIZE OF SPECIFIED FILE IN MB (adjust this to match the size of your file in MB)
$size = 100

#PROXY DETAILS
$proxy = "http://PROXY-SERVER:PORT"  #Comment out this line to not use a proxy

#___________________________________________________________________
#    DO NOT EDIT BELOW THIS LINE UNLESS COMMENTING OUT THE PROXY
#___________________________________________________________________

#WHERE TO STORE DOWNLOADED FILE
$documents = [Environment]::GetFolderPath("MyDocuments")
$localfile = "$documents/100mb.bin"


#RUN DOWNLOAD
$downloadstart_time = Get-Date
#$WebClientProxy = New-Object System.Net.WebProxy($proxy,$true)  #Comment out this line to not use a proxy
$webclient = New-Object System.Net.WebClient
#$webclient.proxy = $WebClientProxy  #Comment out this line to not use a proxy
$webclient.DownloadFile($downloadurl, $localfile)

#CALCULATE DOWNLOAD SPEED
$downloadtimetaken = $((Get-Date).Subtract($downloadstart_time).Seconds)
$downloadspeed = ($size / $downloadtimetaken)*8
Write-Output "Time taken: $downloadtimetaken second(s)   |   Download Speed: $downloadspeed mbps"

#___________________________________________________________________

#RUN UPLOAD
$uploadstart_time = Get-Date
$webclient.UploadFile($UploadURL, $localfile) > $null;

#CALCULATE UPLOAD SPEED
$uploadtimetaken = $((Get-Date).Subtract($uploadstart_time).Seconds)
$uploadspeed = ($size / $uploadtimetaken) * 8
Write-Output "Time taken: $uploadtimetaken second(s)   |   Upload Speed: $uploadspeed mbps" 

#___________________________________________________________________

#DELETE TEST DOWNLOAD FILE
Remove-Item –path $localfile
Download/Upload Speed Test Script with Notifications
#SITE NAME
$site = "INSERT NAME WHERE TEST IS RUN HERE FOR EMAIL"

# MINIMUM ACCEPTED THRESHOLD IN mbps (adjust this to match your minimum accepted speeds mbps)
$mindownloadspeed = 500
$minuploadspeed = 500

# FILE TO DOWNLOAD
$downloadurl = "URL TO TEST DOWNLOAD FILE"
$UploadURL = "URL TO TEST UPLOAD LOCATION"

# SIZE OF SPECIFIED FILE IN MB (adjust this to match the size of your file in MB)
$size = 100

# PROXY DETAILS
$proxy = "http://PROXY-SERVER:PORT" #Comment out this line to not use a proxy

# SMTP SETTINGS FOR EMAIL
$recipient = "EMAIL ADDRESS TO RECEIVE ALERTS"
$smtpserver = "SMTP SERVER"
$SmtpSettings = @{
To = "$recipient"
From = "EMAIL TO SEND AS"
Priority = "High"
Subject = "Low Speed Test @ $site"
SmtpServer = "$smtpserver"
}

#___________________________________________________________________
# DO NOT EDIT BELOW THIS LINE UNLESS COMMENTING OUT THE PROXY
#___________________________________________________________________


# WHERE TO STORE DOWNLOADED FILE
$documents = [Environment]::GetFolderPath("MyDocuments")
$localfile = "$documents/100mb.bin"

# WEB CLIENT VARIABLES
#$WebClientProxy = New-Object System.Net.WebProxy($proxy,$true) #Comment out this line to not use a proxy
$webclient = New-Object System.Net.WebClient
#$webclient.proxy = $WebClientProxy #Comment out this line to not use a proxy

#___________________________________________________________________

#RUN DOWNLOAD
$downloadstart_time = Get-Date
$webclient.DownloadFile($downloadurl, $localfile)

#CALCULATE DOWNLOAD SPEED
$downloadtimetaken = $((Get-Date).Subtract($downloadstart_time).Seconds)
$downloadspeed = ($size / $downloadtimetaken)*8
Write-Output "Time taken: $downloadtimetaken second(s) | Download Speed: $downloadspeed mbps"

#___________________________________________________________________

#RUN UPLOAD
$uploadstart_time = Get-Date
$webclient.UploadFile($UploadURL, $localfile) > $null;

#CALCULATE UPLOAD SPEED
$uploadtimetaken = $((Get-Date).Subtract($uploadstart_time).Seconds)
$uploadspeed = ($size / $uploadtimetaken) * 8
Write-Output "Time taken: $uploadtimetaken second(s) | Upload Speed: $uploadspeed mbps"

#___________________________________________________________________

#SEND EMAIL IF BELOW MINIMUM THRESHOLD 
if ($downloadspeed -gt $mindownloadspeed) { Write-Output "Speed is acceptable"}
else { Send-MailMessage @SmtpSettings -Body "Current download speed at $Site is $downlaodspeed mbps which is below the minimum threshold of $mindownloadspeed mbps" -ErrorAction Stop }

#___________________________________________________________________

#SEND EMAIL IF UPLOAD BELOW MINIMUM THRESHOLD 
if ($uploadspeed -gt $minuploadspeed) { Write-Output "Speed is acceptable" }
else { Send-MailMessage @SmtpSettings -Body "Current upload speed at $Site is $uploadspeed mbps which is below the minimum threshold of $minuploadspeed mbps" -ErrorAction Stop }

#DELETE TEST DOWNLOAD FILE
Remove-Item –path $localfile
Modifications

There are various modifications that could be made to this script, but it’s something I wrote quickly to allow me to run an Internet speed test in PowerShell quickly. A couple of ideas I have had but not yet had time to add are:

  • Add a progress bar for the upload and download.
  • Calculate the download size automatically so it doesn’t need to be entered into the script.
  • Add multiple download options so the script can be a portable script that you simply run, then choose the download size.
  • Add a little calculation to the email showing how much below the minimum threshold the speed actually is.

 

Test Download Files

If you can’t or don’t want to host them yourself, they can be downloaded from either Think Broadband or Hetzner in a variety of sizes.

 

4 comments on Internet speed test in Powershell

  1. hello,

    I like the script and am trying to modify it to be used with our RMM system, I have got the download working fine and it reports no errors in the RMM, however I can figure out how to do the upload, where should I upload to? Should I just create a directory which is open to the world and upload to there?

    Thanks,
    Daniel

    1. Hi Daniel, in short yes. It’s probably not seen as the ideal way of doing things from a security perspective but I guess you could lock the upload down by IP or implement a username and password into the script for the upload depending on your web server’s configuration. What RMM are you using out of interest?

      I’ve also found with the host I tested this on (1&1/IONOS – not who I use for my blog by the way!) the upload test worked with standard read only permissions. Despite the upload actually failing, the upload speed result came back correct (presumably 1&1’s server received the file before denying it).

  2. Hello,

    getting this error:

    PS C:\script> ./BasicSpeedTest.ps1
    At C:\script\BasicSpeedTest.ps1:78 char:15
    + Remove-Item –path $localfile
    + ~~~~~~~~~~~~~~~~
    The string is missing the terminator: “.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

    1. Apologies for the delayed reply, your comment was flagged as spam!

      I would check the $localfile = “$documents/100mb.bin” section of the code and ensure the file path has the correct quotation marks (“) around them. Depending on your chosen text editor, these are sometimes converted when copying from a webpage or RTE.

      It’s also worth checking any other sections of the code for the same thing as they’re likely have all copied over the same.

Leave a Reply