The Hitchhiker’s Guide to Multi-Lingual IPU

Here’s a scenario: you work for a global (intergalactic?) organization. Across your fleet of devices, you’ve got many different languages. You’re looking for a clever way to keep all these machines updated when new builds of Windows come out.

Let’s say you’ve got a device that is localized for de-DE. If you were to attempt to run an IPU using an en-US setup media, the IPU would fail quite early on–that’s because the device’s UI language must match the language of the IPU setup media.

Don’t Panic.

There’s several ways you could approach this. The solution I’ve been happiest with is one by Wilhelm Kocher. A very high level overview of this is:

  • Detect if the device’s UI language is different from the install media
  • If it matches, IPU as usual. If it’s different:
    • Restart the device into Windows PE
    • Apply the install media’s language pack
    • Change the device’s UI language so it matches the install media
    • Restart the device into Windows, and resume the IPU (installing the device’s native language pack during the process)
    • Change the device’s UI language back to the native language

Let’s dive in and see how we can automate this.

Disclaimer: The post you are about to read is heavily inspired by Wilhelm’s. The goal of this post is to extend his original solution with a couple quality-of-life improvements (and a blocking issue with Windows 7 machines!). Call it stealing with pride or whatever you’d like, just take note that the real mastermind behind the inception of this post is him. 🙂

 

Alright. To begin, we’re going to need a few things.

 

The Prerequisites: Downloads

Windows 10 ISO (en-US)

If you don’t have this already, we’ll need the Windows 10 ISO so you can install Windows. In this guide, we’ll be using the en-US ISO. This is available on the VLSC.

Language Packs

There’s two categories of language packs that we’ll need:

  • First, we need the en-US language pack for every version of Windows in your environment (that will be IPU’d). These language packs will be used to change older versions of Windows into en-US so they can be upgraded.
    • If you need Windows 7/8.1 language packs, download the language pack ISOs from the VLSC.
    • If you need Windows 10 1507 and 1511 language packs, download the language pack ISOs from the VLSC.
    • If you need Windows 10 1607 or later, you can use this script to download language packs from Windows Update (we’ll dig into this later).
  • Next, we need language packs for every language in your environment (only for the build of Windows 10 that you’re upgrading to). These language packs will be used to change the IPU’d Windows installation back into the device’s native language.

Features on Demand – Disc 1

The Features on Demand disc includes, amongst other things, the rest of the language features (speech, handwriting, text to speech, OCR). We’ll only need disc 1, and we only need the version for the build of Windows 10 that you’re upgrading to.

Note: If you don’t download the FoD and add the extra language features to your language packages, it’s not the end of the world–Windows will download these automatically (assuming your firewall doesn’t block Windows Update traffic). That being said, I prefer my IPU’d machines to be localized out of the box so users can hit the ground running.

A Windows 7 Fix

Are you running IPUs on Windows 7 clients? You will need a patched lsasrv.dll.mui, otherwise the device will enter a “black screen of death” after the UI language is changed. You can read more and download the file from here!

OSD MUI

Finally, we’re going to need the OSD MUI Scripts created by Wilhelm Kocher. These can be found on his blog (OSD_MUI_OSDScriptsMUI.zip).

 

Next, let’s get our ConfigMgr packages in order.

Prerequisites II: The Packaging

Existing Languages

To begin, let’s get the en-US language packs added for all of those to-be-IPU’d versions of Windows in your environment.

Unfortunately for Windows 7 through Windows 10 1511, we have a bit of manual work:

  1. Mount the language pack ISO
  2. Navigate to \langpacks\en-us (or \x64\langpacks\en-us)
  3. Copy the lp.cab file and create a package for it (no program)

 

For Windows 10 1607 through 1803, you can use a script to download the en-US language pack from Windows Update (and create the package in ConfigMgr for you!)

This script, New-WULanguagePackPackage.ps1, is available on GitHub.

.\New-WULanguagePackPackage.ps1 -SiteServer "CM01" -PackageSourcePath "\\CM01\Sources\OSD\LanguagePacks\Windows10" -XmlSourcePath ".\lp_download.xml"

New Build Languages

Next, we need the language packs for every language in your environment–but only for the build of Windows that you’re upgrading to. We can automate this, too!

For this, mount the Language Pack ISO and the Features on Demand ISO. Nickolaj Andersen provides an excellent script that extracts language packs from their ISO, and I used it as the base for a new script which also extracts language features from the FoD ISO–all while creating the ConfigMgr packages for you.
This script, New-CMLanguagePackPackage.ps1, is available on GitHub.

.\New-CMLanguagePackPackage.ps1 -SiteServer "CM01" -ISORootPath "F:\" -FoDx64RootPath "G:\" -PackageSourcePath "\\CM01\CMSource\OSD\LanguagePacks\Windows10" -LanguagePacks "en-US", "ja-JP", "en-GB", "de-DE", "zh-CN" -LanguagePackArchitecture "x64" -PackageName "Windows 10" -WindowsVersion "1809" -WindowsBuildnumber "17763"

After you run this command, you’ll see that your language pack packages have been created and are ready to go (after they get distributed!)

Windows 7 lsasrv.dll.mui

If you’re planning on upgrading Windows 7 machines, create a package with the patched lsasrv.dll.mui.

OSD MUI

Extract and create a package for the two PowerShell scripts from OSD_MUI_OSDScriptsMUI.zip.

 

Alright, all the pieces are in place. Get your towel ready.

 

Putting it all Together: The Task Sequence

Create a new task sequence based on the “Upgrade an Operating System from an Upgrade Package” template. The example below shows the steps that we’ve added. Other steps/folders have been removed for clarity (and so my screenshot wasn’t a kilometer in length).

Hope you’ve got your FitBit handy, because that’s a lot of steps.

 

Since this task sequence will depend on rebooting into Windows PE, be sure to add your boot image by right-clicking on the task sequence and selecting Properties.

 

Here’s how each step was created:


Run PowerShell Script: Detect MUI Settings

Command: OSDDetectInstalledLP.ps1 (Execution Policy set to Bypass)
Condition: (no condition set)


Group: Change System Culture

Condition: Task Sequence Variable CurrentOSLanguage not equals en-US


Group: Stage en-US Language Pack

Condition: (no condition set)


Download Package Content: Stage lsasrv.dll.mui – Windows 7 (en-US)

Condition: If all conditions are met:

OSArchitecture equals 64-bit
OSVersion equals 6.1.7601

Note: this is step 1 of 2 that helps resolve an issue where Windows 7 devices are unable to boot after the UI language is changed. More details about this fix can be found here.


Download Package Content: Stage Language Pack – Windows 7 (en-US)

Condition: If all conditions are met:

OSArchitecture equals 64-bit
OSVersion equals 6.1.7601

 

Use this step as a template for the remainder of your en-US language packs.

Windows 8.1 OSVersion = 6.3.9600
Windows 10 1511 OSVersion = 10.0.10586
Windows 10 1607 OSVersion= 10.0.14393
Windows 10 1703 OSVersion= 10.0.15063
Windows 10 1709 OSVersion= 10.0.16299
Windows 10 1803 OSVersion= 10.0.17134
Windows 10 1809 OSVersion= 10.0.17763


Run Command Line: Prepare lsasrv

Command: powershell.exe -command "Move-Item -Path C:\lsasrv\*\*.mui -Destination C:\lsasrv\ -Force"
Condition: If folder C:\lsasrv exists


Run Command Line: Prepare Language Packs

Command: powershell.exe -command "Move-Item -Path C:\LanguagePacks\*\*.cab -Destination C:\LanguagePacks\ -Force"

Condition: If folder C:\LanguagePacks exists


Run Command Line: Suspend BitLocker

Command: powershell.exe -command "Suspend-BitLocker -MountPoint "C:" -RebootCount 0"
Condition: (no condition set)


Run Command Line: Suppress User Logon after Reboot

Command: powershell.exe -command "Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\smstsmgr -Name Start -Value 4 -Type DWord -Force; Set-ItemProperty -Path HKLM:\SYSTEM\Setup -Name SetupType -Value 2 -Type DWord -Force; Set-ItemProperty -Path HKLM:\SYSTEM\Setup -Name CmdLine -Value 'system32\osdsetuphook.exe /execute' -Type String -Force"
Condition: (no condition set)

As noted in Wilhelm’s post, this is step 1 of 3 that should be disabled if you run into issues.


Restart Computer: Restart Computer into Windows PE

Condition: (no condition set)


Group: Apply en-US Language Pack

Condition: Task Sequence Variable MUIdetected not exists


Run Command Line: Apply en-US Language Pack

Command: dism.exe /image:%_OSDDetectedWinDrive% /ScratchDir:%_OSDDetectedWinDir%\Temp /Add-Package /PackagePath:%_OSDDetectedWinDrive%\LanguagePacks\
Condition: (no condition set)


Run Command Line: Update lsasrv.dll.mui

Command: cmd.exe /c copy /Y %_OSDDetectedWinDrive%\lsasrv\lsasrv.dll.mui %_OSDDetectedWinDir%\system32\en-us
Condition: If folder %_OSDDetectedWinDrive%\lsasrv exists

Note: this is step 2 of 2 that helps resolve an issue where Windows 7 devices are unable to boot after the UI language is changed. More details about this fix can be found here.


Run Command Line: Cleanup Temporary Language Packs Store

Command: cmd.exe /c rd %_OSDDetectedWinDrive%\LanguagePacks /s /q
Condition: If folder %_OSDDetectedWinDrive%\LanguagePacks exists


Run Command Line: Cleanup Temporary lsasrv Store

Command: cmd.exe /c rd %_OSDDetectedWinDrive%\lsasrv /s /q
Condition: If folder %_OSDDetectedWinDrive%\lsasrv exists


Set Task Sequence Variable: Set MUIdetected

Condition: (no condition set)


Run Command Line: Set UILang en-US on %_OSDDetectedWinDrive%

Condition: (no condition set)


Run Command Line: Copy OSDSetupHook to %_OSDDetectedWinDir%

Condition: (no condition set)

As noted in Wilhelm’s post, this is step 2 of 3 that should be disabled if you run into issues.


Restart Computer: Restart Computer to Installed OS

Condition: (no condition set)


Run Command Line: Re-Enable Task Sequence Service after Reboot

Command: powershell.exe -command "Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\smstsmgr -Name Start -Value 3 -Type DWord -Force"
Condition: (no condition set)

As noted in Wilhelm’s post, this is step 3 of 3 that should be disabled if you run into issues.


Group: Stage Language Packs

Condition: Task Sequence Variable MUIdetected exists


Run Command Line: Resume BitLocker

Command: powershell.exe -command "Resume-BitLocker -MountPoint "C:""
Condition: (no condition set)


Stage Language Pack de-DE

Condition: Task Sequence Variable de-DE exists

Repeat/change as needed, including all language packs that exist in your environment. Be sure to set the condition logic to the correct locale (e.g. en-GB, ja-JP, zh-CN)


Set Task Sequence Variable: Include Language Packs for Upgrade

Task Sequence Variable: OSDSetupAdditionalUpgradeOptions
Value:
/InstallLangPacks C:\LanguagePacks
Condition:
If folder C:\LanguagePacks exists


Upgrade Operating System: Upgrade Operating System (Enterprise SKU)

Condition: Task Sequence Variable OSSKU not equals PROFESSIONAL


Run PowerShell Script: Set UILanguage back for Logon Screen Language

Command: OSDRegionalSettings.ps1 (Execution Policy set to Bypass)
Condition: Task Sequence Variable CurrentOSLanguage not equals en-US


Run Command Line: Cleanup Temporary Language Packs Store

Command: cmd.exe /c rd %_OSDDetectedWinDrive%\LanguagePacks /s /q
Condition: If folder %_OSDDetectedWinDrive%\LanguagePacks exists


Group: Rollback UILanguage

Condition: Task Sequence Variable OSDUILanguage not equals en-US


Run Command Line: Set back %OSDUILanguage% on %_OSDDetectedWinDrive%

Command: dism /image:%_OSDDetectedWinDrive% /set-uilang:%OSDUILangiuage%
Condition: (no condition set)


Lifecycle Planning

Your language packages are set, your task sequence is created–how do we keep this maintained for future Windows 10 releases?

Fortunately, the way this is architected, you’ve already completed all the hard work! When the next Windows 10 release comes around, you’ll need to:

  • Add the new language packs and features from the language pack ISO and Features on Demand ISO (automated!)
  • Add the new language packages to your task sequence

Then it’s the usual new-Windows-10-release steps (adding your upgrade package, etc.)

 

 

Now you’re automating for awesome, multi-lingually!

Jacob

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.