You might be working with a default Windows installation for all your users no matter where they are located. For example, all the devices you order from your vendor have a Windows 11 installation in English. But there might be a requirement in some countries to hand over the device to the end-user not in English but in the language of that specific country.
This creates the challenge of automatically installing an (additional) language pack on the device and changing the complete Windows installation to another language.
In Windows 11 22H2 we have two PowerShell commands available which together make it possible to install a new language pack and change the Windows machine in another language:
Install-Language
Copy-UserInternationalSettingsToSystem
With the PowerShell command Install-Language, we install the new language pack including the Feature On Demand (FOD) items. In the past, we needed to take several steps with our scripts to install the language pack including the FODs, but on Windows 11 we have just this PS command.
Another big advantage of this command, we have no requirement for an Azure AD signed-in user or the related language store app which needs to be assigned to an AAD user. This allows us to install the language pack during Autopilot enrollment.
To get this job done I created a PowerShell script, that is available on GitHub.
In my case, I wrapped the script as a win32 application to deploy it with Microsoft Intune. I assigned it as required to a device group and added it to the Enrollment Status Page. This makes sure the script is executed during Autopilot enrollment and before the first end-user is signed in.
The script explained
The script consists of a few parts, which I explain here.
I first set a few variables.
The Company name is used in the registry path I use for Intune detection.
The language tag is used in several places in the script, to install the new language and set it as the default language in several parts of Windows.
The GeoID is used to set the home location.
To install the new language pack, we simply use the command Install-Language.
When we add the parameter CopySettings, the installed language is set as default in several places on the device.
After installing the language pack, we set the new language as System Preferred UI Language with Set-SystemPreferredUILanguage.
Although we use the CopyToSettings parameter with the install command, not all parts of the system are changed to the new language. In Windows 11 we have a new PowerShell command available; Copy-UserInternationalSettingsToSystem. This command Copies the current user’s international settings (Windows Display language, Input language, Regional Format/locale, and Location/GeoID) to the Welcome screen, system, and new user accounts. This changes the last pieces of the system to the new language.
But before we can do that, we first need to configure the new language for the account (system) under which the script is running, because the international settings are copied from the current user to the system.
That is done for several parts of Windows with the below commands.
After setting the language defaults, this is copied to the system.
And as last, I add a registry key, which is used for Intune detection.
That’s all for the script.
Win32 install command and detection rule
In case you want to wrap the script as a WIN32 app to deploy it during Autopilot enrollment these are the install command and detection rule you can use.
For the install and uninstall commands, I use the same rule. This is because I don’t provide an uninstall script.
This is my install rule, change it so it matches the name of your PowerShell script:
PowerShell.exe -ExecutionPolicy Bypass -file .\InstallLanguagePackDuringAutopilotESP_Windows11nl-NL.ps1
At the end of the script, a registry key is written when the language is installed successfully. This registry key is used in Intune for the detection of the installation status of the package.
This is the detection rule, change it to match your needs (company name, script version and language):
Key path: HKEY_LOCAL_MACHINE\Software\Klapwijk\LanguageXPWIN11ESP\v1.1
Value name: SetLanguage-nl-NL
Detection method: Value exists
The end-user experience
When we have a look at a device that was installed with an English (en-US) Windows 11 22H2 image and the script executed to install the Dutch (nl-NL) language, this is the Welcome screen shown in Dutch after enrollment.
And the login screen is shown in Dutch.
If we have a look at the language and region settings tab in Windows, we see the Windows display language is set to Nederlands (Dutch). And also Country or region is set to Nederland (The Netherlands).
Searching shows results in the new language.
The Microsoft Store is completely shown in the new language.
But directly after signing in to the device, we see in the start menu that store applications are still updating, because some app names show in Dutch and others still show in English.
So it might be a good idea the also remove unused/ unwanted store apps during the enrollment, to reduce the time of updating all these apps.
But after some time, all store app names show in the new language.
And to confirm via PowerShell under the user, all these items are set to Dutch and The Netherlands.
So that’s all to completely change the language of a Windows 11 device during Windows Autopilot enrollment.
If you are interested in changing the complete Windows language of an existing device in an automated way, also have a look at this blog post of mine.
If you want to change the time zone automatically (during Autopilot enrollment), have a look at this blog post.
Again, the script is found on my GitHub. Let me know if you make any improvements/ changes to the script for your usage in the comments below.
21 Comments
Hi Peter,
I’ve tried using your script in our Autopilot environment, for applying Japanese Language Pack for our Japanese users, but somehow it just fails with a dummy error I can’t really find what it means…
Install-Language : Failed to install language. ErrorCode: -2147024809. Please try again.
At C:\Windows\IMECache\6ffc9955-c265-4e62-9571-c076e57f592a_5\InstallLanguage.ps1:96 char:9
+ Install-Language $language -CopyToSettings
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotInstalled: (:) [Install-Language], Exception
+ FullyQualifiedErrorId :
FailedToInstallLanguage,Microsoft.LanguagePackManagement.Powershell.Commands.InstallLanguage
Install-Language : Failed to install language. ErrorCode: -2147024809. Please try again.
At C:\Windows\IMECache\6ffc9955-c265-4e62-9571-c076e57f592a_5\InstallLanguage.ps1:96 char:9
+ Install-Language $language -CopyToSettings
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotInstalled: (:) [Install-Language], Exception
+ FullyQualifiedErrorId : FailedToInstallLanguage,Microsoft.LanguagePackManagement.Powershell.Commands.InstallLang
uage
Does that ring a bell to you by any chance ?
Thanks a lot !
Hi Stéphane,
This seems it is just the installation of the Language pack itself, by running Install-Language command. I’ve seen this once before, but strange enough after a wipe on the same device all went fine the second time.
If you take a test device, are you able to install the language (already running in Windows) by the install-language account?
Hey Stéphane,
I have the same issue here.. Can’t install a language through Powershell. It’s ether working on Intune nor directly on the client in a local powershell session.
Did you found any solution about this issue?
Thanks a lot!
Same problem running the script both via a win32 and platform script.
Hangs for many minutes before the autopilot/esp service ends it and continues/fails the esp.
That is really interesting read. We had all kinds of issues with Language pack install during SCCM/PXE task sequence. Mainly, cos the ISO was US eng, and we tried to inject Cumulative updates. But the FoD / Lang packs were all installed during the TS based on variables (preselection with UI++). The end result was a failure up until we realized that the cumulative udpate must be reaplied after the lang pack install. So wim servicing is no longer in place.
WIM
Lang pack (if requested)
LCU
TADA.WAV.
Glad to see that it’s vastly different via AutoPilot. Can’t wait to try.
Do you also have a tip for the Language dependend Apps like Teams / office / Outlook
Hi Peter,
I have the Issue, that after running your Skript within the Autopilot the Account Setup step fails. It fails at “Apps” It’s running into a timeout although MS is already working in he background. I can even restart the machine and it would work just fine.
Dou you have an idea how this is related?
autopilot gives error 0x81036502
In my attempt to localize to English (Canada), I too was seeing a -2147024809 error on fresh install of the en-US Pro Retail ESD. It didn’t outright fail to install, rather the error stated it was only able to “partially install”.
Despite ChatGPT insisting that Canadians should use en-US as a base, I was able to avoid the error by installing the en-GB ESD.
My observation is that when using en-US as a base, the “Install-Language en-CA -CopyToSettings” command attempts to download an LXP, whereas if I start with en-GB, only an LP is downloaded.
For those not aware, the display language default for English (Canada) is actually English (United Kingdom):
https://answers.microsoft.com/en-us/windows/forum/all/english-canada-defaults-to-english-uk/dea95b3f-0a8e-4203-a2a6-685fc7997fb4
So we have used the script in SCCM and it works great. Currently the OS installed is US and we install en-GB as the language. When the OSD completes it asks user to select en-GB or US. Anyway in your script to remove the language
I’ve not tested this, but the Uninstall-Language is available to uninstall a language. Most likely after installing the language pack, you first need to reboot the device before the other language can be uninstalled.
Seems to work for the most part, however I see no change in the TimeZone.
What would you recommend to change/add to the script to add this during the ESP?
No, the time zone isn’t part of changing the language.
I recently wrote this article on changing the time zone; https://inthecloud247.com/automatically-configure-the-time-zone-during-autopilot-enrollment
Hello Peter,
I want to deploy this via Intune but what are the install/uninstall commands and detection rule?
Hi Hennie,
I added some info to the blog post to describe these values.
Peter,
This is great! It worked like a charm for me. I would like the default language and location to still be en-US. What’s the best approach to do that given your script? Should a $language2 be added or parts of your script be removed?
Hi Gordon,
Regarding the default language, remove CopySettings from the script and see if that does the job for you.
If you mean the location that is retrieved by running Get-WinHomeLocation, you need to change the value for $geoId to 244.
I also would like to know what I should change in the script if I need the Display Language in US and all other settings in the language I define.
Thanks in advance!
To add a little more details.
Our PC’s come with Danish installed. But our requirements are US as corporate Display Language.
So I’d need to install the US as Display language as well as install the language needed for the other settings, region, time/date, keyboard etc.
Got any tips for me Peter?
I’m not sure if this is the right script you need to use as you only want to change the display language.
You’re now mentioning different settings, that are managed with different settings/ PowerShell commands.
Set-WinHomeLocation for example changes the location.
With Get-WinUserLanguageList you can change the keyboard.
But you might also need Set-WinSystemLocale, which needs to be run as administrator. So you need to see for yourself which combinations of settings/ commands does the job in your situation.
I’ve recently tested this (without reading this great article beforehand) and came up with a very similar script. I initally tried to set it up as platform script, but I really dislike the user experience during autopilot with long running platform scripts, so I added it as Win32 App as well (just wrapped with PSADT).
What kind of bugs me is the timing. Even with a modern, fast laptop being connected to a 250 Megabit Internet connection the process of adding a language takes up to 25 minutes for me. And I try to keep the ESP as slim as possible, since Office 365 already takes a good portion of the time during ESP.
Unfortunatly I ran a bit tight on the clock and switched to a different method (as we use OSDCloud anyways currently in this special use case). But I was wondering if anyone got better runtimes with using the “-ExcludeFeatures” parameter. I’m just not sure yet on how to add the FoD languates afterwards. Maybe running the command again without the switch?