PowerShell Pipeline
Viewing Wireless Networks with PowerShell Legacy Commands
Combining the netch command in PowerShell will allow users to pull up useful information about local wireless networks.
Just because we are using PowerShell doesn't mean that we don't have times where we must rely on some legacy commands to get the job done. In this case, we are going to have a little fun by using PowerShell with a command that has been available for quite some time and merge the both of these to list out all of the wireless networks in our vicinity.
The command that I will be utilizing today is netsh. If you have worked in the command line to troubleshoot something network related, odds are that you have dipped your toes into the water with this command. Netsh is very powerful to use not only in troubleshooting network related issues, but also for performing a query for information related to a wireless network.
The command that I will be using to list out all of the available wireless networks within range is listed below:
netsh wlan show network mode=bssid
The results provide some great information, but unfortunately it is all listed as a string which means filtering for specific data is very difficult and doesn't promise that you will accurately display all of the information.
PS C:\Users\proxb\Desktop> netsh wlan show network mode=bssid
Interface name : Wi-Fi
There are 8 networks currently visible.
SSID 1 : Alpha1_5G
Network type : Infrastructure
Authentication : WPA2-Personal
Encryption : CCMP
BSSID 1 : 94:10:3e:01:2c:02
Signal : 80%
Radio type : 802.11ac
Channel : 161
Basic rates (Mbps) : 6 12 24
Other rates (Mbps) : 9 18 36 48 54
SSID 2 : LLR 5GHz
Network type : Infrastructure
Authentication : WPA2-Personal
Encryption : CCMP
BSSID 1 : 24:a2:e1:ec:21:e5
Signal : 6%
Radio type : 802.11ac
Channel : 52
Basic rates (Mbps) : 6 12 24
Other rates (Mbps) : 9 18 36 48 54
SSID 3 : DIRECT-roku-905-12BEF4
Network type : Infrastructure
Authentication : WPA2-Personal
Encryption : CCMP
BSSID 1 : 08:05:81:43:99:af
Signal : 32%
Radio type : 802.11n
Channel : 11
Basic rates (Mbps) : 6 12 24
Other rates (Mbps) : 9 18 36 48 54
SSID 4 : CenturyLink1024
Network type : Infrastructure
Authentication : WPA2-Personal
Encryption : CCMP
BSSID 1 : a0:a3:e2:42:f0:65
Signal : 70%
Radio type : 802.11n
Channel : 11
Basic rates (Mbps) : 1 2 5.5 11
Other rates (Mbps) : 6 9 12 18 24 36 48 54
SSID 5 : C&HHome5G-1
Network type : Infrastructure
Authentication : WPA2-Personal
Encryption : CCMP
BSSID 1 : 2c:30:33:40:a4:66
Signal : 16%
Radio type : 802.11ac
Channel : 44
Basic rates (Mbps) : 6 12 24
Other rates (Mbps) : 9 18 36 48 54
SSID 6 : WILLIAMS0906
Network type : Infrastructure
Authentication : WPA2-Personal
Encryption : CCMP
BSSID 1 : c0:c5:22:51:9e:1c
Signal : 4%
Radio type : 802.11ac
Channel : 36
Basic rates (Mbps) : 6 12 24
Other rates (Mbps) : 9 18 36 48 54
SSID 7 : DIRECTV_WVB_DF7146D3
Network type : Infrastructure
Authentication : WPA2-Personal
Encryption : CCMP
BSSID 1 : 8c:57:9b:37:51:cd
Signal : 12%
Radio type : 802.11n
Channel : 161
Basic rates (Mbps) : 6 12 24
Other rates (Mbps) : 9 18 36 48 54
SSID 8 : DIRECT-
Network type : Infrastructure
Authentication : Open
Encryption : WEP
BSSID 1 : fa:04:2e:c8:d8:fa
Signal : 81%
Radio type : 802.11ac
Channel : 161
Basic rates (Mbps) : 6 12 24
Other rates (Mbps) : 9 18 36 48 54
This is where PowerShell comes into play. We can skip the first three lines to take out the unnecessary lines and then just focus on the rest of the data. I am also going to trim all of the white space from the beginning and end of each line using Trim() and then cast the entire output as a string so I can more easily parse out the data using regular expressions.
$WiFi = (netsh wlan show network mode=bssid | Select-Object -Skip 3).Trim() | Out-String
Speaking of regular expressions, we need to build up our expression to grab only the data that we need. In my case, I am looking to grab everything except for the Basic and Other rates. In an effort to make the regular expression a little more readable, I will use a here-string to build out the regular expression.
$RegEx = @'
(?x)
SSID\s\d+\s:\s(?<SSID>[a-z0-9\-\*\.&_]+)\r\n
Network\stype\s+:\s(?<NetworkType>\w+)\r\n
Authentication\s+:\s(?<Authentication>[a-z0-9\-_]+)\r\n
Encryption\s+:\s(?<Encryption>\w+)\r\n
BSSID\s1\s+:\s(?<BSSID>(?:\w+:){5}\w+)\r\n
Signal\s+:\s(?<Signal>\d{1,2})%\r\n
Radio\stype\s+:\s(?<Radio>[a-z0-9\.]+)\r\n
Channel\s+:\s(?<Channel>\w+)\r\n
'@
Now the next step is to split up each Wi-Fi group into its own single string object. This will make it easier to iterate through each network and apply our regular expression to build out an object.
$Networks = $WiFi -split "\r\s+\n"
The last thing left to do is to begin stepping through each network and parse out the data using our expression. I will use an If statement to test each item against the expression and if it is a match, begin building the object out.
$WiFiNetworks = $Networks | ForEach {
If ($_ -match $RegEx) {
[pscustomobject]@{
SSID = $Matches.SSID
NetworkType = $Matches.NetworkType
AuthenticationType = $Matches.Authentication
Encryption = $Matches.Encryption
BSSID1 = $Matches.BSSID
SignalPercentage = [int]$Matches.Signal
RadioType = $Matches.Radio
Channel = $Matches.Channel
}
}
}
$WiFiNetworks | Sort SignalPercentage -Descending
The end result is a nicely formatted object that I can use later on or filter against if needed.
SSID : Alpha1
NetworkType : Infrastructure
AuthenticationType : WPA2-Personal
Encryption : CCMP
BSSID1 : 94:10:3e:01:2c:01
SignalPercentage : 97
RadioType : 802.11ac
Channel : 8
SSID : DIRECT-
NetworkType : Infrastructure
AuthenticationType : Open
Encryption : WEP
BSSID1 : fa:04:2e:c8:d8:fa
SignalPercentage : 82
RadioType : 802.11ac
Channel : 161
SSID : Alpha1_5G
NetworkType : Infrastructure
AuthenticationType : WPA2-Personal
Encryption : CCMP
BSSID1 : 94:10:3e:01:2c:02
SignalPercentage : 81
RadioType : 802.11ac
Channel : 161
SSID : C&HHome5G-1
NetworkType : Infrastructure
AuthenticationType : WPA2-Personal
Encryption : CCMP
BSSID1 : 2c:30:33:40:a4:66
SignalPercentage : 14
RadioType : 802.11ac
Channel : 44
SSID : DIRECTV_WVB_DF7146D3
NetworkType : Infrastructure
AuthenticationType : WPA2-Personal
Encryption : CCMP
BSSID1 : 8c:57:9b:37:51:cd
SignalPercentage : 10
RadioType : 802.11n
Channel : 161
SSID : C&HHome5G-2
NetworkType : Infrastructure
AuthenticationType : WPA2-Personal
Encryption : CCMP
BSSID1 : 2c:30:33:40:a4:68
SignalPercentage : 6
RadioType : 802.11ac
Channel : 157
SSID : WILLIAMS0906
NetworkType : Infrastructure
AuthenticationType : WPA2-Personal
Encryption : CCMP
BSSID1 : c0:c5:22:51:9e:1c
SignalPercentage : 2
RadioType : 802.11ac
Channel : 36
In this case, I sorted by signal strength to find out which networks were the closest to my current location. And just like anything that we build, we can make it into a function for easier use!
Function Get-WiFiNetwork {
$RegEx = @'
(?x)
SSID\s\d+\s:\s(?<SSID>[a-z0-9\-\*\.&_]+)\r\n
Network\stype\s+:\s(?<NetworkType>\w+)\r\n
Authentication\s+:\s(?<Authentication>[a-z0-9\-_]+)\r\n
Encryption\s+:\s(?<Encryption>\w+)\r\n
BSSID\s1\s+:\s(?<BSSID>(?:\w+:){5}\w+)\r\n
Signal\s+:\s(?<Signal>\d{1,2})%\r\n
Radio\stype\s+:\s(?<Radio>[a-z0-9\.]+)\r\n
Channel\s+:\s(?<Channel>\w+)\r\n
'@
$WiFi = (netsh wlan show network mode=bssid | Select-Object -Skip 3).Trim() | Out-String
$Networks = $WiFi -split "\r\s+\n"
$Networks | ForEach {
If ($_ -match $RegEx) {
[pscustomobject]@{
SSID = $Matches.SSID
NetworkType = $Matches.NetworkType
AuthenticationType = $Matches.Authentication
Encryption = $Matches.Encryption
BSSID1 = $Matches.BSSID
SignalPercentage = [int]$Matches.Signal
RadioType = $Matches.Radio
Channel = $Matches.Channel
}
}
}
}
With that, we have taken a legacy command and used it to look at the surrounding wireless networks in a usable object format.