Saturday, July 19, 2014

Input Localisation for different systems

As usual, Apple is different from any other brand name computer: their keyboard for french Canadian localisation is different from any other brand. All other standard Canadian french keyboards have a layout called exactly that: Canadian French. Apple french keyboard is Canadian Multilingual Standard. Following is the combined documentation resulting of almost a week of reading and tests on systems to finally figure it all out.

Ideally in a French Cnadian stup environment or in any other setup with multiple default keyboard options, we are looking for the following:
  • Apple:
    • FRA-CMS (French Canadian Multilingual Standard) keyboard
    • ENG-CMS (English Canadian Multilingual Standard) keyboard
  • anything else
    • FRA-CAFR (French Canadian French) keyboard
    • ENG-CMS (English Canadian Multilingual Standard) or ENG-US (English US) keyboard
It could be easily accomplished by changing the settings and deleting the extras that we do not need in the following list. Then, this admin settings can be copied to New user profiles and System/login screen settings.

However, this task seems to be harder to do during the deployment. For the moment, I haven't found any way to do it.
In general, we could, as usual, use our make collection variable to set the Input Locale but how?
  1. Using unattend.xml
  2. Using custom script
  3. Direct registry edit

Codes

Before we start, we have to figure out the codes for each Input Locale:
From Microsoft (technet and msdn), we can get two following sets of info:
  • http://technet.microsoft.com/en-us/library/hh825682.aspx
    • English - Canada
      • Primary --> en-CA: United States - English (1009:00000409)
      • Secondary ---> en-CA: Canadian Multilingual Standard (1009:00011009)
    • French - Canada
      • Primary --> fr-CA: Canadian Multilingual Standard (0c0c:00011009)
      • Secondary ---> en-CA: Canadian Multilingual Standard (1009:00011009)
  • http://msdn.microsoft.com/en-ca/goglobal/bb895996.aspx
    • English_Canadian
      • 1009:00000409,
      • 1009:00011009,
      • 1009:00001009
    • French_Canadian
      • 0c0c:00011009,
      • 0409:00000409
Have you noticed something? Actually there are few things that do not look nice.
  1. French - Canada codes from technet we notice that there is no French Canadian keyboard. Moreover, the secondary keyboard specified is actually an English one?!
  2. The article from MSDN specifies two keyboards for French Canadian and three form English Canadian?
To clear out all this weird things, we have to look at how the codes are defined. The code has two components:  language and keyboard layout separated by a column. Moreover, the combination has to be compatible. That is, we cannot set "anything: anything" and just assume that it will work.
Languages:
  • 0c0c - French (fr)
  • 0409 - English (en) US
  • 1009 - English (en) Canadian
Keyboard layout:
  • 00000409 - US layout
  • 00011009 - Canadian Multilingual Standard layout
  • 00001009 - Who knows??? According to some old post from 2003, it looks like it is French Canadian. We will confirm it in the section 3.

1. Using unattend.xml

This method involves two parts, we could try to use custom collection variables directly in unattend.xml or we could use a custom script to modify the unattend.xml settings during TS. The first option will be covered here and the second will be discussed in the third section.

Unfortunately, I was not able to make custom collection variables work. Defining custom collection variables in TS or in appropriate collection and using them in unattend.xml did not give any results. The variables were not replaced by their respective values. As some have suggested, I removed the line in xml referencing to wim file: no difference. If some one wants to test this method, look at C:\Windows\Panther\UnattendGC\setuperr.txt . If this file has no errors recorded (empty) and you still want to check what was set and how look at setupact.txt in the same location. Somewhere towards the middle of the file setupact.txt you will find the following strings:

In this specific example you may notice that unattend.xml specifies two languages: "0c0c:00001009;0409:00000409" or, according to our codes, "French - Canadian French" and "English - US" inputs. However, the unattend.exe will add four(4) languages! It adds the same languages and in the same order as we see in the first example image of this post. That is, we get:
  • en-CA with CMS
  • fr-CA with CAFR
  • fr-CA with CMS
  • en-US
In this specific example, it looks like the code 0c0c:00001009 has triggered the installation of all 3 keyboards. However, the default keyboard was selected as fr-CA with CAFR because this specific deployment was on a Lenovo laptop. Similar behavior on an iMac with original keyboard gives us fr-CA with CMS as the default keyboard. While it looks like the keyboards are properly selected during deployment, it is still not good enough: users will get mixed up with two different french keyboards.

So lets attempt to deploy the system with no input locale specified. In the case of our Lenovo test system, we get en-CA with CMS and fr-CA with CMS. In the Apple install, we get

2. Using custom script

There are two ways to use a custom script: first we can try to use power-shell to set the input locale or we can try to use a script to set in the unattend.xml the locale. The second method is obviously out of question (see the experiments with unattend.xml). 
The script itself is simple:
Set-WinUserLanguageList -LanguageList fr-CA,en-CA -force
It will work in windows 8 and 8.1 but not earlier. It can be used as part of GPO deployment or in the TS. This is how it looks in the TS:


Unfortunately this methods is not perfect either:
  1. PowerShell script does not accept codes.
  2. It works only for the account it is deployed on
Thus, we are back to the square one: too many keyboards for no reason and no control of what gets set where. Our only solution is to go with a registry edit. Of course, this change will be probably done by a script but it will still be a direct reg change with all the problems it can lead to.

3. Direct registry edit

Probably the best and the worst way to do it but it looks like the only option left. It is the worst because we can kill the system; the best because it looks like the only way to control exactly what keyboard is applied where.
According to the blogpost on http://www.powershellmagazine.com/2014/03/24/set-keyboard-layouts-available-on-logon-screen-in-windows-8-1/ , we can simply copy appropriate codes to appropriate places.
Current user input locale keys are located in HKEY_CURRENT_USER\Keyboard Layout\Preload
Default input locale is located in HKEY_USERS.DEFAULT\Keyboard Layout\Preload key
In the registry, the input locale is supposed to be stored in a hex format (LCIDHex code to be precise). The codes can be found in the already familiar list: http://msdn.microsoft.com/en-ca/goglobal/bb895996.aspx For example, LCIDHex code 0409 is in fact en-US or 0409:00000409 input locale. However... the example below will demonstrate that this is not the case.

In the case of the above mentioned Lenovo install, we can see in the HKEY_CURRENT_USER\Keyboard Layout\Preload the following keys:
In the HKEY_CURRENT_USER\Keyboard Layout\Substitutes we can also find:
For this Lenovo, we do not need fr-CA with CMS input locale. Removing it (using the interface) gives us the following keys and keyboards left:
HKEY_CURRENT_USER\Keyboard Layout\Preload
HKEY_CURRENT_USER\Keyboard Layout\Substitutes


So lets continue and keep only the two keyboards we need. Lets say it is en-US and fr-CA with CAFR keyboard:
HKEY_CURRENT_USER\Keyboard Layout\Preload
HKEY_CURRENT_USER\Keyboard Layout\Substitutes

From the above tests, we can see that the combination of Preload and Substitutes creates the keyboards we use for all systems except Apple make. Notice that:
  • the registry uses the same old codes(not IDs) that we have always delt with
  • the order in the Preload defines the default keyboard (first in the list)
  • the locale that has a secondary/tertiary keyboard is detailed in the Substitutes. For example, en-US (code 409)  has only one keyboard; hence, no entry in the Substitutes. fr-CA (code 0c0c) has many options; therefore, there is a specification of exact language and layout in the Substitutes: 0c0c - French Canadian with 1009 - French Canadian keyboard.

So now we can set this in HKEY_USERS.DEFAULT\Keyboard Layout\Preload key  with the following registry file (or any other script that can suit you): 

Windows Registry Editor Version 5.00

[HKEY_USERS\.DEFAULT\Keyboard Layout]
[HKEY_USERS\.DEFAULT\Keyboard Layout\Preload]
"1"="00000c0c"
"2"="00000409"
[HKEY_USERS\.DEFAULT\Keyboard Layout\Substitutes]
"00000c0c"="00001009"
[HKEY_USERS\.DEFAULT\Keyboard Layout\Toggle]

Now, how can we set it in the login screen? According to microsoft kb (http://support.microsoft.com/kb/243330) there are a few security IDs that we can identify. We can also use a full registry search to find all related settings. After all, we will get the following additional registry keys to set:
[HKEY_USERS\S-1-5-18\Keyboard Layout]
[HKEY_USERS\S-1-5-18\Keyboard Layout\Preload]
"1"="00000c0c"
"2"="00000409"
[HKEY_USERS\S-1-5-18\Keyboard Layout\Substitutes]
"00000c0c"="00001009"
[HKEY_USERS\S-1-5-18\Keyboard Layout\Toggle]

[HKEY_USERS\S-1-5-19\Keyboard Layout]
[HKEY_USERS\S-1-5-19\Keyboard Layout\Preload]
"1"="00000c0c"
"2"="00000409"
[HKEY_USERS\S-1-5-19\Keyboard Layout\Substitutes]
"00000c0c"="00001009"
[HKEY_USERS\S-1-5-19\Keyboard Layout\Toggle]

[HKEY_USERS\S-1-5-20\Keyboard Layout]
[HKEY_USERS\S-1-5-20\Keyboard Layout\Preload]
"1"="00000c0c"
"2"="00000409"
[HKEY_USERS\S-1-5-20\Keyboard Layout\Substitutes]
"00000c0c"="00001009"
[HKEY_USERS\S-1-5-20\Keyboard Layout\Toggle]

Note that 1-5-18 is a Local System account used by the OS; 1-5-19 is NT Authority as a Local Service account and 1-5-20 is NT Authority as Network Service account. Following the same strategy, we get the registry keys for Apple type of computers:
Windows Registry Editor Version 5.00

[HKEY_USERS\.DEFAULT\Keyboard Layout]
[HKEY_USERS\.DEFAULT\Keyboard Layout\Preload]
"2"="00001009"
"1"="00000c0c"
[HKEY_USERS\.DEFAULT\Keyboard Layout\Substitutes]
"00001009"="00011009"
"00000c0c"="00011009"
[HKEY_USERS\.DEFAULT\Keyboard Layout\Toggle]

[HKEY_USERS\S-1-5-18\Keyboard Layout]
[HKEY_USERS\S-1-5-18\Keyboard Layout\Preload]
"2"="00001009"
"1"="00000c0c"
[HKEY_USERS\S-1-5-18\Keyboard Layout\Substitutes]
"00001009"="00011009"
"00000c0c"="00011009"
[HKEY_USERS\S-1-5-18\Keyboard Layout\Toggle]

[HKEY_USERS\S-1-5-19\Keyboard Layout]
[HKEY_USERS\S-1-5-19\Keyboard Layout\Preload]
"2"="00001009"
"1"="00000c0c"
[HKEY_USERS\S-1-5-19\Keyboard Layout\Substitutes]
"00001009"="00011009"
"00000c0c"="00011009"
[HKEY_USERS\S-1-5-19\Keyboard Layout\Toggle]

[HKEY_USERS\S-1-5-20\Keyboard Layout]
[HKEY_USERS\S-1-5-20\Keyboard Layout\Preload]
"2"="00001009"
"1"="00000c0c"
[HKEY_USERS\S-1-5-20\Keyboard Layout\Substitutes]
"00001009"="00011009"
"00000c0c"="00011009"
[HKEY_USERS\S-1-5-20\Keyboard Layout\Toggle]

However, all this work cannot help us if we do not find the way to edit the default user profile saved in ntuser.dat. As aresult, we will have to use some script. In my case, I chose to convert all of the above keys into a cmd line script that will edit the default user profile. At the same time, I could use the script to do more changes (in the default profile or any other profile for that matter): see http://stealthpuppy.com/customize-the-windows-default-profile/ and http://technet.microsoft.com/en-us/library/cc742162.aspx.
For those who like more a VB style approach look here: http://micksmix.wordpress.com/2012/01/13/update-a-registry-key-for-all-users-on-a-system/.
For a PowerShell approach, look here: http://www.powershellmagazine.com/2014/03/24/set-keyboard-layouts-available-on-logon-screen-in-windows-8-1/.

It finally looks like this:

Other
Apple
@ECHO OFF
REM Load the default profile hive
SET HKEY=HKU\Default
REG LOAD %HKEY% %SystemDrive%\Users\Default\NTUSER.DAT

REM Set keyboard locale for Default User
REG ADD "%HKEY%\Keyboard Layout" /f
REG ADD "%HKEY%\Keyboard Layout\Preload" /f
REG ADD "%HKEY%\Keyboard Layout\Preload" /v "1" /t REG_SZ /d "00000c0c" /f
REG ADD "%HKEY%\Keyboard Layout\Preload" /v "2" /t REG_SZ /d "00000409" /f
REG ADD "%HKEY%\Keyboard Layout\Substitutes" /f
REG ADD "%HKEY%\Keyboard Layout\Substitutes" /v "00000c0c" /t REG_SZ /d "00001009" /f

REM Set keyboard locale for .default
REG ADD "HKEY_USERS\.DEFAULT\Keyboard Layout" /f
REG ADD "HKEY_USERS\.DEFAULT\Keyboard Layout\Preload" /f
REG ADD "HKEY_USERS\.DEFAULT\Keyboard Layout\Preload" /v "1" /t REG_SZ /d "00000c0c" /f
REG ADD "HKEY_USERS\.DEFAULT\Keyboard Layout\Preload" /v "2" /t REG_SZ /d "00000409" /f
REG ADD "HKEY_USERS\.DEFAULT\Keyboard Layout\Substitutes" /f
REG ADD "HKEY_USERS\.DEFAULT\Keyboard Layout\Substitutes" /v "00000c0c" /t REG_SZ /d "00001009" /f

REM Set keyboard locale for S-1-5-18
REG ADD "HKEY_USERS\S-1-5-18\Keyboard Layout" /f
REG ADD "HKEY_USERS\S-1-5-18\Keyboard Layout\Preload" /f
REG ADD "HKEY_USERS\S-1-5-18\Keyboard Layout\Preload" /v "1" /t REG_SZ /d "00000c0c" /f
REG ADD "HKEY_USERS\S-1-5-18\Keyboard Layout\Preload" /v "2" /t REG_SZ /d "00000409" /f
REG ADD "HKEY_USERS\S-1-5-18\Keyboard Layout\Substitutes" /f
REG ADD "HKEY_USERS\S-1-5-18\Keyboard Layout\Substitutes" /v "00000c0c" /t REG_SZ /d "00001009" /f

REM Set keyboard locale for S-1-5-19
REG ADD "HKEY_USERS\S-1-5-19\Keyboard Layout" /f
REG ADD "HKEY_USERS\S-1-5-19\Keyboard Layout\Preload" /f
REG ADD "HKEY_USERS\S-1-5-19\Keyboard Layout\Preload" /v "1" /t REG_SZ /d "00000c0c" /f
REG ADD "HKEY_USERS\S-1-5-19\Keyboard Layout\Preload" /v "2" /t REG_SZ /d "00000409" /f
REG ADD "HKEY_USERS\S-1-5-19\Keyboard Layout\Substitutes" /f
REG ADD "HKEY_USERS\S-1-5-19\Keyboard Layout\Substitutes" /v "00000c0c" /t REG_SZ /d "00001009" /f

REM Set keyboard locale for S-1-5-20
REG ADD "HKEY_USERS\S-1-5-20\Keyboard Layout" /f
REG ADD "HKEY_USERS\S-1-5-20\Keyboard Layout\Preload" /f
REG ADD "HKEY_USERS\S-1-5-20\Keyboard Layout\Preload" /v "1" /t REG_SZ /d "00000c0c" /f
REG ADD "HKEY_USERS\S-1-5-20\Keyboard Layout\Preload" /v "2" /t REG_SZ /d "00000409" /f
REG ADD "HKEY_USERS\S-1-5-20\Keyboard Layout\Substitutes" /f
REG ADD "HKEY_USERS\S-1-5-20\Keyboard Layout\Substitutes" /v "00000c0c" /t REG_SZ /d "00001009" /f

REM Set keyboard locale for Current User
REG ADD "HKEY_CURRENT_USER\Keyboard Layout" /f
REG ADD "HKEY_CURRENT_USER\Keyboard Layout\Preload" /f
REG ADD "HKEY_CURRENT_USER\Keyboard Layout\Preload" /v "1" /t REG_SZ /d "00000c0c" /f
REG ADD "HKEY_CURRENT_USER\Keyboard Layout\Preload" /v "2" /t REG_SZ /d "00000409" /f
REG ADD "HKEY_CURRENT_USER\Keyboard Layout\Substitutes" /f
REG ADD "HKEY_CURRENT_USER\Keyboard Layout\Substitutes" /v "00000c0c" /t REG_SZ /d "00001009" /f

REM Unload the default profile hive
REG UNLOAD %HKEY%
@ECHO OFF
REM Load the default profile hive
SET HKEY=HKU\Default
REG LOAD %HKEY% %SystemDrive%\Users\Default\NTUSER.DAT

REM Set keyboard locale for Default User
REG ADD "%HKEY%\Keyboard Layout" /f
REG ADD "%HKEY%\Keyboard Layout\Preload" /f
REG ADD "%HKEY%\Keyboard Layout\Preload" /v "1" /t REG_SZ /d "00000c0c" /f
REG ADD "%HKEY%\Keyboard Layout\Preload" /v "2" /t REG_SZ /d "00001009" /f
REG ADD "%HKEY%\Keyboard Layout\Substitutes" /f
REG ADD "%HKEY%\Keyboard Layout\Substitutes" /v "00000c0c" /t REG_SZ /d "00011009" /f
REG ADD "%HKEY%\Keyboard Layout\Substitutes" /v "00001009" /t REG_SZ /d "00011009" /f

REM Set keyboard locale for .default
REG ADD "HKEY_USERS\.DEFAULT\Keyboard Layout" /f
REG ADD "HKEY_USERS\.DEFAULT\Keyboard Layout\Preload" /f
REG ADD "HKEY_USERS\.DEFAULT\Keyboard Layout\Preload" /v "1" /t REG_SZ /d "00000c0c" /f
REG ADD "HKEY_USERS\.DEFAULT\Keyboard Layout\Preload" /v "2" /t REG_SZ /d "00001009" /f
REG ADD "HKEY_USERS\.DEFAULT\Keyboard Layout\Substitutes" /f
REG ADD "HKEY_USERS\.DEFAULT\Keyboard Layout\Substitutes" /v "00000c0c" /t REG_SZ /d "00011009" /f
REG ADD "HKEY_USERS\.DEFAULT\Keyboard Layout\Substitutes" /v "00001009" /t REG_SZ /d "00011009" /f

REM Set keyboard locale for S-1-5-18
REG ADD "HKEY_USERS\S-1-5-18\Keyboard Layout" /f
REG ADD "HKEY_USERS\S-1-5-18\Keyboard Layout\Preload" /f
REG ADD "HKEY_USERS\S-1-5-18\Keyboard Layout\Preload" /v "1" /t REG_SZ /d "00000c0c" /f
REG ADD "HKEY_USERS\S-1-5-18\Keyboard Layout\Preload" /v "2" /t REG_SZ /d "00001009" /f
REG ADD "HKEY_USERS\S-1-5-18\Keyboard Layout\Substitutes" /f
REG ADD "HKEY_USERS\S-1-5-18\Keyboard Layout\Substitutes" /v "00000c0c" /t REG_SZ /d "00011009" /f
REG ADD "HKEY_USERS\S-1-5-18\Keyboard Layout\Substitutes" /v "00001009" /t REG_SZ /d "00011009" /f

REM Set keyboard locale for S-1-5-19
REG ADD "HKEY_USERS\S-1-5-19\Keyboard Layout" /f
REG ADD "HKEY_USERS\S-1-5-19\Keyboard Layout\Preload" /f
REG ADD "HKEY_USERS\S-1-5-19\Keyboard Layout\Preload" /v "1" /t REG_SZ /d "00000c0c" /f
REG ADD "HKEY_USERS\S-1-5-19\Keyboard Layout\Preload" /v "2" /t REG_SZ /d "00001009" /f
REG ADD "HKEY_USERS\S-1-5-19\Keyboard Layout\Substitutes" /f
REG ADD "HKEY_USERS\S-1-5-19\Keyboard Layout\Substitutes" /v "00000c0c" /t REG_SZ /d "00011009" /f
REG ADD "HKEY_USERS\S-1-5-19\Keyboard Layout\Substitutes" /v "00001009" /t REG_SZ /d "00011009" /f

REM Set keyboard locale for S-1-5-20
REG ADD "HKEY_USERS\S-1-5-20\Keyboard Layout" /f
REG ADD "HKEY_USERS\S-1-5-20\Keyboard Layout\Preload" /f
REG ADD "HKEY_USERS\S-1-5-20\Keyboard Layout\Preload" /v "1" /t REG_SZ /d "00000c0c" /f
REG ADD "HKEY_USERS\S-1-5-20\Keyboard Layout\Preload" /v "2" /t REG_SZ /d "00001009" /f
REG ADD "HKEY_USERS\S-1-5-20\Keyboard Layout\Substitutes" /f
REG ADD "HKEY_USERS\S-1-5-20\Keyboard Layout\Substitutes" /v "00000c0c" /t REG_SZ /d "00011009" /f
REG ADD "HKEY_USERS\S-1-5-20\Keyboard Layout\Substitutes" /v "00001009" /t REG_SZ /d "00011009" /f

REM Set keyboard locale for Current User
REG ADD "HKEY_CURRENT_USER\Keyboard Layout" /f
REG ADD "HKEY_CURRENT_USER\Keyboard Layout\Preload" /f
REG ADD "HKEY_CURRENT_USER\Keyboard Layout\Preload" /v "1" /t REG_SZ /d "00000c0c" /f
REG ADD "HKEY_CURRENT_USER\Keyboard Layout\Preload" /v "2" /t REG_SZ /d "00001009" /f
REG ADD "HKEY_CURRENT_USER\Keyboard Layout\Substitutes" /f
REG ADD "HKEY_CURRENT_USER\Keyboard Layout\Substitutes" /v "00000c0c" /t REG_SZ /d "00011009" /f
REG ADD "HKEY_CURRENT_USER\Keyboard Layout\Substitutes" /v "00001009" /t REG_SZ /d "00011009" /f

REM Unload the default profile hive
REG UNLOAD %HKEY%
Each script is part of a package and is configured as an application in SCCM. This will give me an ability to deploy the script to any machine at any time. Note however, that if you choose to deploy the script as an application, the changes in the registry may not be immediately visible to active user: log-off / log-in or a restart sequence is usually a good idea.

TO BE CONTINUED

No comments:

Post a Comment