Deploying Windows 10 dynamically using different languages

Recently I took part in a project where a client has several branch office locations in 13 different countries total. Two countries required a Windows display language other than English (en-US) and all the employees got physical keyboard layouts matching their countries standard layout.

As a result, I wanted to simplify the configuration of Windows locale settings, display languages, keyboard layouts and time zones. The plan was to set the languages dynamically before the OS deployment starts — to make the lives of my colleagues (and mine hopefully 😉) easier.

I could not find a solution which was working properly for Windows 10 1809. So I tried quite a few approaches and ran into many issues. It tempted me to just download all the different WIM files —  one for every language. Luckily I came up with a better approach and this blog post explains how it works.



We are already using UI++ as an OSD front end for other clients and it makes my MEMCM admin life easier. That’s why I wanted to implement a dynamic selection using this tool. I will not be detailing the usage of this tool and show my exact configuration, but much rather only show the relevant parts of the language selection.

What happens when you select the language?

The following SMSTS variables are set and also displayed on a summary page at the end:
– Hostname (generated from the location code and serial number)
– Language
– Regional settings

– Location code

OSD Language Selection-04
The resulting variables

Here are the relevant parts from the UI++ configuration.

Selecting the variables:

<Action Type="Input" Name="ClientSetupInput" Title="Language and Location" ShowBack="True">
	<ChoiceInput Variable="OSLanguage" Question="Select OS Language" Required="True" Default="English">
		<Choice Option="English" Value="en-US" />
		<Choice Option="German" Value="de-DE" />
		<Choice Option="Spanish" Value="es-ES" />
	<ChoiceInput Variable="OSRegionalSettings" Question="Select Regional Settings" DropDownSize="13" Required="True">
		<Choice Option="Czech" Value="cs-CZ" />
		<Choice Option="Danish" Value="da-DK" />
		<Choice Option="Dutch" Value="nl-NL" />
		<Choice Option="Finnish" Value="fi-FI" />
		<Choice Option="French - fr-FR" Value="fr-FR" />
		<Choice Option="French - fr-BE" Value="fr-BE" />
		<Choice Option="German" Value="de-DE" />
		<Choice Option="Greek" Value="el-GR" />
		<Choice Option="Italian" Value="it-IT" />
		<Choice Option="Latvian" Value="lv-LV" />
		<Choice Option="Polish" Value="pl-PL"  />
		<Choice Option="Spanish" Value="es-ES" />
		<Choice Option="Swedish" Value="sv-SE" />

Setting the SMSTS variables for the Task Sequence:

<Action Type="TSVar" Name="Language">%Language%</Action>
<Action Type="TSVar" Name="RegionalSettings">%RegionalSettings%</Action>

Task Sequence

And this is what it looks like in the TS editor, in this case choosing German for OS language and regional settings. You can find the used commands below.

Commands used:

#Install Client LP:
dism.exe /norestart /online /add-package /packagepath:.\

#Install Feature on Demand language features:
dism.exe /norestart /online /add-package /packagepath:.\FoD\
dism.exe /norestart /online /add-package /packagepath:.\FoD\
dism.exe /norestart /online /add-package /packagepath:.\FoD\
dism.exe /norestart /online /add-package /packagepath:.\FoD\
dism.exe /norestart /online /add-package /packagepath:.\FoD\

#Apply regional settings:
control intl.cpl,, /f:"de-DE.xml"

#Apply time zone settings:
cmd.exe /c tzutil.exe /s "W. Europe Standard Time"

You can download the necessary ISO files for setting up the languages from VLSC:
Client Language Pack: SW_DVD9_NTRL_Win_10_1809_32_64_ARM64_MultiLang_LangPackAll_LIP_X21-91305.ISO
Feature on Demand: SW_DVD9_NTRL_Win_10_1809_64Bit_MultiLang_FOD_1_X21-91307.ISO

This is what my folder structure looks like for the OS languages (German in this example).
The package 1809 – German – de-DE from the above screenshots also refers to the base of the German -de-DE folder. All XML files are in one folder which I use in only one package to keep it simple:

Here is the content for the German de-DE XML file. Only with the below syntax I could get it to work correctly, so I advise you to only change the corresponding parameters.

<gs:GlobalizationServices xmlns:gs="urn:longhornGlobalizationUnattend">
    <!--User List-->
        <gs:User UserID="Current" CopySettingsToSystemAcct="true" CopySettingsToDefaultUserAcct="true" />

    <!--Display Language-->
        <gs:MUILanguage Value="de-DE" />
        <gs:MUIFallback Value="en-US" />
	<!--User Locale-->
        <gs:Locale Name="de-DE" SetAsCurrent="true" ResetAllSettings="false" />

    <!-- SystemLocale: Specifies the language for non-Unicode programs. -->
    <gs:SystemLocale Name="de-DE" />
    <!--input preferences-->
		<gs:InputLanguageID Action="add" ID="0407:00000407" Default="true" />
        <gs:InputLanguageID Action="remove" ID="0409:00000409" />
        <gs:GeoID Value="94" />

In case you need to look up other values for the above XML files, you can find them here:

InputLanguageID (keyboard layouts):
GeoID value:
Locale name:

Since MEMCM 1910 you can also set the above settings with the default step ‘Apply Windows Settings’, which I have not tested yet:

MEMCM 1910 OSD Language Features

I hope this post will save you some time researching solutions for this scenario. If you have any feedback, please let me know in the comments. 🙂

You may also like

Leave a Comment