Servicing Windows 10 when Multiple Languages are Installed

I do not remember why, but 2 years ago when I started the journey to upgrade our devices to Windows 10, I decided to use the offline method to install language packs. At the time it seemed like a good idea and was simple enough. With a little MDT magic, I was able to deploy Windows 10 in different languages using only the English (United States) ISO downloaded from MVLS site. Fast forward a year to the first servicing update. Suddenly you cannot run servicing on the non English (United States) machines. When you run the Config Manager “Upgrade Operating System” step pointing to the English (United States) source files it fails on “0xC1900204” which translates to “Migration choice (auto upgrade) not available (probably the wrong SKU or architecture)·” It appears using the offline injection of the language pack changes the product SKU. This left me with 2 choices, either I needed to download each of the languages ISO files from MVLS and import them into Config Manager, or I needed to use the work around listed in such posts as MS Blog post on “How to upgrade windows clients with multiple languages installed to windows 10”.

For the first round of servicing, I decided to use the steps outlines in the MS Blog. This way I would save space on my distribution points. By the way, this blog post has been disabled now. It appeared to work, I did not need to download 18 different ISO’s, but there were a few issues with it. The reboot that for the upgrade occurred sooner, this was due to the computer needing to boot to WinPE to reset the setup UI language back to English (United States). When performing this step, the user logon screen was disabled so the user would not log back in. If the upgrade failed, the user was left with no method to log back in. They then called into the Service Desk saying they could not logon. Maybe I just did not have my error exception steps correct, but either way it caused calls to the Service Desk, which is never a good thing.  Then when at MMS Desert Edition, I was talking to some of the great people from Microsoft about how best to handle this situation. They informed me that the method of changing the system UI in WinPE was not supported by the operating system team. Between this statement and the issues, we had seen with the first round of servicing, I decided to try the first approach of having different upgrade images for each language.

I started my new journey with downloading the ISO’s needed for the languages supported by my company. The first issue I had was there was no download for Portuguese Brazil in MVLS. There was Portuguese Portugal, but no specific ISO for Brazil. I figured I would deal with that later (and I did). Now that I had my 16 ISO’s downloaded, I needed to prepare them for Config Manager. After reading several blogs on dynamic updates and how important it is to have the latest updates and servicing stacks injected into the upgrade image, I used David Segura’s OSD Builder to inject these in each ISO.  I imported the OSMedia into Config Manager and was ready to test.

The upgrade worked great, with a better user experience, however, English was no longer installed on the computer. Where before both German and English would be installed, now only German was installed. This was nothing that could not be fixed. I just needed to add the English United States language packs to the upgrade images. Below are the steps I followed, there are different methods to accomplish this, but this is what I did.

  • Mounted each of the ISO’s
  • Opened PowerShell and ran
  • Get-OSBuilder -CreatePaths -SetPath e:\OSBuilder -Update
  • This imported the ISO’s into the OSDBuilder “OSMedia” folder.
  • Downloaded the Windows 10 1809 Feature on Demand and language pack ISO’s from MVLS.
  • Created a folder and copied the English United States files there.
  • Ran the following PowerShell Script
    $Languages = @("nb-no","nl-nl","es-es")
    ForEach($Lang in $Languages)
    {
         $LogFilePath = "E:\OSBuilder\OSMedia\Windows 10 Enterprise x64 1809 17763.107 $lang"
         $WimPath ="$LogFilePath\OS\sources\install.wim"
         $MountDir = 'E:\Mount'
         #Add English - US to WIM
         Get-WindowsImage -ImagePath $WimPath -Index 1 |Select *
         Mount-WindowsImage -Path $MountDir -ImagePath $WimPath -Index 1
         Add-WindowsPackage -PackagePath "E:\1809_LP\English-en-us\Microsoft-Windows-Client-Language-Pack_x64_en-us.cab" -Path $MountDir
         Add-WindowsPackage -PackagePath "E:\1809_LP\English-en-us\Microsoft-Windows-LanguageFeatures-Basic-en-us-Package.cab" -Path $MountDir
         Add-WindowsPackage -PackagePath "E:\1809_LP\English-en-us\Microsoft-Windows-LanguageFeatures-Fonts-PanEuropeanSupplementalFonts-Package.cab" -Path $MountDir
         Add-WindowsPackage -PackagePath "E:\1809_LP\English-en-us\Microsoft-Windows-LanguageFeatures-Handwriting-en-us-Package.cab" -Path $MountDir
         Add-WindowsPackage -PackagePath "E:\1809_LP\English-en-us\Microsoft-Windows-LanguageFeatures-OCR-en-us-Package.cab" -Path $MountDir
         Add-WindowsPackage -PackagePath "E:\1809_LP\English-en-us\Microsoft-Windows-LanguageFeatures-Speech-en-us-Package.cab" -Path $MountDir
         Add-WindowsPackage -PackagePath "E:\1809_LP\English-en-us\Microsoft-Windows-LanguageFeatures-TextToSpeech-en-us-Package.cab" -Path $MountDir
         Get-WindowsOptionalFeature -Path $MountDir >"$LogFilePath\WindowsOptionalFeature.txt"
         Get-WindowsCapability -Path $MountDir >"$LogFilePath\WindowsCapability.txt"
         Get-WindowsPackage -Path $MountDir >"$LogFilePath\WindowsPackage.txt"
         Dismount-WindowsImage -Path "$MountDir" -Save
         Get-WindowsImage -ImagePath $WimPath -Index 1 |select * >"$LogFilePath\WindowsImage.txt"
    }
  • I then updated the OSMedia with OSD Builder PowerShell command Update-OSMedia.
  • When prompted, I selected each of the OSMedia files I updated.  This updated the media with all the newest servicing stack updates and quality updates.
  • I imported each of these media files into Config Mgr. The downside to this was each language is about 5 GB of data and with the 17 languages (including en-US) it took 80 GB on the distribution points.  (The Portuguese Brazil was not imported yet.)

But what about Portuguese Brazil? This turned out to be easily accomplished. I made a copy of the English United States, OS Media folder and performed the following steps:

  • Copied the language pack file and feature on demand files to the “E:\1809_LP\Portuguese (Brazil)-pt-br” folder.
  • Copied the script used above replacing “English – en-us” with “Portuguese (Brazil)-pt-br” and “en-US” with “pt-br”. I also commented out the step where I dismount the WIM.
  • I do not know if all these commands were necessary, but they are quick and could not hurt anything:
    dism.exe /image:e:\mount /set-UILang:pt-br
    dism.exe /image:e:\mount /set-SysLocale:pt-br
    dism.exe /image:e:\mount /set-UserLocale:pt-br
    dism.exe /image:e:\mount /set-InputLocale:"0416:00000416"
    dism.exe /image:e:\mount /set-AllIntl:pt-BR
    dism.exe /image:e:\mount /set-TimeZone:"E. South America Standard Time"
    dism.exe /image:e:\mount /set-SkuIntlDefaults:pt-BR
    dism.exe /image:e:\mount /gen-LangINI:E:\OSBuilder\OSMedia\Windows 10 Enterprise x64 1809 17763.107 en-US pt-BR\OS
    
  • Edited the Lang.ini file that was created. I removed the en-US line and changed the pt-BR line to be “pt-BR = 3”
  • Ran: dism.exe /image:e:\mount /set-SetupUILang:E:\OSBuilder\OSMedia\Windows 10 Enterprise x64 1809 17763.107 en-US pt-BR\OS
  • I then ran the dism.exe /unmount-wim /mountdir:e:\mount /commit
  • These new OSMedia files were then imported into Config Manager.

The final step was to change the task sequence to know which upgrade image to use. To do this, I included a “Run PowerShell Script” step in the task sequence to run the following script. This script returned the install OS language along with some other variables:

function Write-log($string, $color)
{
if ($Color -eq $null) {$color = "white"}
     write-host $string -foregroundcolor $color
     $string | out-file -Filepath $logfile -append
}
#region setupLogging
$ScriptName=(($MyInvocation.MyCommand.Name).Split("."))[0]
$tsenv = New-Object -ComObject Microsoft.SMS.TSEnvironment -ErrorAction SilentlyContinue
If($tsenv)
{
     $LogFilePath=$tsenv.value('_SMSTSLogPath')
}else
{
     $LogFilePath= 'c:\windows\temp'
}
$logfile= "$LogFilePath\$($ScriptName)_$(get-date -format `"yyyyMMdd_hhmmsstt`").log"
#endregion

$InstallLanguages = Get-WmiObject win32_operatingsystem|select MUILanguages
If($InstallLanguages.MUILanguages.Count -gt 1)
{
     $OSLang = $InstallLanguages.MUILanguages[0]
     $AddLP1 = $InstallLanguages.MUILanguages[1]
     If($InstallLanguages.MUILanguages[2])
     {
          $AddLP2 = $InstallLanguages.MUILanguages[2]
     }
     If($AddLP1 -eq 'en-US') #US is in image not needed here
     {
          If($AddLP2)
          {
               $AddLP1 = $AddLP2
               Remove-Variable AddLP2
          }
          Else {Remove-Variable AddLP1}
     }
}
If($tsenv)
{
     If($AddLP1){$tsenv.value("AddLP1") = $AddLP1}
     If($AddLP2){$tsenv.value("AddLP2") = $AddLP1}
     If($OSLang){$tsenv.value("OSLang") = $OSLang}
}

Write-log "MUILanguages: $($InstallLanguages.MUILanguages)"
Write-LOG "OSLang: $OSLang"
Write-LOG "AddLP1: $AddLP1"
Write<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>-LOG "AddLP2: $AddLP2"

I placed a condition on each of the “Upgrade Operating System”, that OSLang task sequence variable equal the language:

https://configgirl.files.wordpress.com/2019/03/032319_2225_servicingwi3.png

And that was it. I the Windows Servicing Task Sequence was usable for all languages we supported.

2 thoughts on “Servicing Windows 10 when Multiple Languages are Installed

Leave a Reply to Julie Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s