Halloween is upon is, trick or treat? In today’s blog, I’m going spoil you rotten in a spooktacular way by giving you a trick and a treat.

The trick? How to retain your System Language setting when running an in-place upgrade of Windows 10. The treat? The satisfaction of implementing it in no time – mmmmmwwwwahahahahahaha!

If you joined us at our recent webinar, Windows as a Service for Smarties, we were asked how to upgrade devices if the display language, or UILanguage as it’s known, has been changed from the original media.

When changing the UILanguage of a Windows 10 install, the operating system is then running as that language. If upgrade media is run, it expects the media for that language. If dealing with multiple regions in your environment the last thing you want to do is point the upgrades at each individual language-based media to get them from baseline to baseline.

So, we must implement our trick and here’s how.

Spellbinding Step One

The first step is to capture the information on the existing device. We need to know the current UILanguage of the device.

This can be easily achieved by querying the culture of the operating system with the Get-Culture PowerShell command and then storing this as a Task Sequence variable.

If we run the Get-Culture command, we get the following information back.

Therefore, a quick script can store this as a Task Sequence variable.

$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$CurrentLanguage = (Get-Culture).Name
$tsenv.Value("OSDLanguage") = $CurrentLanguage 

The script itself should be run in the early stages of the in-place upgrade Task Sequence before the device is restarted into WinPE. You can use a Run PowerShell Script step to execute the code.

Petrified Part Two

The next step is to revert the language of the device being built back to the original media language. Say, for example, that you originally used theen-USmedia for deployment and layered on the UILanguage during the original build process. You will need to revert the UILanguage back to the same as the media.

DISM helps us out with this one. A Run Command Line step is required, followed by a Restart Computer, and this needs to be run prior to the Upgrade Operating System step. The command to use would be:

dism /image:%_OSDDetectedWinDrive% /set-uilang:en-US

Now, when the Upgrade Operating System step runs, it will accept the en-US media as valid and upgrade the device.

Creepy Conclusion

With the device now running as en-US, you’ll need to apply your language interface packs again. Since you have the original UILanguage set as a Task Sequence variable called OSDLanguage, if you used the code provided, you can set this to install the language pack based on a condition being True.

Finally, you’ll need to add the magic potion. This is a script to use the captured UILanguage. We set as OSDLanguage, and store it in an XML file. The file can then be applied during the upgrade build to set the operating system back with the system language we were using before our upgrade began. What ghoulish fun!

To do this we are using a modified version of a script written for the community by Nicolas Lacour, and then modified by Dan Padgett. My version strips the code down to its basics.

It takes the OSDLanguage variable and writes the value back into an XML file called UISettings.xml which is written into the C:\Windows\Temp folder. Note that the OSDLanguage value will be written into the settings for UILanguage, UserLocale and SystemLocale.

The code below needs to be saved into a PowerShell script and executed from a Run PowerShell Script step.

$TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$srcXML = @"
<gs:GlobalizationServices xmlns:gs="urn:longhornGlobalizationUnattend">

<!-- user list -->
    <gs:User UserID="Current" CopySettingsToDefaultUserAcct="true" CopySettingsToSystemAcct="true"/>

<!-- MUI preferences --> 
    <gs:MUILanguage Value="%UIID%"/>
    <gs:MUIFallback Value="en-US"/>

<!--User Locale-->
    <gs:Locale Name="%UserLocale%" SetAsCurrent="true" ResetAllSettings="false"/>

<!-- system locale -->
  <gs:SystemLocale Name="%SystemLocale%"/>

$destXML = "C:\Windows\Temp\UISettings.xml"

$VarNameLng = '%UIID%'
$lng = $TSEnv.Value("$OSDLanguage")

$VarNameUserLocale = '%UserLocale%'
$UserLocale = $TSEnv.Value("$OSDLanguage")

$VarNameSystemLocale = '%SystemLocale%'
$SystemLocale = $TSEnv.Value("$OSDLanguage")

$content = $srcXML -replace $VarNamelng, $lng
$content = $content -replace $VarNameUserLocale, $UserLocale
$content = $content -replace $VarNameSystemLocale, $SystemLocale

Out-File $destXML -InputObject $content

Next, use a Run Command Line step with the command line:

rundll32.exe shell32,Control_RunDLL intl.cpl,,/f:”C:\Windows\Temp\UISettings.xml.” This will set the language back to what it was prior to upgrade, initiate a Restart Computer step back into the current operating system for the changes to take effect.

I hope this helps you with dealing with the fiendishly frightening prospect of upgrading your multi-regional Windows 10 devices when the display language has been changed as part of the original build.

Happy Halloween all!