Internet Speed Test
Aymen E.
The script uses the speedtest.exe application from to generate the result.
the script downloads the application directly from , extracts the file into C:\temp and then displays the result.
Here’s the result :
and here’s the script :
Aymen EL JAZIRI
Explore topics
To conduct an internet speed test using PowerShell, you can leverage the Test-NetConnection cmdlet to measure the latency and the Test-Connection cmdlet to assess the network connectivity. By combining these cmdlets with other PowerShell functionalities, you can create a custom script that not only tests the internet speed but also stores the results for future analysis.
Here’s an example of a basic PowerShell script to conduct an internet speed test:
$startTime = Get-Date
$webClient = New-Object System.Net.WebClient
$fileURL = “http://speedtest.tele2.net/100MB.zip”
$endTime = Get-Date
$duration = $endTime — $startTime
Write-Host “Download Speed: $speed MB/s”
This script initiates a download from a known source (in this case, “http://speedtest.tele2.net/100MB.zip”), measures the time it takes to complete the download, and calculates the download speed in megabytes per second (MB/s).
By running this script, you can quickly evaluate your internet connection’s download speed using PowerShell. You can further expand this script to include additional metrics, such as upload speed, latency, and packet loss, providing a comprehensive assessment of your network performance.
Utilizing PowerShell for internet speed testing offers the advantage of automation, customization, and integration with existing infrastructure monitoring tools. Whether for personal use or in a professional setting, this capability enables efficient and detailed evaluations of internet connections.
Для онлайн тестирования скорости интернета существуют большое количество онлайн-сервисов. Если вам нужно периодически собирать метрики скорости Интернет-подключения от провайдера для системы мониторинга, можно воспользоваться широко известной консольный клиент Speedtest от Ookla. В этой статье, мы рассмотрим, как измерить скорость Интернет-подключения из командной строки Windows (скрипта PowerShell).
Чтобы автоматически протестировать скорость скачивания/загрузки сети до ближайшей к вам локации с сервисом Speedtest, выполните команду:

Утилита вернет скорость скачивания, загрузки (в Мбит/с), сетевые задержки с вашего компьютера до ближайшего сервера Speedtest. Если сервер расположен близко к вам (а их действительно очень много), условно это и будет вашей скоростью Интернета.
Можно вручную выбрать провайдера, страну и город с сервером Speedtest, до которого нужно тестировать подключение. Выведите список ближайших точек и скопируйте ID:
Выполнить тестирование до выбранного сервера:
.\speedtest.exe -s 37149

Утилита speedtest позволяет возвращать результаты в структурированных форматах (CSV, JSON, TSV), что удобно, когда вам нужно дополнительно извлечь данные из результатов или отправить результату проверки в систему мониторинга.
Например, чтобы получить результаты тестирования скорости Интернета из скрипта PowerShell:
$speedtestcmd = & "C:\ps\Speedtest\speedtest.exe" --accept-license -s 37149 -f json
Вы можете передать результаты тестировании скорости интернета в виде метрик в вашу систему мониторинга (как получить данные в Zabbix из PowerShell скрипта).
В локальной сети можно протестировать пропускную способность сети между двумя машинами можно с помощью утилиты iperf.
Many online services allow you to test your Internet connection speed in real-time. If you need to regularly collect Internet connection speed metrics from your provider for monitoring, you can use the popular Speedtest console client from Ookla. Let’s look at how to measure the speed of an Internet connection using the Windows command prompt or a PowerShell script.
Download the console speedtest.exe tool for Windows from https://www.speedtest.net/apps/cli and extract it to a local directory.
To automatically test network download and upload speeds to the nearest Speedtest service location, run the command

The tool returns download and upload speeds (in Mbps), network latency from your computer to the nearest Speedtest server. Since there are many SpeedTest locations worldwide, this will be the speed of your internet connection.
You can manually select the ISP, country, and city to test your Internet connection speed to. List the nearest test points and copy the ID:
Run the speed test against the target server:
.\speedtest.exe -s 11787

The speedtest command can return results in structured formats (CSV, JSON, TSV), which is useful if you need to extract additional data from the results or send the test result to the monitoring system.
For example, you can use a PowerShell script to get the results of an Internet speed test:
$speedtestcmd = & "C:\ps\speedtest.exe" --accept-license -s 37149 -f json
$speedtestresult=ConvertFrom-Json $speedtestcmd
$result=[PSCustomObject]@{ Download = [math]::round($speedtestresult.download.bandwidth/1MB, 5)*8 Upload = [math]::round($speedtestresult.upload.bandwidth/1MB, 5)*8
}
$result
You can send the Internet speed test results to your monitoring system as metrics (Getting data into Zabbix from a PowerShell script).
On a local network, you can use the iperf tool to test the network bandwidth between two machines.
Hello Everyone !
#https://www.speedtest.net/apps/cli
cls
$DownloadURL = "https://install.speedtest.net/app/cli/ookla-speedtest-1.0.0-win64.zip"
#location to save on the computer. Path must exist or it will error
$DOwnloadPath = "c:\temp\SpeedTest.Zip"
$ExtractToPath = "c:\temp\SpeedTest"
$SpeedTestEXEPath = "C:\temp\SpeedTest\speedtest.exe"
#Log File Path
$LogPath = 'c:\temp\SpeedTestLog.txt'
#Start Logging to a Text File
$ErrorActionPreference="SilentlyContinue"
Stop-Transcript | out-null
$ErrorActionPreference = "Continue"
Start-Transcript -path $LogPath -Append:$false
#check for and delete existing log files
function RunTest()
{ $test = & $SpeedTestEXEPath --accept-license $test
}
function sendMail ($subject, $message)
{ "Sending Email" #SMTP server name $smtpServer = "smtp.office365.com" $EmailSender = "noreply@yourdomain.com" $emailPassword = "password123_or_monkey" $port = '587' $from = "noreply@yourdomain.com" $to = "you@yourdomain.com" #Creating a Mail object $msg = new-object Net.Mail.MailMessage $emailCredential = New-Object System.Net.NetworkCredential($EmailSender, $emailPassword) #Creating SMTP server object $smtp = new-object Net.Mail.SmtpClient($smtpServer) $smtp.Port = $port $smtp.EnableSSl = $true $smtp.Credentials = $emailCredential #Email structure $msg.From = $from $msg.To.add($to) $msg.subject = $subject $msg.body = $message #Sending email $smtp.Send($msg) write-host "Email Sent" -ForegroundColor Green
};
#check if file exists
if (Test-Path $SpeedTestEXEPath -PathType leaf)
{ Write-Host "SpeedTest EXE Exists, starting test" -ForegroundColor Green RunTest
}
else
{ Write-Host "SpeedTest EXE Doesn't Exist, starting file download" #downloads the file from the URL wget $DownloadURL -outfile $DOwnloadPath #Unzip the file Add-Type -AssemblyName System.IO.Compression.FileSystem function Unzip { param([string]$zipfile, [string]$outpath) [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath) } Unzip $DOwnloadPath $ExtractToPath RunTest
}
#get hostname
$Hostname = hostname
#read results out of log file into string
$MailMessage = (Get-Content -Path $LogPath) -join "`n"
#email results use log file string as body
$MailSubject = $Hostname + " SpeedTest Results"
sendMail $MailSubject $MailMessage
#stop logging
Stop-TranscriptВсем привет! Порой, написать графическую форму для консольного приложения может оказаться очень удобным решением, тем самым не нужно запоминать все ключи программы, особенно, если пользоваться им приходится изредка, тем самым автоматизируя работу с данным приложением в дальнейшем. Но, ситуация может быть обратной, когда приложение имеет только графический интерфейс, а вам нужно получить вывод его работы в консоли, например, для возможности передачи метрик в систему мониторинга. С тех пор как начал проводить все больше времени в консоли, заметил, что становится менее удобно переключаться на ранее привычные инструменты, лишний раз использовать мышь, держать открытыми излишние приложения или вкладки в браузере, особенно, если работаешь на удаленной машине без прямого доступа к графическому интерфейсу. У меня накопилась небольшая коллекция полезных модулей, большинство из которых написаны совсем недавно, успел привыкнуть при регулярном использовании и хотелось бы ими поделиться. Осознавая, что тенденция ухода Windows систем на территории РФ растет, тем не менее думаю еще очень много людей, кто так же как и я продолжают использовать данную систему и автоматизировать свою работу, возможно, представленные модули так же смогут пригодятся. Все модули опубликованы в репозитории на GitHub и менеджере пакетов Nuget, откуда их можно установить одной командой.
PowerShell модуль представляет собой набор функций, которых объединяет между собой файл с расширением psm1 и манифест psd1 (последний не обязателен для работы модуля, нужен для его описания). Модули используют для взаимодействия с приложением или целой системой (например, система хранения TrueNAS, резервного копирования Veeam, виртуализации VMWare или Hyper-V, различными системами баз данных и т.п.), с возможностью повторного применения описанных в нем функций на уровне системы и его массового распространения через менеджеров пакетов. Еще модуль можно воспринимать как cli (интерфейс командной строки) для конкретного приложения, тем самым позволяя взаимодействовать с ним оперируя параметрами в консоли, при этом имея возможность для дальнейшей автоматизации или интеграции с другими сервисами напрямую через язык PowerShell. Например, команда для вывода содержимого файлов в консоли Get-Content, или более привычный для Linux систем псевдоним cat по факту представляет PowerShell функцию, базирующуюся на .NET, которая в свою очередь входит в состав модуля Microsoft.PowerShell.Management.
Console-Translate
На протяжении нескольких лет я пользуюсь переводчиком DeepL практически на ежедневной основе. Меня не всегда устраивает то, что у него есть ограничение в 1500 символов, тем не менее, так как у него есть полноценное десктопное приложение, это удобная альтернатива браузерным решениям, которое всегда под рукой на горячей клавише. Сменив место работы, и получив ограничение в самостоятельной установке какого-либо стороннего программного обеспечения на рабочем ноутбуке, пришлось задуматься в сторону альтернативного и простого решения, так как пользоваться переводчиком и при этом консолью я реже не стал, пришла идея использовать единый интерфейс. Для доступа к переводу текста в консоли можно использовать REST API, к сожалению, получить бесплатный ключ доступа DeepL для России невозможно, но тут можно найти много альтернатив. Во-первых, существует проект DeepLX с открытым исходным кодом, с помощью которого можно запустить свой бесплатный API-сервер, который может быть доступен одновременно нескольким пользователям в сети. Во-вторых, каждый, кто использует расширение Google Translate в своем браузере может перехватить публичный API-ключ (используя интерфейс DevTools во вкладке Network) с возможностью его использования через любой REST-клиент в консоли. И в-третьих, существует немало бесплатных провайдеров для перевода текста с наличием API, например MyMemory, которая содержит одну из крупнейших баз для переводов. Все перечисленные сервисы получилось внедрить в один модуль Console-Translate, который можно установить в своей консоли с помощью одной команды:
Install-Module Console-Translate -Repository NuGetНеобходимо, чтобы предварительно у вас в системе уже был зарегистрирован менеджер пакетов Nuget:
Register-PSRepository -Name "NuGet" -SourceLocation "https://www.nuget.org/api/v2" -InstallationPolicy TrustedСинтаксис простой, в первый параметр передается текст (если вы используете более одного слова, обязательно необходимо заключить весь передаваемый текст в кавычки), второй (через пробел) отвечает на язык назначения, например так:
> Get-Translate "Как дела?"
How are you?
> Get-Translate "Как дела?" de
Wie geht es Ihnen?По умолчанию перевод происходит между Русским и Английским языком в обоих направлениях, с автоматически определением языка на уровне PowerShell. Т.к. на уровне API не всегда хорошо срабатывает определение языка, добавил достаточно простую реализацию, так как акцент сделан на двух языках, каждый раз происходит подсчет переданных букв с разбивкой (методом Char) на русские и английские символы, букв какого из языков окажется больше, тот и будет являться исходным языком, и соответственно второй будет являться языком назначения (пример на скриншоте ниже).
Перевод текста в консоли через PowerShell на Linux и Windows машинах
С появления версии PowerShell Core данный язык является кроссплатформенным, по этой причине модуль будет работать в системе Linux, где я так же часто его использую, как и сам язык в силу привычки.
CrystalDiskInfo
У программы CrystalDiskInfo нет командного интерфейса для прямого взаимодействия через консоль, есть возможность только сформировать файловый отчет, где содержится много лишней информации в текстовом виде. Помимо этого отчета, программа так же хранит информацию в конфигурационных ini-файлах, которые обновляются в процессе сканирования или изменения настроек. Модуль CrystalDisk-Cli читает эти конфигурационные файлы и выводит результат в формате OSObject или Collection (необходимо, что бы программа CrystalDiskInfo уже была установлена). Вывод работы модуля будет выглядеть так:
Установить модуль CrystalDisk-Cli можно также одной командой:
> Install-Module CrystalDisk-Cli -Repository NuGet
> Import-Module CrystalDisk-Cli
> Get-DiskInfo
Name : WD PC SN740 SDDPNQD-1T00-10272243A5454811
Date : 2024/02/19 11:16:48
HealthStatus : 1
Temperature : 48
PowerOnHours : 1010
PowerOnCount : 448
Life : 100
HostWrites : 10322
HostReads : 10092
01 : 0
02 : 0
03 : 0
04 : 0
05 : 0
ReallocatedSectorsCount : 0
06 : 0
07 : 0
08 : 0
09 : 0
0A : 0
0B : 0
0C : 0
0D : 0
0E : 0
0F : 0Если необходимо обновить информацию и получить актуальный отчет, используется параметр Report (если консоль не запущена с правами администратора, при запуске появится окно, которое запросит подтверждение). Само приложение производит автоматическое обновление с заданным промежутком времени, которое можно изменить в настройках программы, например каждые 5 минут, используя команду: Get-DiskInfoSettings -AutoRefresh 5 (при запуске без параметров вернет текущие настройки, для изменения настроек понадобится запустить консоль с правами администратора). Вот пример вывода для нескольких дисков:
Вывод работы модуля CrystalDisk-Cli
Everything
Install-Module PSEverything -Repository NuGet
Find-Everything ".temp" -ComputerName plex-01 -Port 9999 -User every -Password thing # удаленное получение данных
Find-Everything ".temp" # локальное получение данных
$(Find-Everything ".temp").Count # посчитать количество файлов, подходящих под критерии поискаПоиск файлов через модуль PSEverything
Программа не содержит открытый исходный код, перед написанием модуля я ознакомился с правами лицензионного соглашения, которые крайне лояльны, и дают возможность интегрировать данное приложение для своих целей. Мне данный модуль очень мог автоматизировать поиск файлов для нескольких несложных скриптов, что было бы сложнее реализовать средствами PowerShell, не говоря про скорость работы, которая чаще не превышает 200мс (повышенная задержка при большом количестве найденных файлов вызвана не программой, а самим языком при обработке получаемых данных).
SpeedTest
У меня как-то была задача, реализовать мониторинг скорости интернета получаемую от провайдера на регулярной основе. Для примера, можно воспользоваться всеми известным Speedtest от Ookla, у данного сервиса уже присутствует cli-интерфейс, вывод которой можно распарсить, но это не единственный провайдер для предоставления подобный услуги и требует зависимость в виде исполнимого файла. В случае c встроенным Windows PowerShell версии 5.1 есть возможность использовать Internet Explorer через COM интерфейс, тем самым в браузере автоматизировать нажатие кнопок в фоновом режиме и забирать содержимое страницы прямо в консоль, для дальнейшей обработки и вывода в формате объекта, как это реализовано в модуле Ookla-SpeedTest-API. Вот пример:
Get-PackageProvider # проверяем, что провайдер пакетов nuget установлен
Find-PackageProvider # отобразить все допступные менеджеры пакетов
Install-PackageProvider nuget # установить менеджер пакетов nuget
Set-PackageSource nuget -Trusted # разрешаем установки пакетов из указанного источника
Find-Package Ookla-SpeedTest # ищем пакеты по названию во всех менеджерах
Install-Module Ookla-SpeedTest -Scope CurrentUser # установить модуль для текущего пользователя
### Запускаем модуль и забираем метрики
$test = Invoke-SpeedTest
$test | Select-Object date,download,upload
date download upload
---- -------- ------
19.02.2024 14:00:15 37263 19320Измерение скорости интернета через Ookla Speedtest в PowerShell 5.1
Используя такой модуль, можно настроить отправку метрик в базу данных и вывести данные на dashboard Grafana (такой пример с созданием службы есть на GitHub). Хотя данный подход уже является устаревшим, он не требует никаких зависимостей, но при этом не поддерживается в версии PowerShell Core. Для подобных целей правильнее использовать библиотеку Selenium (версии dotNET), например через браузер Chrome/Chromium, подробнее про установку зависимостей и создание модулей я уже писал пост на Habr. Вот пример вывода на примере OpenSpeedTest и LibreSpeedTest:
Измерение скорости интернета через Open и Libre Speedtest в PowerShell Core
Сервер и клиент Syslog
Маловероятно, что вам понадобится запустить сервер для сбора логов на системе Windows, при условии, что чаще для этих целей используют сервера на базе Linux, к тому же имеется достаточно большое количество отличных альтернатив, например Visual Syslog. Но если у вас есть запрет на запуск какого-либо стороннего программного обеспечения на системах Windows (что в моем случае и послужило причиной) или например PowerShell скрипт, события работы которого необходимо настроить для передачи серверу Syslog, данный процесс можно автоматизировать с помощью модуля pSyslog. Для установки и запуска серверной части используйте следующие команды:
Install-Module pSyslog -Scope CurrentUser
Start-pSyslog -Port 514
Get-pSyslog # читает входящие сообщения в реальном времени
Show-pSyslog # читает локальный файловый журналДля отправки сообщения на любой сервер Syslog, используйте команду Send-pSyslog:
Отправка сообщения на сервер Syslog
Серверная и клиентская часть базируются на классе .NET System.Net.Sockets, все источники документации и примеры работы есть в описании репозитория. Модуль поддерживает шифрование Base64, UDP Relay и ротацию локального журнала, который возможно настроить для получения метрик, например, по типу сообщения или содержимому. Протестировано в работе для версии Windows PowerShell на разных билдах до 3-х одновременных клиентов, также работает в версии Core.
Windows API
Модуль ps.win.api – это полноценный REST API и Web сервер на чистом PowerShell, серверная часть которого базируется на классе .NET HttpListener. Про то, как создать такой сервер я уже писал статью на Habr, с тех пор прошло не так много времени, тем не менее функционала стало больше, в том числе добавлен модуль, который позволяет запускать серверную часть в режиме фонового процесса и управлять им, а также он включает в себя большую часть используемых функций с возможностью удаленного взаимодействия с сервером для каждой команды, вывод которых будет одинаковый как для локальной, так и для удаленной машины. Все функции представляют из себя дополненный и более читаемый вывод уже встроенных WMI/CIM команд, результат которых можно получить с удаленный машины через данный модуль в PowerShell, или любой REST-клиент, например curl в Linux, без необходимости конфигурации WinRM или ssh.
Устанавливаем модуль и запускаем серверную часть на одной машине:
Install-Module ps.win.api -Repository NuGet -AllowClobber
Import-Module ps.win.api
Start-WinAPI
Test-WinAPI
Port Status
---- ------
8443 OpenНа удаленной машине предварительно устанавливаем модуль и используем функцию, например, для удаленного и локального просмотра датчиков температуры дисков:
Get-Smart
Get-Smart -ComputerName 192.168.3.100 -User rest -Pass api -Port 8443Пример вывода температуры датчиков на локальной и удаленной Windows машинах
Примеры работы и настройки можно найти в репозитории на GitHub. Также помимо запуска и остановки служб и процессов, добавлен функционал просмотра всех журналов событий Windows через Web-интерфейс с возможностью фильтрации вывода, пример для ssh подключений на скриншоте:
Get-Query
В системе Windows для просмотра в консоли списка текущих авторизованных пользователей, а также запущенных ими процессов присутствует встроенная программа query.exe, которая отдает вывод в текстовом формате. Модуль Get-Query преобразуя вывод команды в формат объекта, что позволяет использовать его для мониторинга активных пользовательских сессий, например, через активного Zabbix-агента, а также с помощью такого модуля (или любого другого подобного модуля в формате PSObject) можно заполнить таблицу DataGridView используемую в Windows Forms, данный подход я использовал в проекте RSA. Пример вывода для одного пользователя:
Install-Module Get-Query
Get-Query
User : lifailon
Session : console
ID : 1
Status : Active
IdleTime : отсутствует
LogonTime : 12.02.2024 13:08Итог
По мимо перечисленных модулей, присутствуют модули на мониторинга Veeam репозиториев и заданий, а так же датчиков температуры системы через Open и LibreHardwareMonitor, статью про последний я также писал на Habr, где упоминал про кастомизацию терминала, используя профили для oh-my-posh. Всего модулей в различных репозитория огромное множество, менеджер Nuget насчитывает больше 392 тысяч пакетов, 30 тысяч из которых составляют модули для PowerShell и библиотеки, которые могут быть интегрированы через платформу .NET. Использование удобных именно для вас модулей заставляет меньше покидать терминал, а времяпровождение в консоли приносит все больше удовольствия, и как мне кажется, формирует полезную привычку в дальнейшем.
Creating the Speed Test Script on Windows#
We will guide you through creating a PowerShell script step-by-step to automate internet speed tests and save the results.
Step 1: Run the Speedtest Command#
Run the speedtest command in PowerShell to see the output:
Step 2: Analyze the Output#
Understand the Output:
- The output will display key metrics like download and upload speeds, latency, and server details.
Speedtest by OoklaServer: Switch Inc. - City, State (id: 14553)Idle Latency: 5.58 ms (jitter: 1.60ms, low: 5.14ms, high: 9.06ms)Download: 90.75 Mbps (data used: 98.5 MB)41.81 ms (jitter: 10.30ms, low: 13.46ms, high: 344.05ms)Upload: 69.28 Mbps (data used: 78.1 MB)345.08 ms (jitter: 86.85ms, low: 23.80ms, high: 624.29ms)Packet Loss: 0.0%Result URL: https://www.speedtest.net/result/c/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxStep 3: Getting Creative#
- Now, let's see what else we can do. Looking at [Speedtest commands](https://gist.github.com/itsChris/6f7a5d59b408f0cb774bf2570137a0ef#file-speedtest-cli-by-ookla-md)
You can also view this locally by running `speeedtest -h` command
notice the `-f format_type –form` for output formats. We want to work with csv so we can combine multiple outputs into the same file for over time comparisonStep 3: Create a Date Folder and Save Results#
Create a folder with the current date and save the speed test results in CSV format:
Creating a Date-Specific Folder:
$dateFolder = (Get-Date).ToString()New-Item -Path $dateFolder -ItemType DirectoryStep 4: Accumulate and Display Multiple Results#
Run the test multiple times and import the CSV data to view it as a table:
Step 5: Automate Daily Speed Tests#
Combine all steps into a script for daily automation:
$dateFolder = (Get-Date).ToString()New-Item -Path $dateFolder -ItemType Directory -ForceThe Breakdown of the Speed test with PowerShell
As we enter this script, you can see my laziness already. The first thing I do is make a string called ctemp for the “c:\temp”. This way I don’t have to type “c:\temp” repeatedly. Next, we test the path to see if c:\temp exists. If it doesn’t, we make it. We do this with the new-item command with the name as temp and the item type as a directory. We do the same thing with c:\temp\speedtest for later. If you really want to get fancy, you can replace the C: with an $env:systemdrive.
Building the folders
$CTemp = "c:\Temp"
if (!(Test-Path $CTemp)) { New-Item -Path "c:\" -Name Temp -ItemType Directory }
if (!(Test-Path "$CTemp\SpeedTest")) { New-Item -Path "c:\" -Name Temp -ItemType Directory }The next step is to download the speed test application from ookla. We need the URL and where it’s going to be downloaded. That’s why the URL has the URL needed. We want to call the file speedtest.zip. Next, we test to see if we already downloaded it. If we didn’t, we download the file using the invoke web request and the out file tags.
Downloading the app
$URL = "https://install.speedtest.net/app/cli/ookla-speedtest-1.0.0-win64.zip"
$DownloadPath = "$CTemp\SpeedTest.Zip"
if (!(Test-Path $DownloadPath)) { Invoke-WebRequest -Uri $URL -OutFile $DownloadPath }Once we have the file downloaded, we need to extract the Speed test files. We use the expand archive command to force the download to the c:\temp\speedtest folder that we made at the beginning. I use the force flag here to overwrite anything just in case the file was already there.
Expanding the drive
#Expand the Zip File Expand-Archive $DownloadPath -DestinationPath "$CTemp\Speedtest" -Force
Next, we run the Speed test with PowerShell. In PowerShell, you can run apps directly inside the shell and input that data directly into the shell by using the & sign. With this software, we need to accept the license if we want to do this script without human interaction. Finally, we want to push its output into a variable. Since it’s a test, let us call it a test.
Running the Speed test with PowerShell
$test = & "$CTemp\Speedtest\speedtest.exe" --accept-license
The variable $test contains a few strings with the information we need. It’s time to work with those strings. The string contains the server, isp, download, upload, and jitter information. Here is an example output of what this little program produces:
Speedtest by Ookla Server: Piedmont Redacted ISP: Spectrum Business Latency: 22.46 ms (0.12 ms jitter) Download: 166.84 Mbps (data used: 217.5 MB) Upload: 194.09 Mbps (data used: 224.6 MB) Packet Loss: 0.0% Result URL: redacted
The first item I want to extract is the download. The code is a little complex so lets start from the inside. We start off with our $test variable. We want to find the string line that contains “Download:” and then trim that up.
($test | where-object { $_ -like "*Download:*" }).trim()The Regex
$ISP = ($test | where-object { $_ -like "*ISP:*" }).trim().split(":")[1].trim()
$server = ($test | where-object { $_ -like "*Server:*" }).trim().split(":")[1].trim()
$SpeedTestURL = ($test | where-object { $_ -like "*Result URL:*" }).trim().split(" ")[2].trim()Now, we need to work with The ISP. We search for the “ISP:” inside our test variable. Like before, we trim up the string. This removes the spaces at the start and end. Then we split this string with the “:”. The split is here because it makes sense. We select the second object from that split as it contains the text. The first, which is also 0, doesn’t contain the text. Now we have the string, we once again trim it up. There you go. That’s the ISP. We do the same thing with the server as the ISP. The results URL is a little different. We split the space and then select the third object.
Displaying the information
Finally, we create a PS custom object and place each piece of useful information into it. When you launch the script, this information will return and you can see it inside your rmm feedback. From here, you can add this information to your RMM tool in custom fields if you wish. Since I use Ninja at the moment, I will go over that later.
That’s it, Speed Test with PowerShell is at your fingertips. I hope you enjoy it.
Installing Speedtest CLI#
Before automating internet speed tests with PowerShell, the Ookla Speedtest CLI must be installed. Here’s how to do it on various operating systems:
Windows Installation#
Download and Install Winget:
- Winget is pre-installed on Windows 11 versions. If you get an error when you type
wingetin PowerShell, follow these steps to install it. - Visit the Winget GitHub releases page
. - Download and open the
Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundlefile and follow the on-screen instructions. - After installation, close and reopen the PowerShell window. Type
wingetto verify the installation.
- Winget is pre-installed on Windows 11 versions. If you get an error when you type
Install Speedtest CLI Using Winget:
winget install --id=Ookla.Speedtest.CLI -e
macOS, Ubuntu/Debian, Fedora/CentOS, FreeBSD Installation#
(Include detailed installation instructions for these operating systems)
Analyzing Your Speed Test Data#
Describe how to use the accumulated data for understanding internet speed trends.
The Script
#Tests if C:Temp Exists, If it doesn't, makes it.
$CTemp = "c:\Temp"
if (!(Test-Path $CTemp)) { New-Item -Path "c:\" -Name Temp -ItemType Directory }
if (!(Test-Path "$CTemp\SpeedTest")) { New-Item -Path "c:\" -Name Temp -ItemType Directory }
#Download the Speed Test Tool.
$URL = "https://install.speedtest.net/app/cli/ookla-speedtest-1.0.0-win64.zip"
$DownloadPath = "$CTemp\SpeedTest.Zip"
if (!(Test-Path $DownloadPath)) { Invoke-WebRequest -Uri $URL -OutFile $DownloadPath }
#Expand the Zip File
Expand-Archive $DownloadPath -DestinationPath "$CTemp\Speedtest" -Force
$test = & "C:\temp\Speedtest\speedtest.exe" --accept-license
$DownloadSpeed = [regex]::match(($test | where-object { $_ -like "*Download:*" }).trim(), '[0-9]+\.?[0-9]*').value
$uploadSpeed = [regex]::match(($test | where-object { $_ -like "*Upload:*" }).trim(), '[0-9]+\.?[0-9]*').value
$ISP = ($test | where-object { $_ -like "*ISP:*" }).trim().split(":")[1].trim()
$server = ($test | where-object { $_ -like "*Server:*" }).trim().split(":")[1].trim()
$SpeedTestURL = ($test | where-object { $_ -like "*Result URL:*" }).trim().split(" ")[2].trim()
[PSCustomObject]@{ Server = $server ISP = $ISP Download = $DownloadSpeed Upload = $uploadSpeed ResultsURL = $SpeedTestURL
}Next Steps#
With this PowerShell script, you’re well-equipped to keep track of your internet speed and network health!
Automating Internet Speed Tests with PowerShell#
Experiencing slow internet speeds can be frustrating. With PowerShell and the Ookla Speedtest CLI, you can automate the process of testing your internet speed. This guide will walk you through setting up a script to run speed tests and save the results, which can be useful for monitoring your network’s performance or discussing issues with your ISP.
Prerequisites#
- Download and install the Ookla Speedtest CLI
on your system. - Basic understanding of PowerShell scripting.
Considerations for Accurate Testing#
Explain how to ensure accurate test results for discussions with ISPs.


