To get the current list of wireless access points programmatically in PowerShell, I'm trying to query this WMI class. WMI Explorer 2.0.0.2 shows that it can be accessed via
$computer = $env:COMPUTERNAME
$namespace = "ROOT\WMI"
$classname = "MSNdis_80211_BSSIList"
Write-Output "====================================="
Write-Output "COMPUTER : $computer "
Write-Output "CLASS : $classname "
Write-Output "====================================="
Get-WmiObject -Class $classname -ComputerName $computer -Namespace $namespace |
Select-Object * -ExcludeProperty PSComputerName, Scope, Path, Options, ClassPath, Properties, SystemProperties, Qualifiers, Site, Container |
Format-List -Property [a-z]*
When I try to enumerate, I get 0 instances. The description of the adjacent MSNdis_80211_BssIdListScan
is
Perform a survey to refresh the NDIS 802.11 BSS list
but has no indication of how to perform a survey. This also appears in wmicore.mof:6892 in the Windows 10 SDK, again with no hint as to what a survey is or how it's done.
I am open to the idea of other methods to get detailed BSS properties, but it seems like my options are limited. I'm looking to enumerate beacon information elements (IEs).
The MSNdis
wmi classes in general are no longer updated, and are very rarely the best approach. The 80211 subset are in even worse shape — as far as I'm aware, they actually never worked right. (There was a time when every OID in the NDIS driver model was mechanically ported to WMI, regardless of whether this was at all useful. The 80211 classes are one of the worst products of that effort. I found one of them that was just transcribed incorrectly, so it couldn't have possibly ever worked.) Unlike most of the networking WMI classes, the WLAN area has not been ported to CIM: there's a MSFT_NetXxx
class for almost everything except WLAN.
The best-maintained programming surface for WLAN is wlanapi. There are a few other front-ends to that (e.g. netsh.exe wlan
), but retrieving IEs is a fairly specialized task and I'm not sure you'll find any other front-end has the IE details you're looking for. As others have already commented, your best path to success is likely to p/invoke your way through WlanGetNetworkBssList
. Yes, it's not an easy API to p/invoke. I unfortunately don't have any experience using this API from C#, so I can't give you a solid recommendation of some existing library of p/invokes for wlanapi, but I see there are a few libraries bouncing around github, so you can at least find a starting place there.
You may already be aware of this, but for the benefit of other people browsing this page, please temper your expectations of what kind of IE data you can get back from a consumer-grade station. Many WLAN chips are fairly vague about what IEs they get back, and necessarily do a fair amount of fudging of data. For example, the NDIS driver model suggests that WLAN chips should actually merge the IEs that are received from beacons and probe responses (with one or two necessary exceptions for specific IEs that would just be semantically broken if you did this), so you're getting back a jumble of data that was never actually transmitted in any single network frame. Windows doesn't need every management frame to be reproduced with perfect precision, so our tests don't hold manufacturers to a needlessly-high standard here.
Consumer-grade WLAN chips also can't listen on every channel at every time, so they are designed to do a fair amount of caching and extrapolating of data. This all happens internally in the device firmware, so by the time the BSS list gets to the OS, the data is already fairly well cooked.
All this chip-specific magic behavior varies fairly widely among manufacturers, so you'll get noticeably different results when comparing different radios. If you need one good result, be prepared to shop around for a few different chips. If you are building a general-purpose product for widespread use, be prepared to spend the time to make it robust to different manufacturers' quirks.