The following script is very handy for any Windows machine which relies on Wi-Fi, wireless or LTE 4G networks. WiFi at the best of times is not that reliable and you can experience WiFi dropouts or Wi-Fi disconnections. You can now have a full automatic solution which keeps a Windows machine connected to WiFi even if the connection drops.
Running this AutoConnectWiFi.ps1 script (below) will ensure that the Windows device is actually connected to a known WiFi network. A known WiFi network is a network in which the device has already connected to in the past and is aware of both the Wireless SSID and passphrase.
The script has the smarts to connect only to the strongest known network.
If the script runs and the Windows device is already connected to any WiFi network, then the script will essentially do nothing and simply end gracefully, so it is safe to run this multiple times as peice of mind to make sure the device never drops a Wireless network connection.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$PreferredSSID = $null # otherwise change this to '$PreferredSSID = 'My SSID'. If $null, it will connect to an available known WiFi network | |
function Get-WifiNetwork { | |
end { | |
netsh wlan show networks mode=bssid | % –process { | |
if ($_ -match '^SSID (\d+) : (.*)$') { | |
$current = @{} | |
$networks += $current | |
$current.Index = $matches[1].trim() | |
$current.SSID = $matches[2].trim() | |
} else { | |
if ($_ -match '^\s+(.*)\s+:\s+(.*)\s*$') { | |
$current[$matches[1].trim()] = $matches[2].trim() | |
$current.Signal = [int]($current.Signal -replace '%') | |
} | |
} | |
} –begin { $networks = @() } –end { $networks|% { new-object psobject –property $_ } } | |
} | |
} | |
Function AutoConnect ($PreferredSSID){ | |
# WiFi auto-connect | |
if($PreferredSSID -ne $null){ | |
if(Get-NetAdapter | where {($_.Name -like "*wi-fi*" -or $_.Name -like "*wifi*") -and ($_.Status -eq "Disconnected")}){ | |
netsh wlan connect name=$PreferredSSID | |
Start-Sleep –Seconds 2 | |
netsh wlan set profileparameter name=$PreferredSSID connectionmode=auto | |
} | |
} else { | |
$wlanprofile = @() | |
$wlanprofiles = @() | |
$wlanprofileNames = @() | |
$visiblenetworks = @() | |
# get known profiles | |
$wlanprofiles = (netsh wlan show profiles) | |
$wlanprofileNames = $wlanprofiles | Select-String –Pattern "(?<=: ).+" | % { $_.Matches[0].Value } | |
# get visible networks and sort by strength | |
$visiblenetworks = Get-WifiNetwork | select index, ssid, signal, 'radio type' | sort signal –Descending | |
# match visible networks with known profiles | |
$ApprovedNetworks = Compare-Object –ReferenceObject $wlanprofileNames –DifferenceObject $visiblenetworks.ssid –IncludeEqual | where {$_.SideIndicator -eq "=="} | |
# connect to the strongest known network | |
if(Get-NetAdapter | where {($_.Name -like "*wi-fi*" -or $_.Name -like "*wifi*") -and ($_.Status -eq "Disconnected")}){ | |
netsh wlan connect name=($ApprovedNetworks[0]).InputObject | |
Start-Sleep –Seconds 2 | |
netsh wlan set profileparameter name=($ApprovedNetworks[0]).InputObject connectionmode=auto | |
} | |
} | |
# LTE auto-connect for devices that have SIM cards | |
while ((Get-NetAdapter | where {$_.Name -like "*mobile*"}).Status -eq "Disconnected") | |
{ | |
Start-Sleep –Seconds 1 | |
$mbnprofile = @() | |
$mbnprofiles = @() | |
$mbnprofiles = (netsh mbn show profiles) -join "" -replace ".*Profiles.*- ","" | |
ForEach($mbnprofile in $mbnprofiles){ | |
netsh mbn connect interface="Mobile Broadband" connmode=name name=$mbnprofile | |
} | |
} | |
} | |
AutoConnect $PreferredSSID | |
## Adding a pause for 5 minutes in case the wireless router is restarting | |
Start-Sleep –Seconds 300 | |
AutoConnect $PreferredSSID |
To add this script above as a scheduled task, run the script below (ScheduledTask-Event-Repeat.ps1). The PowerShell script below will attach a specific Windows Event to a scheduled task and in turn run a PowerShell script when event ID 8003 (WiFi disconnection) is logged in the event log.
In other words, as soon as the WiFi network is disconnected, the scheduled task is kicked off running the AutoConnectWiFi.ps1 script.
Run this PowerShell script as administrator to ensure you have the privileges necessary to add a scheduled task.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### Variables | |
$dropboxDBfile = Get-ChildItem –Path $env:USERPROFILE\AppData\Local –Recurse –ErrorAction SilentlyContinue | ? {$_.Name -eq 'host.db'} | |
$base64path = gc $dropboxDBfile.FullName | select –index 1 | |
$dropboxPath = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($base64path)) # convert from base64 to ascii | |
$taskName = "Keep_WiFi_Connected" | |
$Path = 'PowerShell.exe' | |
$Arguments = "-ExecutionPolicy Unrestricted -File c:\StartLTE-WiFi.ps1" | |
$Service = new-object –ComObject ("Schedule.Service") | |
$Service.Connect() | |
$RootFolder = $Service.GetFolder("\") | |
$TaskDefinition = $Service.NewTask(0) # TaskDefinition object https://msdn.microsoft.com/en-us/library/windows/desktop/aa382542(v=vs.85).aspx | |
$TaskDefinition.RegistrationInfo.Description = '' | |
$TaskDefinition.Settings.Enabled = $True | |
$TaskDefinition.Settings.AllowDemandStart = $True | |
$TaskDefinition.Settings.DisallowStartIfOnBatteries = $False | |
$Triggers = $TaskDefinition.Triggers | |
$Trigger = $Triggers.Create(0) ## 0 is an event trigger https://msdn.microsoft.com/en-us/library/windows/desktop/aa383898(v=vs.85).aspx | |
$Trigger.Enabled = $true | |
# Expiry time if needed # $TaskEndTime = [datetime]::Now.AddMinutes(30);$Trigger.EndBoundary = $TaskEndTime.ToString("yyyy-MM-dd'T'HH:mm:ss") | |
$Trigger.Id = '8003' # 8003 is for disconnections and 8001 is for connections | |
$Trigger.Subscription = "<QueryList><Query Id='0' Path='Microsoft-Windows-WLAN-AutoConfig/Operational'><Select Path='Microsoft-Windows-WLAN-AutoConfig/Operational'>*[System[Provider[@Name='WLAN-AutoConfig'] and EventID=8003]]</Select></Query></QueryList>" | |
$Action = $TaskDefinition.Actions.Create(0) | |
$Action.Path = $Path | |
$action.Arguments = $Arguments | |
$RootFolder.RegisterTaskDefinition($taskName, $TaskDefinition, 6, "System", $null, 5) | Out-Null |