PowerShell WiFi
WiFi Quick Reference
|
Scan-Before-Connect Gotcha
|
Current connection
netsh wlan show interfaces | Select-String -Pattern "State|SSID|Signal|Authentication|Channel"
Saved profiles
netsh wlan show profiles
netsh wlan show profile name="CHLA_Staff"
netsh wlan show profile name="test-wifi" key=clear
Connect reliably
netsh wlan disconnect interface="Wi-Fi"
Start-Sleep -Seconds 3
netsh wlan connect name="CHLA-Remote" interface="Wi-Fi"
Signal strength
$sig = (netsh wlan show interfaces) -match '^\s+Signal' -replace '^\s+Signal\s+:\s+',''
Write-Host "Signal: $sig"
Export all profiles (backup)
netsh wlan export profile folder="$env:TEMP" key=clear
Extract all saved passwords
(netsh wlan show profiles) -match "All User Profile" -replace ".*:\s+", "" | ForEach-Object {
$name = $_
$pass = (netsh wlan show profile name="$name" key=clear) -match "Key Content" -replace ".*:\s+", ""
[PSCustomObject]@{
Profile = $name
Password = if($pass){$pass}else{"(enterprise/none)"}
}
} | Format-Table -AutoSize
WiFi Management (netsh wlan Replacement)
Get WiFi adapter
Get-NetAdapter | Where-Object { $_.InterfaceDescription -match 'Wi-Fi|Wireless' }
See available WiFi networks (what you can connect to NOW)
netsh wlan show networks
Available networks with signal strength and security
netsh wlan show networks mode=bssid
Parse available networks into objects
$networks = @()
$current = @{}
netsh wlan show networks mode=bssid | ForEach-Object {
if ($_ -match "^SSID \d+ : (.*)") {
if ($current.SSID) { $networks += [PSCustomObject]$current }
$current = @{SSID = $matches[1]}
}
if ($_ -match "Signal\s+: (\d+)%") { $current.Signal = $matches[1] }
if ($_ -match "Authentication\s+: (.*)") { $current.Auth = $matches[1].Trim() }
if ($_ -match "BSSID \d+\s+: (.*)") { $current.BSSID = $matches[1].Trim() }
if ($_ -match "Channel\s+: (\d+)") { $current.Channel = $matches[1] }
}
if ($current.SSID) { $networks += [PSCustomObject]$current }
$networks | Sort-Object Signal -Descending | Format-Table SSID, Signal, Auth, Channel, BSSID
Force rescan for networks
# Disable/enable adapter to force rescan
$adapter = Get-NetAdapter | Where-Object { $_.InterfaceDescription -match 'Wi-Fi|Wireless' }
Disable-NetAdapter -Name $adapter.Name -Confirm:$false
Start-Sleep -Seconds 2
Enable-NetAdapter -Name $adapter.Name -Confirm:$false
Start-Sleep -Seconds 5
netsh wlan show networks
List saved WiFi profiles (networks you HAVE connected to)
netsh wlan show profiles
List just profile names
(netsh wlan show profiles) -match "All User Profile" -replace ".*:\s+", ""
List saved WiFi profiles (PowerShell parsing)
Get-ChildItem "$env:ProgramData\Microsoft\Wlansvc\Profiles\Interfaces" -Recurse -Filter "*.xml" |
ForEach-Object {
[xml]$profile = Get-Content $_.FullName
[PSCustomObject]@{
Name = $profile.WLANProfile.name
SSID = $profile.WLANProfile.SSIDConfig.SSID.name
Auth = $profile.WLANProfile.MSM.security.authEncryption.authentication
}
}
Scan for available networks
netsh wlan show networks mode=bssid
Connect to saved WiFi profile
netsh wlan connect name="MyNetwork"
netsh wlan connect does NOT trigger a network scan. If the adapter hasn’t scanned since boot or since moving locations, you get: "The network specified by profile is not available to connect." Disconnect first — the adapter scans automatically when disconnected.
|
Connect reliably — disconnect first to force scan
netsh wlan disconnect interface="Wi-Fi"
Start-Sleep -Seconds 3
netsh wlan connect name="CHLA-Remote" interface="Wi-Fi"
Connect to WiFi on specific interface
netsh wlan connect name="MyNetwork" interface="Wi-Fi"
Disconnect from WiFi
netsh wlan disconnect interface="Wi-Fi"
Export WiFi profile with password (Admin)
netsh wlan export profile name="MyNetwork" folder="$env:TEMP" key=clear
Import WiFi profile
netsh wlan add profile filename="$env:TEMP\Wi-Fi-MyNetwork.xml"
Delete WiFi profile
netsh wlan delete profile name="MyNetwork"
Create WPA2-PSK WiFi profile programmatically
$profileXml = @"
<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
<name>NewNetwork</name>
<SSIDConfig>
<SSID>
<name>NewNetwork</name>
</SSID>
</SSIDConfig>
<connectionType>ESS</connectionType>
<connectionMode>auto</connectionMode>
<MSM>
<security>
<authEncryption>
<authentication>WPA2PSK</authentication>
<encryption>AES</encryption>
<useOneX>false</useOneX>
</authEncryption>
<sharedKey>
<keyType>passPhrase</keyType>
<protected>false</protected>
<keyMaterial>YourPasswordHere</keyMaterial>
</sharedKey>
</security>
</MSM>
</WLANProfile>
"@
$profileXml | Out-File "$env:TEMP\wifi-profile.xml"
netsh wlan add profile filename="$env:TEMP\wifi-profile.xml"
Show current WiFi connection
netsh wlan show interfaces
Get WiFi status (PowerShell)
Get-NetAdapter -Name "Wi-Fi" | Select-Object Name, Status, LinkSpeed
Get-NetConnectionProfile -InterfaceAlias "Wi-Fi" | Select-Object Name, NetworkCategory, IPv4Connectivity
Set network category (Private/Public/Domain)
Set-NetConnectionProfile -InterfaceAlias "Wi-Fi" -NetworkCategory Private
Get WiFi signal strength
$sig = (netsh wlan show interfaces) -match '^\s+Signal' -replace '^\s+Signal\s+:\s+',''
Write-Host "Signal: $sig"
Monitor WiFi signal continuously
while ($true) {
$sig = ((netsh wlan show interfaces) -match '^\s+Signal') -replace '.*:\s+',''
$ssid = ((netsh wlan show interfaces) -match '^\s+SSID') -replace '.*:\s+',''
Write-Host "$(Get-Date -Format 'HH:mm:ss') - SSID: $ssid - Signal: $sig"
Start-Sleep -Seconds 5
}
View saved profile with password (Admin)
netsh wlan show profile name="MyNetwork" key=clear
Extract just the password from profile
$profile = "MyNetwork"
(netsh wlan show profile name="$profile" key=clear) -match "Key Content" -replace ".*:\s+", ""
View ALL saved profiles with passwords (Admin)
(netsh wlan show profiles) -match "All User Profile" -replace ".*:\s+", "" | ForEach-Object {
$name = $_
$pass = (netsh wlan show profile name="$name" key=clear) -match "Key Content" -replace ".*:\s+", ""
[PSCustomObject]@{
Profile = $name
Password = if($pass){$pass}else{"(none/enterprise)"}
}
} | Format-Table -AutoSize
Get detailed info for all profiles
(netsh wlan show profiles) -match "All User Profile" -replace ".*:\s+", "" | ForEach-Object {
$name = $_
$details = netsh wlan show profile name="$name"
$connMode = ($details -match "Connection mode") -replace ".*:\s+", ""
$auth = ($details -match "Authentication") -replace ".*:\s+", "" | Select-Object -First 1
$cipher = ($details -match "Cipher") -replace ".*:\s+", "" | Select-Object -First 1
[PSCustomObject]@{
Profile = $name
AutoConnect = $connMode
Auth = $auth
Cipher = $cipher
}
} | Format-Table -AutoSize
Remove/forget WiFi network
netsh wlan delete profile name="NetworkToForget"
Remove all saved WiFi profiles (careful!)
netsh wlan delete profile name=* i=*
Remove profiles matching pattern
(netsh wlan show profiles) -match "All User Profile" -replace ".*:\s+", "" |
Where-Object { $_ -match "Guest|Public|Free" } |
ForEach-Object {
Write-Host "Removing: $_"
netsh wlan delete profile name="$_"
}
WiFi connection history (Event Log)
Get-WinEvent -LogName "Microsoft-Windows-WLAN-AutoConfig/Operational" -MaxEvents 50 |
Where-Object { $_.Id -eq 8001 -or $_.Id -eq 8003 } | # 8001=connected, 8003=disconnected
Select-Object TimeCreated,
@{N='Event';E={if($_.Id -eq 8001){"Connected"}else{"Disconnected"}}},
@{N='Details';E={$_.Message.Split("`n")[0]}}
WiFi adapter statistics
$wifi = Get-NetAdapter | Where-Object { $_.InterfaceDescription -match 'Wi-Fi|Wireless' }
Get-NetAdapterStatistics -Name $wifi.Name | Select-Object @{N='Adapter';E={$wifi.Name}},
@{N='ReceivedMB';E={[math]::Round($_.ReceivedBytes/1MB,2)}},
@{N='SentMB';E={[math]::Round($_.SentBytes/1MB,2)}},
ReceivedUnicastPackets, SentUnicastPackets,
ReceivedDiscards, OutboundDiscards
WiFi connection quality metrics
$iface = netsh wlan show interfaces
$props = @{}
$iface | ForEach-Object {
if ($_ -match "^\s+(.+?)\s+:\s+(.+)") { $props[$matches[1].Trim()] = $matches[2].Trim() }
}
[PSCustomObject]@{
SSID = $props['SSID']
BSSID = $props['BSSID']
Signal = $props['Signal']
TxRate = $props['Transmit rate (Mbps)']
RxRate = $props['Receive rate (Mbps)']
RadioType = $props['Radio type']
Channel = $props['Channel']
Auth = $props['Authentication']
}
Compare available vs saved networks
$saved = (netsh wlan show profiles) -match "All User Profile" -replace ".*:\s+", ""
$available = @()
netsh wlan show networks | ForEach-Object {
if ($_ -match "^SSID \d+ : (.+)") { $available += $matches[1] }
}
Write-Host "=== Available networks with saved profile ===" -ForegroundColor Green
$available | Where-Object { $_ -in $saved } | ForEach-Object { Write-Host " $_" }
Write-Host "`n=== Available networks (no saved profile) ===" -ForegroundColor Yellow
$available | Where-Object { $_ -notin $saved -and $_ -ne "" } | ForEach-Object { Write-Host " $_" }
Write-Host "`n=== Saved profiles (not in range) ===" -ForegroundColor Cyan
$saved | Where-Object { $_ -notin $available } | ForEach-Object { Write-Host " $_" }
WiFi XML Profile Management
Location of WiFi profile XML files
# Profiles stored here (Admin access required)
$profilePath = "$env:ProgramData\Microsoft\Wlansvc\Profiles\Interfaces"
Get-ChildItem $profilePath -Recurse -Filter "*.xml" | Select-Object FullName, LastWriteTime
Export single profile to XML
netsh wlan export profile name="MyNetwork" folder="$env:TEMP" key=clear
Get-Content "$env:TEMP\Wi-Fi-MyNetwork.xml"
Export ALL profiles to folder
$exportPath = "$env:TEMP\wifi-profiles"
New-Item -ItemType Directory -Path $exportPath -Force | Out-Null
netsh wlan export profile folder="$exportPath" key=clear
Get-ChildItem $exportPath -Filter "*.xml" | Select-Object Name, Length
Parse XML profile structure
$xmlFile = "$env:TEMP\Wi-Fi-MyNetwork.xml"
[xml]$profile = Get-Content $xmlFile
Write-Host "Name: $($profile.WLANProfile.name)"
Write-Host "SSID: $($profile.WLANProfile.SSIDConfig.SSID.name)"
Write-Host "Connection Type: $($profile.WLANProfile.connectionType)"
Write-Host "Connection Mode: $($profile.WLANProfile.connectionMode)"
Write-Host "Authentication: $($profile.WLANProfile.MSM.security.authEncryption.authentication)"
Write-Host "Encryption: $($profile.WLANProfile.MSM.security.authEncryption.encryption)"
Write-Host "UseOneX: $($profile.WLANProfile.MSM.security.authEncryption.useOneX)"
View password from XML (if exported with key=clear)
[xml]$profile = Get-Content "$env:TEMP\Wi-Fi-MyNetwork.xml"
$keyMaterial = $profile.WLANProfile.MSM.security.sharedKey.keyMaterial
if ($keyMaterial) {
Write-Host "Password: $keyMaterial"
} else {
Write-Host "No PSK (likely enterprise 802.1X profile)"
}
Parse all exported profiles into table
$exportPath = "$env:TEMP\wifi-profiles"
Get-ChildItem $exportPath -Filter "*.xml" | ForEach-Object {
[xml]$profile = Get-Content $_.FullName
$sec = $profile.WLANProfile.MSM.security
[PSCustomObject]@{
Name = $profile.WLANProfile.name
SSID = $profile.WLANProfile.SSIDConfig.SSID.name
Auth = $sec.authEncryption.authentication
Cipher = $sec.authEncryption.encryption
UseOneX = $sec.authEncryption.useOneX
AutoConnect = $profile.WLANProfile.connectionMode
Password = if($sec.sharedKey.keyMaterial){$sec.sharedKey.keyMaterial}else{"N/A"}
}
} | Format-Table -AutoSize
Import WiFi profile from XML
netsh wlan add profile filename="$env:TEMP\Wi-Fi-MyNetwork.xml"
Import profile for all users
netsh wlan add profile filename="$env:TEMP\Wi-Fi-MyNetwork.xml" user=all
Import all profiles from folder
$importPath = "$env:TEMP\wifi-profiles"
Get-ChildItem $importPath -Filter "*.xml" | ForEach-Object {
Write-Host "Importing: $($_.Name)"
netsh wlan add profile filename="$($_.FullName)" user=all
}
Modify profile XML (change auto-connect)
$xmlFile = "$env:TEMP\Wi-Fi-MyNetwork.xml"
[xml]$profile = Get-Content $xmlFile
# Change from manual to auto-connect
$profile.WLANProfile.connectionMode = "auto" # or "manual"
$profile.Save($xmlFile)
Write-Host "Modified. Re-import with: netsh wlan add profile filename=`"$xmlFile`""
Modify profile XML (change network to hidden SSID)
[xml]$profile = Get-Content "$env:TEMP\Wi-Fi-MyNetwork.xml"
# Add nonBroadcast element for hidden networks
$ssidConfig = $profile.WLANProfile.SSIDConfig
$nonBroadcast = $profile.CreateElement("nonBroadcast", $profile.DocumentElement.NamespaceURI)
$nonBroadcast.InnerText = "true"
$ssidConfig.AppendChild($nonBroadcast) | Out-Null
$profile.Save("$env:TEMP\Wi-Fi-MyNetwork-Hidden.xml")
Create new WPA2-PSK profile from scratch
function New-WifiProfile {
param(
[string]$SSID,
[string]$Password,
[string]$OutputPath = "$env:TEMP"
)
$xml = @"
<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
<name>$SSID</name>
<SSIDConfig>
<SSID>
<hex>$([System.BitConverter]::ToString([System.Text.Encoding]::UTF8.GetBytes($SSID)) -replace '-','')</hex>
<name>$SSID</name>
</SSID>
</SSIDConfig>
<connectionType>ESS</connectionType>
<connectionMode>auto</connectionMode>
<MSM>
<security>
<authEncryption>
<authentication>WPA2PSK</authentication>
<encryption>AES</encryption>
<useOneX>false</useOneX>
</authEncryption>
<sharedKey>
<keyType>passPhrase</keyType>
<protected>false</protected>
<keyMaterial>$Password</keyMaterial>
</sharedKey>
</security>
</MSM>
</WLANProfile>
"@
$outFile = Join-Path $OutputPath "Wi-Fi-$SSID.xml"
$xml | Out-File $outFile -Encoding UTF8
Write-Host "Created: $outFile"
return $outFile
}
# Usage
$file = New-WifiProfile -SSID "HomeNetwork" -Password "MySecretPass123"
netsh wlan add profile filename="$file"
Create WPA3 profile
$wpa3Profile = @"
<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
<name>WPA3Network</name>
<SSIDConfig>
<SSID><name>WPA3Network</name></SSID>
</SSIDConfig>
<connectionType>ESS</connectionType>
<connectionMode>auto</connectionMode>
<MSM>
<security>
<authEncryption>
<authentication>WPA3SAE</authentication>
<encryption>AES</encryption>
<useOneX>false</useOneX>
</authEncryption>
<sharedKey>
<keyType>passPhrase</keyType>
<protected>false</protected>
<keyMaterial>YourWPA3Password</keyMaterial>
</sharedKey>
</security>
</MSM>
</WLANProfile>
"@
$wpa3Profile | Out-File "$env:TEMP\wpa3-profile.xml" -Encoding UTF8
netsh wlan add profile filename="$env:TEMP\wpa3-profile.xml"
Backup all profiles with metadata
$backupPath = "$env:USERPROFILE\wifi-backup-$(Get-Date -Format 'yyyyMMdd')"
New-Item -ItemType Directory -Path $backupPath -Force | Out-Null
# Export profiles
netsh wlan export profile folder="$backupPath" key=clear
# Create metadata file
$profiles = (netsh wlan show profiles) -match "All User Profile" -replace ".*:\s+", ""
$metadata = $profiles | ForEach-Object {
[PSCustomObject]@{
Name = $_
ExportDate = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
ComputerName = $env:COMPUTERNAME
}
}
$metadata | Export-Csv "$backupPath\metadata.csv" -NoTypeInformation
Write-Host "Backed up $($profiles.Count) profiles to: $backupPath"
Restore profiles from backup
$backupPath = "$env:USERPROFILE\wifi-backup-20260303"
Get-ChildItem $backupPath -Filter "*.xml" | ForEach-Object {
Write-Host "Restoring: $($_.BaseName)"
netsh wlan add profile filename="$($_.FullName)" user=all
}