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 "$ModuleUtilityDir\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 = & "$ModuleUtilityDir\SpeedTest CLI\speedtest.exe" --accept-license

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

            ### Download Latency
            TRY { 
                [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(" ","")
            } CATCH { $DownloadLatency = $null }

            ### Download Latency High
            TRY { 
                [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(" ","")
            } CATCH { $DownloadLatencyHigh = $null }
    
            ### Upload Speed
            TRY { 
                $UploadSpeed = $SpeedTestResults | select-string -Pattern "Upload:"
                $UploadSpeed = $UploadSpeed.ToString().Replace('Upload:','')
                [string[]]$UploadSpeed = $UploadSpeed.Split('.')
                [int]$UploadSpeed = $UploadSpeed[0].Replace(' ','')
            } CATCH { $UploadSpeed = $null }

            ### Upload Latency
            TRY { 
                [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(" ","")
            } CATCH { $UploadLatency = $null }

            ### Upload Latency High
            TRY { 
                [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(" ","")
            } CATCH { $UploadLatencyHigh = $null }

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

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

            IF ($DownloadSpeed -ne $null) { $DownloadSpeed = ($DownloadSpeed.ToString() + " Mbps") }
            IF ($DownloadLatency -ne $null) { $DownloadLatency = ($DownloadLatency.ToString() + " ms") }
            IF ($DownloadLatencyHigh -ne $null) { $DownloadLatencyHigh = ($DownloadLatencyHigh.ToString() + " ms") }
            IF ($UploadSpeed -ne $null) { $UploadSpeed = ($UploadSpeed.ToString() + " Mbps") }
            IF ($UploadLatency -ne $null) { $UploadLatency = ($UploadLatency.ToString() + " ms") }
            IF ($UploadLatencyHigh -ne $null) { $UploadLatencyHigh = ($UploadLatencyHigh.ToString() + " ms") }
            IF ($PacketLoss -ne $null) { $PacketLoss = ($PacketLoss.ToString() + "%") }


            $Results += [PSCustomObject]@{
                Time = $Time
                ISP = $ISP
                DownloadSpeed = $DownloadSpeed
                DownloadLatencyAvg = $DownloadLatency
                DownloadLatencyHigh = $DownloadLatencyHigh
                UploadSpeed = $UploadSpeed
                UploadLatencyAvg = $UploadLatency
                UploadLatencyHigh = $UploadLatencyHigh
                PacketLoss = $PacketLoss
            }


            [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]@{                
                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]@{
            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