How do I deploy Keyman 15 with custom keyboards for all users?

For the last 3 years, we’ve been deploying Keyman 13.0.100 successfully in our Windows environment via Microsoft ConfigMgr (SCCM). My installation script deploys the software silently via MSI, and then proceeds to run

kmshell.exe -i -s [keyboard].kmp

This has worked great. Keyman installs and keyboards install for all users (and all future users who log in).

I just got a request to add a second keyboard, so I thought I’d take the time to repackage my application and update it at the same time. Using the same scripts I used before, I modified it for the current version of Keyman, 15.0.271, and included both keyboards. I then run two lines of kmshell.exe to install each keyboard. At the end of the installation though, the keyboards don’t seem to be fully installed, or are half installed. If I open Keyman Configuration and under Keyboard Layouts, click the two keyboards (which show up here, but not my keyboard switcher in the Taskbar), I see that they don’t have languages, but the keyboard shows as installed. There’s just the “Languages:” header to the left, and then an “Add language” button. If I uninstall the keyboard via the interface and reinstall it, a language appears, and it appears properly in the Taskbar keyboard switcher.

I took the 15.0.271 installer out and swapped it with the 13.0.100 installer, and it worked properly. I figured there must have been some sort of change to the application deployments, so I did some searching and came across this very helpful post by Marc, which cleared things up…partially.

This seems to be the piece I was missing for Keyman 14 and up:

kmshell -s -ikl KeyboardID BCP47Tag

The problem is making this work for all users, including the Default Profile (so future users who log in have the keyboard). Is there any way to tell this to apply to everyone on the system? If this isn’t possible with kmshell, are there any registry keys I can set manually to accomplish the same thing (this I can do for each user in my script)? Otherwise, I’m thinking my solution is to keep using Keyman 13.

Any ideas would be greatly appreciated!

Welcome to the community @Scott!

With Keyman 14 and later versions, the installation of the keyboard into the system, and the linking of a keyboard to a language, have been split into separate processes, which better matches the way Windows works.

The recommended way of assigning keyboards to languages is, as you found already, to run kmshell -s -ikl <keyboardID> <bcp47tag> in a logon script for the user, rather than to statically configure all users. This is in part because the language identifiers that Windows uses can differ per user (see transient language identifiers).

If you only want the logon script to run once, you can use a HKCU registry flag to determine whether the script has been run, to avoid overwriting a user’s language configuration if they change it. Or this could even be a version number for the configuration, to simplify deployment of changed versions. Note that kmshell -ikl is idempotent - you can safely re-run it even if it has already been run.

Thanks for your reply! I’ve taken advantage of ActiveSetup keys in Windows to execute the kmshell -s -ikl commands (one command for each keyboard) per user, and this appears to half work. The keyboards are now showing a language in Keyman Configuration > Keyboard Layouts, which they weren’t before, and the keyboard switcher in the System Tray now shows both languages after ActiveSetup has executed. Looking good so far!

When I try to use the keyboards though, they don’t work, and I’ve realized that the check box next to each of the two keyboards I have isn’t checked in the Keyboard Layouts screen. So, I’m a step further in that the keyboard entries now have a language, but they’re not checked automatically. As soon as I put a check mark next to the keyboards, they work instantly.

What am I missing in order to “check” or enable the keyboards afterwards in my install script?

By the way, I’ve updated my package here to use the latest version now, so 15.0.272 instead of .271, so this was all tested with .272.


EDIT: Ok, using Process Monitor, it looks like checking the boxes in the GUI to enable the keyboard places a couple registry entries at:

  • HKCU\SOFTWARE\Keyman\Keyman Engine\Active Keyboards\0 - which has a value of the keyboard name
  • HKCU\SOFTWARE\Keyman\Keyman Engine\Active Keyboards<Keyboard>\keyman id - which has a value of 0

I could probably script this for each user too, but this seems messy because there’s also a number of other keys being changed when I click the check box in the GUI that appear to be Microsoft control panel and settings type registry keys, and I don’t want to mess with those necessarily if there’s more going on behind the scenes. I thought maybe the keyboards weren’t enabled because I had unchecked them while testing something, but even after deleting my HKCU Software Keyman key altogether and reinstalling, the default for these keyboards, although we’ve fixed the language adding problem, is still unchecked.

There must be a way to enable the keyboards via automation somehow that I’m missing. Is there another step, or is this a bug?

From my understanding of what is happening, kmshell.exe (via kmcomapi.dll) should enable any newly installed keyboards the first time it starts for a given user account:

So I am not sure why that is not happening for you?

kmshell.exe does not currently provide any command-line option to enable or disable a keyboard, but you can do so via COM with IKeymanKeyboardInstalled/Loaded.

This topic shows how to instantiate via VBScript; there are similar methods with PowerShell: IKeyman Interface

I ended up just doing the registry entries per user, as I mentioned in my last post. I set those keys at the time of install both for all users on the system currently, as well as the Default User profile. Fortunately, this seems to be enough.

  • HKCU\SOFTWARE\Keyman\Keyman Engine\Active Keyboards\0 - which has a value of the keyboard name
  • HKCU\SOFTWARE\Keyman\Keyman Engine\Active Keyboards\keyman id - which has a value of 0

I assume that by these keys being there when the user launches the Keyman software for the first time, Keyman sees that these keyboards should be active and does whatever else it needs to do to Windows in order to make that work. At least that’s what seems to be happening and it’s working, so I won’t complain!

My only other thought is… is the reason it doesn’t work the way you describe because of the order I’m doing things in my script?

This it the order:

  • Install Keyman
  • Run kmshell.exe -firstrun
  • Copy the keyboards to the system
  • Install the keyboards with kmshell.exe -i -s “keyboard.kmp”
  • Configure ActiveSetup key with kmshell.exe -s -ikl KeyboardID BCP47Tag
  • Then finally set the registry keys as I had above.

This seems to work reliably. But the only thing I could think of as to a reason why this might not be working was the fact I ran the -firstrun at the beginning (which was always fine in Keyman 13). Does the order of when this is ran matter?

Thanks again for your help!

Hi Scott,

Yes, I think the -firstrun parameter may be the issue here; if Keyman sees that it is already configured, it won’t migrate keyboards. But I feel like -ikl should be enabling the keyboard, so that may be a gap which we should address. I’ve opened an issue to investigate this more deeply.

Just to give this a final test, I ended up removing my block of code that adds the keyboard activation keys (the two registry paths in my last couple messages) and instead simply taking the “kmshell -firstrun” code and moving it down to the end of my script. So, the new script order is:

  • Install Keyman
  • Copy the keyboards to the system
  • Install the keyboards with kmshell.exe -i -s “keyboard.kmp”
  • Configure ActiveSetup key with kmshell.exe -s -ikl KeyboardID BCP47Tag
  • Run kmshell.exe -firstrun

This did not activate the keyboards (same problem as before). If I navigate to HKCU\SOFTWARE\Keyman\Keyman Engine\Active Keyboards, I see the two keyboards I’m installing as subkeys, and they each contain a Languages subkey with the correct values in it. But each keyboard key itself doesn’t contain a keyman id value, and likewise, the Active Keyboards key doesn’t contain a number value with the keyboard name to match, as would be expected if they were active.

I uninstalled again and cleaned up as I usually do after each attempt (deleting registry keys and ProgramData Keyman directory), and reinstalled using my original script from my previous post (with kmshell.exe -firstrun right after installation, and then setting the activation keys manually last), and this worked again. I’ll use this script for now.

Thanks again for your time, and I hope this extra little bit of info helps in troubleshooting!

1 Like

That’s helpful additional data, thank you!