Anyone who’s ever done international OS deploys knows the fun of dealing with regional settings. Recently, I wanted to improve some automation and inventory the keyboard layout to automatically re-deploy the same settings on hardware replacements.
The trouble with keyboards is who do you trust? In reality, all keyboards are identical, they just have some different ink on the top. There are a couple exceptions for Japanese and Korean keyboards though as they might have 106 or 109 keys. Since all keyboards are generally the same, we have to tell the OS what the layout is since the keyboard itself does not provide any meaningful information describing itself to Windows. It’s posible to tell Windows you have a standard US English keyboard, even though the print on the keys is French Canadian, and if you close you eyes and just type from muscle memory the letters will come out right.
So where is this info stored in Windows to let it know what keys map to which letters? The answer as usual is multiple places! There is the default keyboard for the currently logged in user (HKEY_CURRENT_USER\Keyboard Layout\Preload), the keyboard that will come up by default when you’re at the Ctrl+Alt+Del login screen (HKEY_USERS\.DEFAULT\Keyboard Layout\Preload), and lastly, the default keyboard(s) that a new user account will get when logging into the computer for the first time which is stored in C:\Users\Default\Ntuser.dat (Keyboard Layout\Preload).
All three of these can be easily viewed in the “Copy Settings” dialog box.
Now, most out of the box systems management solutions use WMI to collect inventory information. There is a class name Win32_Keyboard which has a property named “Layout”, so many of you may already have this inventory information already available to you, but the question is, WHAT IS IT? Microsoft’s fine documentation tells us it is a “Free-form string indicating the layout of the keyboard.”
Well thank you Microsoft for the detail explanation, have your self some fun and change your own keyboard layout, and see what happens to this property, you might find that it doesn’t change. Also, if you have multiple keyboards connected to the system, the value with be the same on all the keyboards no matter the physical layout or print on the keys. Through some testing and many many reboots, here is exactly what the Win32_Keyboard.Layout value represents:
In short, it is simply the default keyboard layout that will be used when logging in at the Welcome (Ctrl+Alt+Del) screen. It is possible to have multiple keyboard layouts available at the Welcome screen, but the WMI value will be the default one which is stored under HKEY_USERS\.DEFAULT\Keyboard Layout\Preload\1
Whatever the data value is here, is what you will see in the WMI class. UNLESS, it is a keyboard that has a substitute layout, for example, adding French Canadian has a Preload\1 value of 0C0C for French Canadian, but there is a Substitute of 1009 for English Canadian. In this case, you will see 1009 as the value in WMI. (Sorry if I’ve offended any of my friends to the north with my lack of French Canadian history, I know there’s French legacy, US, French French, etc, but you get the point 🙂
These values are the InputLocale IDs, there’s a few different Microsoft sites like the one below that document the values, the MDT has a very nice xml file with values and names, and there’s many blogs about how to pull the display name from your very own registry if you like.
If you manually change these registry values, they take effect immediately when you go to the login screen, but you need to reboot the computer before they will show up in WMI.
So is Win32_Keyboard.Layout good enough to use as an authoritative source on what type of physical keyboard a user has? Maybe, for now it’ll be good enough for me, most end users in their right mind probably wouldn’t want to use Alt+Shift or switch the keyboard everytime they log into a computer, but it could happen. Ideally it would be nice to have an array of all users that have profiles on the system with last logged on date, and the default + alternate layouts they have setup. Then I would look at the data of the primary user of the machine and assume their default layout is what is actually attached to the computer. At this point though, it’s just not worth the extra time to write a script for custom inventory.
The important thing is to understand your inventory data and what it means. Be aware that the Layout value in WMI is what you get at the logon screen, and not necessarily what an end user uses day in and day out.