Summary: Microsoft Scripting Guy, Ed Wilson, talks about using two WMI classes from the root\wmi namespace to reveal additional HID hardware information.
Microsoft Scripting Guy, Ed Wilson, is here. Well, the Scripting Wife and I returned from Europe yesterday. It is good to be home, but we will miss our friends and all the great food. I fell in love with several new types of food that I have absolutely no hopes of ever finding in Charlotte, North Carolina. While there is a pretty good German restaurant in Charlotte, I have yet to find a Danish, Swedish, Norwegian, Swiss, Polish, Czech, or even Swiss restaurant in Charlotte. Major bummer to be sure. Oh, well. Stay in touch with the Scripting Wife on either Facebook or Twitter because she is already talking about planning a return trip to areas we missed on this trip. We only had three weeks after all.
Revisiting WMI mouse & keyboard discovery
On the flight from Frankfurt to Charlotte yesterday, I had time (indeed plenty of time) to spend playing around with Windows PowerShell. (I mean one can only watch so many boring movies on a 5-inch screen that bounces every time the person in front of you moves. In my case, the number was exactly 0.) In all fairness, they did have good Jazz music programing, and so I put my headphones, fired up the Windows PowerShell ISE, and began playing.
Last week, I wrote Use PowerShell and WMI to Find Wireless Keyboard & Mouseabout using WMI to identify a wireless mouse and keyboard attached to my system.
So, I was playing around with a function called Get-NameSpace, which I wrote for my new Microsoft Press Windows PowerShell 3.0 Step by Step book, and I decided to investigate additional namespaces for mouse and keyboard information.
Note The Root\Cimv2 namespace is well documented on MSDN, and the classes there are supported for general use. Classes from other namespaces not documented on MSDN are not supported.
Just because a WMI class is not supported does not mean that it will not work—it only means that I cannot call up Microsoft support for assistance if the thing breaks, quits working, or behaves erratically. With this caveat in place, I begin my investigation.
Note After things settle down, I intend to add the Get-NameSpace to my HSG*WMI*module.
Get-WMINameSpace Function
Function Get-WmiNameSpace
{
Param(
$nameSpace = "root",
$computer = "localhost"
)
Get-WmiObject -class __NameSpace -computer $computer `
-namespace $namespace -ErrorAction "SilentlyContinue" |
Foreach-Object `
-Process `
{
$subns = Join-Path -Path $_.__namespace -ChildPath $_.name
if($subns -notmatch 'directory') {$subns}
$namespaces += $subns + "`r`n"
Get-WmiNameSpace -namespace $subNS -computer $computer
}
} #end Get-WmiNameSpace
When I run the Get-WmiNameSpace function, I am presented with an extensive listing of new WMI namespaces existing on my computer running Windows 8. The partial listing appears in the following image.
As I look over the listing, I find a couple of namespaces that seem like they might be interesting. The first one is Root\Hardware. I use the following command to see if I can find anything related to a mouse or to a keyboard. As shown here, I found nothing.
PS C:\> Get-CimClass *mouse* -Namespace root\hardware
PS C:\> Get-CimClass *keyboard* -Namespace root\hardware
PS C:\>
I could also have used the Windows PowerShell 2.0 syntax, but the results are the same.
PS C:\> Get-WmiObject -List *mouse* -Namespace root\hardware
PS C:\> Get-WmiObject -List *keyboard* -Namespace root\hardware
PS C:\>
After exploring several other namespaces, I decided to go where I felt I would find success—the Root\WMI namespace. Once I queried there, I found several classes I could use.
PS C:\> "*mouse*","*keyboard*" | % {Get-CimClass $_ -Namespace root\WMI}
NameSpace: ROOT/wmi
CimClassName CimClassMethods CimClassProperties
------------ --------------- ------------------
MSMouse {} {}
MSMouse_ClassInformation {} {Active, DeviceId, ...
MSMouse_PortInformation {} {Active, Buttons, C...
MSKeyboard {} {}
MSKeyboard_ExtendedID {} {Active, InstanceNa...
MSKeyboard_PortInformation {} {Active, ConnectorT...
MSKeyboard_ClassInformation {} {Active, DeviceId, ...
Notice that the MSMouse and MSKeyboard classes do not expose any properties in the CimClassProperties column. I verified this by using WbemTest as shown here.
Basically, the MSMouse class is an abstract class, but it does not have the abstract qualifier. I confirmed this by seeing first there are no instances (I pressed the Instances button). Then I pressed the Derived button, and saw there are two WMI classes derived from the MSMouse class (same thing for MSKeyboard). The derived classes are shown here.
Now that I have found the WMI classes that I want to query, I have a couple of choices. If I use the Get-CimInstance cmdlet, I need to supply each class: MSMouse_ClassInformation and MSMouse_PortInformation. But if I use the Get-WmiObject cmdlet, I can take advantage of another unsupported trick. Remember, I said the MSMouse and MSKeyboard classes are abstract? It is not supported to query abstract classes, and the Get-CimInstance cmdlet enforces this ban. However, the Get-WmiObject cmdlet does not. Therefore, when I query an abstract class, the query automatically routes to the two derived classes, and it is from there the answer returns.
Here is the query—I passed the results to the HasWmivalue function from my HSG*WMI* module to filter out empty and system properties.
PS C:\> gwmi msmouse -Namespace root\wmi | ? instancename -match 'hid' | haswmivalue
\\EDLT\root\wmi:MSMouse_PortInformation.InstanceName="HID\\{00001124-0000-1000-8000-00805f9b34fb}_VID&0002
045e_PID&0702&Col02\\9&da0cc6e&0&0001_0"
==========================================================================================================
========================================
Name Value
---- -----
Active True
Buttons 5
ConnectorType 2
DataQueueSize 2
InstanceName HID\{00001124-0000-1000-8000-00805f9b34fb}_VID&0002045e_PID&0702&Col02\9...
\\EDLT\root\wmi:MSMouse_ClassInformation.InstanceName="HID\\{00001124-0000-1000-8000-00805f9b34fb}_VID&000
2045e_PID&0702&Col02\\9&da0cc6e&0&0001_0"
==========================================================================================================
=========================================
Active True
DeviceId 18446738026718451632
InstanceName HID\{00001124-0000-1000-8000-00805f9b34fb}_VID&0002045e_PID&0702&Col02\9...
I can do the same thing with the MSKeyboard class. The MSKeyboard WMI class does contain the abstract qualifier, as shown here.
In addition, instead of only two classes derived from the abstract, there are three, as shown in the WbemTest tool.
Therefore, when I query the abstract MSKeyboard WMI class, three classes report information instead of just the two that report from the MSMouse class. The output from the command is shown here.
PS C:\> gwmi mskeyboard -Namespace root\wmi | ? instancename -match 'hid' | haswmivalue
\\EDLT\root\wmi:MSKeyboard_ClassInformation.InstanceName="HID\\{00001124-0000-1000-8000-00805f9b34fb}_VID&00020
45e_PID&0762&Col01\\9&5c4d6fc&0&0000_0"
===============================================================================================================
=======================================
Name Value
---- -----
Active True
DeviceId 18446738026714008784
InstanceName HID\{00001124-0000-1000-8000-00805f9b34fb}_VID&0002045e_PID&0762&Col01\9&5c4d...
\\EDLT\root\wmi:MSKeyboard_ExtendedID.InstanceName="HID\\{00001124-0000-1000-8000-00805f9b34fb}_VID&0002045e_PI
D&0762&Col01\\9&5c4d6fc&0&0000_0"
===============================================================================================================
=================================
Active True
InstanceName HID\{00001124-0000-1000-8000-00805f9b34fb}_VID&0002045e_PID&0762&Col01\9&5c4d...
Type 81
\\EDLT\root\wmi:MSKeyboard_PortInformation.InstanceName="HID\\{00001124-0000-1000-8000-00805f9b34fb}_VID&000204
5e_PID&0762&Col01\\9&5c4d6fc&0&0000_0"
===============================================================================================================
======================================
Active True
ConnectorType 2
DataQueueSize 1
FunctionKeys 12
Indicators 3
InstanceName HID\{00001124-0000-1000-8000-00805f9b34fb}_VID&0002045e_PID&0762&Col01\9&5c4d...
Well, that is all for now. Join me tomorrow for more cool Windows PowerShell stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy