Public/Network/Test-InternetSpeed.ps1

<#
Copyright © 2024 Integris. For internal company use only. All rights reserved.
#>


FUNCTION Test-InternetSpeed {
    <#
    .SYNOPSIS
    Performs an internet speed test and retrieves connection information.
 
    .DESCRIPTION
    This function runs an internet speed test using the Get-InternetInfo function with the SpeedTest parameter. It measures download and upload speeds, latency, and packet loss, and provides detailed information about the internet connection.
 
    .EXAMPLE
    Get-InternetSpeedTest
 
    This command performs an internet speed test and displays the results.
 
    .NOTES
    This function requires the SpeedTest CLI tool to be installed in the specified directory and may need to be run with appropriate permissions.
    #>

    
    [CmdletBinding(DefaultParameterSetName='SpeedTest')]
    PARAM ( )

    ### Declare Variables
    $Results = @()
    $Time = $null
    
    IF (Test-IntegrisFileDependency -RootPath "C:\Integris\PowerShell Module\Utilities\SpeedTest CLI" -ChildPath "\speedtest.exe" "https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-win64.zip" -Unzip -Force) { 
        Write-Verbose "Speedtest CLI Found" 
        TRY {
            Write-Progress -ID 30 -Activity "Running Internet SpeedTest" -Status "Running Internet SpeedTest - About 30 Seconds" -PercentComplete 0
            
            $GeoData = Get-GeoInfo
            $Time = (Get-Date)   
            $SpeedTestResults = & "C:\Integris\PowerShell Module\Utilities\SpeedTest CLI\speedtest.exe" --accept-license

            ### Download Speed
            $DownloadSpeed = $SpeedTestResults | select-string -Pattern "Download:"
            $DownloadSpeed = $DownloadSpeed.ToString().Replace('Download:','')
            [string[]]$DownloadSpeed = $DownloadSpeed.Split('.')
            [int]$DownloadSpeed = $DownloadSpeed[0].Replace(' ','')

            ### Download Latency
            [string]$DownloadLatency = $SpeedTestResults | select-string -Pattern "jitter:"
            [string[]]$DownloadLatency = $DownloadLatency.Split('j')
            [string]$DownloadLatency = $DownloadLatency[1]
            [string[]]$DownloadLatency = $DownloadLatency.split(')')
            [string]$DownloadLatency = $DownloadLatency[1]
            $DownloadLatency = $DownloadLatency.Replace("ms","")
            $DownloadLatency = $DownloadLatency.Replace("(","")
            [int]$DownloadLatency = $DownloadLatency.Replace(" ","")

            ### Download Latency High
            [string[]]$DownloadLatencyHigh = $SpeedTestResults | select-string -Pattern "high:"
            [string]$DownloadLatencyHigh = $DownloadLatencyHigh[1]
            [string[]]$DownloadLatencyHigh = $DownloadLatencyHigh.Split(':')
            [string]$DownloadLatencyHigh = $DownloadLatencyHigh[3]
            $DownloadLatencyHigh = $DownloadLatencyHigh.Replace("ms","")
            $DownloadLatencyHigh = $DownloadLatencyHigh.Replace(")","")
            [int]$DownloadLatencyHigh = $DownloadLatencyHigh.Replace(" ","")
    
            ### Upload Speed
            $UploadSpeed = $SpeedTestResults | select-string -Pattern "Upload:"
            $UploadSpeed = $UploadSpeed.ToString().Replace('Upload:','')
            [string[]]$UploadSpeed = $UploadSpeed.Split('.')
            [int]$UploadSpeed = $UploadSpeed[0].Replace(' ','')

            ### Upload Latency
            [string]$UploadLatency = $SpeedTestResults | select-string -Pattern "jitter:"
            [string[]]$UploadLatency = $UploadLatency.Split('j')
            [string]$UploadLatency = $UploadLatency[2]
            [string[]]$UploadLatency = $UploadLatency.split(')')
            [string]$UploadLatency = $UploadLatency[1]
            $UploadLatency = $UploadLatency.Replace("ms","")
            $UploadLatency = $UploadLatency.Replace("(","")
            [int]$UploadLatency = $UploadLatency.Replace(" ","")

            ### Upload Latency High
            [string[]]$UploadLatencyHigh = $SpeedTestResults | select-string -Pattern "high:"
            [string]$UploadLatencyHigh = $UploadLatencyHigh[2]
            [string[]]$UploadLatencyHigh = $UploadLatencyHigh.Split(':')
            [string]$UploadLatencyHigh = $UploadLatencyHigh[3]
            $UploadLatencyHigh = $UploadLatencyHigh.Replace("ms","")
            $UploadLatencyHigh = $UploadLatencyHigh.Replace(")","")
            [int]$UploadLatencyHigh = $UploadLatencyHigh.Replace(" ","")

            ### Packet Loss
            $PacketLoss = $SpeedTestResults | select-string -Pattern "Packet Loss:"
            $PacketLoss = $PacketLoss.ToString().Replace('%','')
            $PacketLoss = $PacketLoss.ToString().Replace('Packet Loss:','')
            [int]$PacketLoss = $PacketLoss.ToString().Replace(' ','')

            ### Internet Service Provider
            [string]$ISP = $SpeedTestResults | select-string -Pattern "ISP:"
            $ISP = $ISP.Replace("ISP:","")
            $ISP = $ISP.Replace(" ","")

            $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                Time = $Time
                DownloadSpeed = ($DownloadSpeed.ToString() + " Mbps")
                DownloadLatencyAvg = ($DownloadLatency.ToString() + " ms")
                DownloadLatencyHigh = ($DownloadLatencyHigh.ToString() + " ms")
                UploadSpeed = ($UploadSpeed.ToString() + " Mbps")
                UploadLatencyAvg = ($UploadLatency.ToString() + " ms")
                UploadLatencyHigh = ($UploadLatencyHigh.ToString() + " ms")
                PacketLoss = ($PacketLoss.ToString() + "%")
            }

            [string]$ExportPath = "C:\Integris\PowerShell Module\Logs\Get-InternetSpeedTest\Results\$($GeoData.IP) - $($GeoData.Org), $($GeoData.ISP) - $($GeoData.City), $($GeoData.State) $($GeoData.ZipCode)\"
            MKDIR $ExportPath -ErrorAction SilentlyContinue | Out-Null
            $ExportPath += "↓$($DownloadSpeed.ToString().PadLeft(4," "))"
            $ExportPath += " "
            $ExportPath += "🕑$($DownloadLatency.ToString().PadLeft(4," "))-$($DownloadLatencyHigh.ToString())"
            $ExportPath += " "
            $ExportPath += "↑$($UploadSpeed.ToString().PadLeft(4," "))"
            $ExportPath += " "
            $ExportPath += "🕑$($UploadLatency.ToString().PadLeft(4," "))-$($UploadLatencyHigh.ToString())"
            $ExportPath += " "
            $ExportPath += "☒"
            $ExportPath += "$($PacketLoss.ToString().PadLeft(2," "))%"
            $ExportPath += " "
            $ExportPath += (Get-Date).ToString("yyy_MM_dd HH_mm_ss")
            $ExportPath += ".csv"

            $Results | Select-Object PublicIP, Country, City, State, ZipCode, Org, ISP, DownloadSpeed, DownloadLatencyAvg, DownloadLatencyHigh, UploadSpeed, UploadLatencyAvg, UploadLatencyHigh, PacketLoss | Export-CSV -Path $ExportPath -Force -NoTypeInformation
                            
            Write-Progress -ID 30 -Activity "Running Internet SpeedTest" -Status "Running Internet SpeedTest - About 30 Seconds" -PercentComplete 100 -Completed           
        }
        CATCH {
            Write-Warning "SpeedTest.exe blocked or failed to run. Check security applications such as SentinelOne or ThreatLocker."
            $Results += [PSCustomObject]@{
                PSTypeName = 'IntegrisPowerShell.InternetSpeed'
                Time = $Time
                DownloadSpeed = $null
                DownloadLatencyAvg = $null
                DownloadLatencyHigh = $null
                UploadSpeed = $null
                UploadLatencyAvg = $null
                UploadLatencyHigh = $null
                PacketLoss = $null
            }                        

            Write-Progress -ID 30 -Activity "Running Internet SpeedTest" -Status "Running Internet SpeedTest - About 30 Seconds" -PercentComplete 100 -Completed
        }
    }
    ELSE { 
        Write-Warning "Speedtest CLI exe not found. Please confirm security apps are not blocking the download and try again." 
        $Results += [PSCustomObject]@{
            PSTypeName = 'IntegrisPowerShell.InternetSpeed'
            Time = $Time
            DownloadSpeed = $null
            DownloadLatencyAvg = $null
            DownloadLatencyHigh = $null
            UploadSpeed = $null
            UploadLatencyAvg = $null
            UploadLatencyHigh = $null
            PacketLoss = $null
        }

        RETURN $Results
    }       

    RETURN $Results
}
New-Alias -Name Get-InternetSpeedTest -Value Test-InternetSpeed