This app was inspired by the project Wigle, where you can locate wifi routers in the world.
The script uses some functions for signal strength, some simple math for calculating approximate distance and Windows Forms for the GUI.
In this version the buttons have been created using a function, instead of hard coding every attribute for each button. It doesn't require admin rights to run. It does however require you to place the image file in the same directory and point the script toward it so you get a cool background image.
I was also able to package it into a .exe so it could be run as an app, using Iexpress.
Enjoy!
<# Prerequisites #>
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
<# Main Form #>
$Form_Main_Window = New-Object System.Windows.Forms.Form
$Form_Main_Window.Size = New-Object system.drawing.size(670,400)
$Form_Main_Window.Text = "Wifi Tool 1.0"
$Form_Main_Window.FormBorderStyle = "FixedDialog"
$Form_Main_Window.StartPosition = "CenterScreen"
$Form_Main_Window.ForeColor = [System.Drawing.Color]::LightGreen;
$Form_Main_Window.BackColor = [System.Drawing.Color]::Black;
$Form_Main_Window.MaximizeBox = $False
$Img_Background = "$PSScriptRoot\background_network.png"
$Form_Main_Window.BackgroundImage = [System.Drawing.Image]::FromFile($Img_Background)
$Form_Main_Window.BackgroundImageLayout = [System.Windows.Forms.ImageLayout]::Stretch
function Set-StatusText {
param ([string]$StatusText)
$Txt_Status_Box.Text = $StatusText
}
function Create-Button {
param (
[string]$Text,[System.Drawing.Point]$Location,[System.Drawing.Size]$Size,[scriptblock]$ClickAction
)
$button = New-Object System.Windows.Forms.Button
$button.Text = $Text
$button.Location = $Location
$button.Size = New-Object System.Drawing.Size(100,20)
$button.ForeColor = [System.Drawing.Color]::LightGreen
$button.BackColor = [System.Drawing.Color]::Black
$button.TextAlign = "MiddleLeft"
if ($ClickAction) {
$button.Add_Click($ClickAction)
}
return $button
}
function Scan-Wifi {
param (
[string]$wifiName
)
$wifi_data_in = netsh wlan show networks mode=bssid
$wifi_signal_percentage = $null
$wifi_data_in -split "`r?`n" | ForEach-Object {
if ($_ -match '^SSID\s+\d+\s*:\s*(.+)$') {
$ssid = $matches[1]
}
elseif ($_ -match '^\s*Signal\s*:\s*(\d+)%\s*$') {
$signal = $matches[1]
if ($ssid -eq $wifiName) {
$wifi_signal_percentage = [int]$signal
}
}
}
return $wifi_signal_percentage
}
function Calculate-Distance {
$percentage = Scan-Wifi -wifiName $Txt_Target_Box.Text;
if (-not $percentage) {
Set-StatusText -StatusText "Couldn't calculate distance"
}
$twodotfour = 150 - ($percentage * 1.5);
$five = 70 - ($percentage * 0.7);
$six = 50 - ($percentage * 0.5);
return "`r`nSignal strength: $percentage%`r`n2.4 Ghz: $twodotfour meters`r`n5 Ghz: $five meter`r`n6 Ghz: $six meters";
}
function Scan-AllWifi {
Set-StatusText -StatusText "Scanning nearby wifis";
$wifi_data_in = netsh wlan show networks mode=bssid
$results = @()
$wifi_data_in -split "`r?`n" | ForEach-Object {
if ($_ -match '^SSID\s+\d+\s*:\s*(.+)$') {
$ssid = $matches[1]
}
elseif ($_ -match '^\s*Signal\s*:\s*(\d+)%\s*$') {
$signal = $matches[1]
if ($ssid) {$results += [PSCustomObject]@{SSID = $ssid; Signal = "$signal%"}}
}
}
# Filter, Sort, and Format the results in one step
$outputText = ($results | Where-Object { -not [string]::IsNullOrWhiteSpace($_.SSID) } |
Sort-Object -Property Signal -Descending |
ForEach-Object {"{0,-30} {1,-10}" -f $_.Signal,$_.SSID}) -join "`r`n"
# Save to file and update textbox
$Txt_Main_Box.Text = $outputText
Set-StatusText -StatusText "Log file created. Mainbox updated.";
}
function Loop-Scan {
if ($Txt_Status_Box.Text -ne "Scanning") {
# If not already scanning, set scanning status #
Set-StatusText -StatusText "Scanning";
# Loop the scan and update the meter #
for ($i = 1; $i -le [int]$Txt_Loop_Box.Text; $i++) {$target_output = Scan-Wifi -wifiName $Txt_Target_Box.Text; $ProgressBar.Value = $target_output; Start-Sleep -Milliseconds 1500;}
# Mark scanning as complete #
Set-StatusText -StatusText "Scan complete";
} else {
Set-StatusText -StatusText "Scanning attempt failed"
}
}
function Scan-Target {
$Txt_Main_Box.Text = Calculate-Distance;
$target_output = Scan-Wifi -wifiName $Txt_Target_Box.Text;
$ProgressBar.Value = $target_output;
Set-StatusText -StatusText "Target was scanned";
}
function Quick-Export {
$Txt_Main_Box.Text | Out-File -FilePath "$PSScriptRoot\Wifi-log.txt";
Set-StatusText -StatusText "Quick export clicked";
}
function QuickImport-Log {
# File dialog or just quick import? #
Set-StatusText -StatusText "Quick import button clicked";
$ImportFile = Get-Content -Path $PSScriptRoot\wifi-log.txt -Delimiter "%";
$Txt_Main_Box.Text = $ImportFile;
}
function Export-ResultAs {
Set-StatusText -StatusText "Export as clicked";
$SaveFile_Window = New-Object System.Windows.Forms.SaveFileDialog;
$SaveFile_Window.Filter = "Text files (*.txt)|*.txt";
$SaveFile_Window.FileName = "wifi-log-custom.txt"
$Export_File = $Null;
if ($SaveFile_Window.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {$Export_File = $SaveFile_Window.FileName};
if($Export_File) {$Txt_Main_Box.text | Out-File $Export_File};
}
function Import-Log {
Set-StatusText -StatusText "Import log button clicked.";
$ImportFile_Window = New-Object System.Windows.Forms.OpenFileDialog;
$ImportFile_Window.Filter = "Text files (*.txt)|*.txt";
$ImportFile = $null
if ($ImportFile_Window.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
$ImportFile = $ImportFile_Window.FileName;
$Txt_Main_Box.Text = Get-Content -Path $ImportFile -Raw}
}
function Reset-App {
Set-StatusText -StatusText "Reset button clicked";
$Txt_Main_Box.Text = "";
$Txt_Target_Box.Text = "";
$ProgressBar.Value = 0;
}
function Exit-App {
Set-StatusText -StatusText "Closing";
$Form_Main_Window.Close();
}
<# Main textbox #>
$Txt_Main_Box = New-Object System.Windows.Forms.TextBox
$Txt_Main_Box.Location = New-Object System.Drawing.Size (50,50)
$Txt_Main_Box.Size = New-Object System.Drawing.Size (395,260)
$Txt_Main_Box.Text = "Scan to populate"
$Txt_Main_Box.Multiline = $True
$Txt_Main_Box.ForeColor = [System.Drawing.Color]::LightGreen;
$Txt_Main_Box.BackColor = [System.Drawing.Color]::Black;
$Form_Main_Window.Controls.Add($Txt_Main_Box)
<# Status textbox #>
$Txt_Status_Box = New-Object System.Windows.Forms.TextBox
$Txt_Status_Box.Location = New-Object System.Drawing.Size (50,320)
$Txt_Status_Box.Size = New-Object System.Drawing.Size (200,20)
$Txt_Status_Box.Text = "App is running. Awaiting input."
$Txt_Status_Box.Multiline = $True
$Txt_Status_Box.ForeColor = [System.Drawing.Color]::LightGreen;
$Txt_Status_Box.BackColor = [System.Drawing.Color]::Black;
$Form_Main_Window.Controls.Add($Txt_Status_Box)
<# Target textbox #>
$Txt_Target_Box = New-Object System.Windows.Forms.TextBox
$Txt_Target_Box.Location = New-Object System.Drawing.Size (560,80)
$Txt_Target_Box.Size = New-Object System.Drawing.Size (100,20)
$Txt_Target_Box.Text = "Enter a wifi name"
$Txt_Target_Box.ForeColor = [System.Drawing.Color]::LightGreen;
$Txt_Target_Box.BackColor = [System.Drawing.Color]::Black;
$Form_Main_Window.Controls.Add($Txt_Target_Box)
$Form_Main_Window.Add_Shown({
$Txt_Target_Box.Focus()
$Txt_Target_Box.SelectAll()
})
<# Scan N textbox #>
$Txt_Loop_Box = New-Object System.Windows.Forms.TextBox
$Txt_Loop_Box.Location = New-Object System.Drawing.Size (560,110)
$Txt_Loop_Box.Size = New-Object System.Drawing.Size (50,20)
$Txt_Loop_Box.Text = "10"
$Txt_Loop_Box.Multiline = $True
$Txt_Loop_Box.ForeColor = [System.Drawing.Color]::LightGreen;
$Txt_Loop_Box.BackColor = [System.Drawing.Color]::Black;
$Form_Main_Window.Controls.Add($Txt_Loop_Box)
<# Progress bar #>
$ProgressBar = New-Object System.Windows.Forms.ProgressBar
$ProgressBar.Minimum = 0
$ProgressBar.Maximum = 100
$ProgressBar.Value = 0
$ProgressBar.Location = New-Object System.Drawing.Point(50,10)
$ProgressBar.Size = New-Object System.Drawing.Size(200,20)
$ProgressBar.Style = "Continuous"
$ProgressBar.Text
$ProgressBar.ForeColor = [System.Drawing.Color]::Green
$ProgressBar.BackColor = [System.Drawing.Color]::Red
$Form_Main_Window.Controls.Add($ProgressBar)
<# Label for progress bar #>
$Lbl_ProgressBar = New-Object System.Windows.Forms.Label;
$Lbl_ProgressBar.Location = New-Object System.Drawing.Point(255,10);
$Lbl_ProgressBar.Size = $ProgressBar.Size;
$Lbl_ProgressBar.Text = "Signal strength";
$Lbl_ProgressBar.TextAlign = "MiddleLeft";
$Lbl_ProgressBar.ForeColor = [System.Drawing.Color]::DarkGreen;
$Lbl_ProgressBar.BackColor = [System.Drawing.Color]::Transparent;
$Form_Main_Window.Controls.Add($Lbl_ProgressBar);
<# Scan all button #>
$Btn_Scan_All = Create-Button -Text "Scan All" -Location (New-Object System.Drawing.Point 450, 50) -ClickAction { Scan-AllWifi }
$Form_Main_Window.Controls.Add($Btn_Scan_All)
<# Scan target button #>
$Btn_Scan_Specific = Create-Button -Text "Scan target ->" -Location (New-Object System.Drawing.Point 450, 80) -ClickAction { Scan-Target }
$Form_Main_Window.Controls.Add($Btn_Scan_Specific)
<# Loop scan button #>
$Btn_Loop_Scan = Create-Button -Text "Loop scan ->" -Location (New-Object System.Drawing.Size 450,110) -ClickAction { Loop-Scan }
$Form_Main_Window.Controls.Add($Btn_Loop_Scan)
<# Quick Export button #>
$Btn_Quick_Export = Create-Button -Text "Quick Export" -Location (New-Object System.Drawing.Point 450, 200) -ClickAction { Quick-Export }
$Form_Main_Window.Controls.Add($Btn_Quick_Export)
<# Import Quick button #>
$Btn_Quick_Import = Create-Button -Text "Quick Import" -Location (New-Object System.Drawing.Point 555, 200) -ClickAction { QuickImport-Log }
$Form_Main_Window.Controls.Add($Btn_Quick_Import)
<# Export As button #>
$Btn_Export_As = Create-Button -Text "Export As" -Location (New-Object System.Drawing.Point 450, 230) -ClickAction { Export-ResultAs }
$Form_Main_Window.Controls.Add($Btn_Export_As)
<# Import specific button #>
$Btn_Import = Create-Button -Text "Import Log" -Location (New-Object System.Drawing.Point 555, 230) -ClickAction { Import-Log }
$Form_Main_Window.Controls.Add($Btn_Import)
<# Reset button #>
$Btn_Reset = Create-Button -Text "Reset" -Location (New-Object System.Drawing.Point 450, 260) -ClickAction { Reset-App }
$Form_Main_Window.Controls.Add($Btn_Reset)
<# Exit button #>
$Btn_Exit = Create-Button -Text "Exit App" -Location (New-Object System.Drawing.Point 450, 290) -ClickAction { Exit-App }
$Form_Main_Window.Controls.Add($Btn_Exit)
<# Display the window #>
$Form_Main_Window.ShowDialog()