-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTest-Speed.ps1
129 lines (102 loc) · 6.21 KB
/
Test-Speed.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
function Test-Speed {
<#
.Synopsis
Wrapper around Speedtest.net's commandline "speedtest.exe" tool that allows for multiple speed tests to be performed during a specified timeframe.
.Description
Run multiple speed tests using Speedtest.net's commandline speedtest.exe tool. Running without any parameters will run a single speed test immediately.
Alternatively, you may specify *either* a number of repetitions to perform (-Repetitions) *or* time to stop at (-EndTime), but not both. You may also provide a -StartTime along with either option to delay the start.
This provides the ability to, for example, run a speed test every 10 minutes between 3:00am and 5:00am, or run 30 speed tests every five minutes starting now.
See `Get-Help Test-Speed -Examples` for more.
Requires speedtest.net's speedtest.exe, which can be downloaded here: https://www.speedtest.net/apps/cli (choose the Download for Windows option, obviously). After downloading, speedtest.exe must exist in your PATH, OR you can specify the full path to the exe using the -SpeedtestExe parameter.
.Example
Test-Speed -Interval 5 -Repetitions 10 | Tee-Object -Variable results
Run speed every five minutes, ten times in a row, and save the results to $results as well as printing them to screen.
.Example
Test-Speed -Interval 0.5 -EndTime "3:36pm"
Run a speed test every 30 seconds from now until 3:36pm
.Example
Test-Speed -Interval 10 -StartTime "2:00am" -EndTime "5:00am"
Run a speed test every 10 minutes between 2:00am and 5:00am
.Example
Test-Speed -Interval 10 -StartTime "2021/08/19 3:00am" -EndTime "2021/08/19 7:00am"
Run a speed test every 10 minutes between 3am and 7am on August 19th (required if, e.g., you want to run it after midnight tonight).
.Example
Test-Speed | Select *
Return all properties instead of just the default set.
.Example
Test-Speed -Repetitions 5 -ServerID 10300
Specify speedtest.net server to use. A list of nearby servers can be obtained by running `speedtest.exe -L`.
If a server isn't specified, speedtest.exe will automatically choose a nearby server on the first loop, and will use the same server for each subsequent loop.
#>
[cmdletbinding(DefaultParametersetname="Repetitions")]
param (
# Specify the end time. Accepts any format accepted by "Get-Date", e.g. "3:00am" or "2021/04/06 3:00pm". Specify this parameter OR -Repetitions, but not both.
[Parameter(Mandatory = $true, ParameterSetName = "EndTime")]
[DateTime]$EndTime,
# Specify the number of repetitions to perform. Specify this parameter OR -EndTime, but not both.
[Parameter(ParameterSetName = "Repetitions")]
[int]$Repetitions = 1,
[Parameter(ParameterSetName = "EndTime")]
[Parameter(ParameterSetName = "Repetitions")]
# Specify the interval between tests in minutes. Defaults to 1.
[int]$Interval = 1,
[Parameter(ParameterSetName = "EndTime")]
[Parameter(ParameterSetName = "Repetitions")]
# Specify the start time. Accepts any format accepted by "Get-Date", e.g. "3:00am" or "2021/04/06 3:00pm". Defaults to NOW.
[DateTime]$StartTime = $(Get-Date),
[Parameter(ParameterSetName = "EndTime")]
[Parameter(ParameterSetName = "Repetitions")]
# Specify speedtest.net server ID to use. Otherwise automatically chooses one.
[int]$ServerID,
[Parameter(ParameterSetName = "EndTime")]
[Parameter(ParameterSetName = "Repetitions")]
# Full path to speedtest.exe, if not in PATH. E.g. "C:\speedtest\speedtest.exe"
[System.IO.FileInfo]$SpeedtestExe = "speedtest.exe"
)
# Pass the input of the -StartTime and -EndTime (if specified) paramaters to Get-Date. This causes the provided
# string to be evaluated by Get-Date and enables natural language formats such as "3:05am" or "2021/05/24 12pm" to be used.
$StartTime = Get-Date $StartTime
If ($EndTime) {$EndTime = Get-Date $EndTime}
# If it ain't time to start yet sleep a while
while ($(Get-Date) -lt $StartTime) {
Start-Sleep -seconds 10
}
# Do the magic. This loop works whether -Repetitions or -EndTime is provided, because if $Repetitions is $Null,
# then "$ -le $Repetitions" will continue to evaluable to $False, but "Get-Date -lt $EndTime" will be $True once
# the current time is past the end time.
for ($i = 1; (($i -le $Repetitions) -or ($(get-date) -lt $EndTime)); $i++) {
# Don't sleep on the first loop. Otherwise, sleep for the specified interval.
if ($i -ne 1) {
Start-Sleep -Seconds $($Interval * 60)
}
# Get the current time
$time = Get-Date
# Arguments to pass to speedtest.exe
$arguments = @("--format=csv","--output-header")
# If the -ServerID parameter has been specified, then add "--server-id" to the list of parameters to
# pass to speedtest.exe. Otherwise it will automatically choose a server.
If ($ServerID) {
$arguments += "--server-id=$ServerID"
}
# Call speedtest.exe at the specified path with the specified objects, convert the CSV results to an object, and save to $results
$results = . $SpeedtestExe $arguments | ConvertFrom-Csv
# Return the results as a custom object
[PSCustomObject]@{
PSTypeName = "Justus-Module.Test-Speed.Results" #This sets the TypeName of the object. There's a corresponding display format in "Justus-Module.Format.ps1xml" which outputs the results in a table by default.
Time = $time
ServerName = $results."server name"
ServerID = $results."server id"
Latency = $results."latency"
Jitter = $results."jitter"
PacketLoss = $results."packet loss"
"Download(Mb)" = [math]::Round($results."download bytes"/1024/1024,2) #Convert bits to megabits and round to two decimals
"Upload(Mb)" = [math]::Round($results."upload bytes"/1024/1024,2) #Convert bits to megabits and round to two decimals
ShareURL = $results."share url"
}
# If -ServerID parameter has not been specified, then set $ServerID to the server automatically selected in the first loop so that
# the script uses the same server for each repetition.
If (-Not($ServerID)) {
$ServerID = $results."server id"
}
}
}