*PWN = PowerShell, WMI, and NDIS

WMI is frequently misunderstood.   WMI is a large collection of technologies designed to help you manage computers.  Most commonly, you'll see IT pros using WMI (usually via VBScript) to do something funky across their domain, like search 1000 computers for nearly-full disk volumes.  But (another misunderstood point) VBScript isn't the only way to use WMI.  Better yet, there's all kinds of cool WMI integration with NDIS for you to use.

In particular, NDIS is a WMI provider.  Typically, NDIS will map a type of OID request to a WMI class[1].  This means that you can issue OIDs from anywhere that you can call into WMI.  And boy howdy, you can invoke WMI from anywhere!  For now, we'll start off with my favorite tool: PowerShell.  Later we'll look at some other ways to call into the same WMI functionality.

Note: If you want to follow along at home (and you should), you'll need PowerShell 2.0 or better.  PowerShell 2.0 is included with Windows 7, and is a free download for prior versions of Windows.  For our purposes, make sure to run your PowerShell command prompt elevated.

Okay, let's look at a real example.  Suppose I want to get the MAC addresses of each network adapter on the system.  Here's a PowerShell snippet that prints the addresses to the console:

$Adapters = Get-WMIObject -Namespace root\wmi -Class MSNdis_EthernetCurrentAddress
 
$Adapters | ForEach-Object {
    $FormattedAddress = ($_.NdisCurrentAddress.Address | % {"{0:X2}" -f $_}) -join "-"
    Write-Host $FormattedAddress, $_.InstanceName
}

The first thing we do is use Get-WMIObject to get all instances of the root\wmi\MSNdis_EthernetCurrentAddress class.  NDIS creates one instance of the class for each Ethernet adapter.  So on a typical machine, $Adapters holds several instances[2].

Then we use a ForEach-Object (PowerShell's way of doing a for-loop) to iterate over each adapter.  We use some admittedly-obtuse PowerShell formatting magic to turn the array-of-bytes into a nicely-formatted[3] string.  After that, we print the formatted MAC address, followed by the adapter name to the console.  Here's the output on my machine[4]:

00-03-FF-A3-DF-F0 BitBlaster 2000 Fast Ethernet Adapter
E4-17-20-52-41-53 WAN Miniport (Network Monitor)
E4-17-20-52-41-53 WAN Miniport (IP)
E4-17-20-52-41-53 WAN Miniport (IPv6)

Pretty cool huh?  Next time we'll look at some of the other things that NDIS exposes through WMI, but in the meantime, it's always a good time to brush up on your PowerShell! 

 

1 - There is a WMI glossary on MSDN in case the jargon gets confusing, but generally words like class, instance, method, and event are used in ways that are intuitive to developers.
2 - This will include hidden virtual adapters too, like the WAN miniports.
3 - Believe it or not, but IEEE 802-2001/9.2.1 actually standardizes how you should format MAC addresses for display.
4 - The events logged in this output are based on the lives of real adapters.  Names and addresses have been changed to protect the innocent.