Set SharePoint user display-language using PowerShell

I never remember correctly how to set a SharePoint users display languages using PowerShell. Searching always brings up one or the other form of the following code:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles")
$ctx = [Microsoft.Office.Server.ServerContext]::GetContext((Get-SPWebApplication | Select -First 1))
$upm = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager -ArgumentList @($ctx)
$lang = "de-DE,en-US"
$enum = $upm.GetEnumerator()
while ($enum.MoveNext()) {
$up = $enum.Current
write-host "$($up.DisplayName) ($($up.AccountName))"
$up["SPS-MUILanguages"].Value = $lang
$up["SPS-ContentLanguages"].Value= $lang
$up.Commit()
}

This seems look good, when looked at from central admin:

user language looks good in SharePoint central admin

But for some (or all) users, when looking at the same settings from the users’ mysite. Things are not so well:

not at all good whe seen from the SharePoint mysite

The “secret” to this is that the settings from the SharePoint UserProfile are distributed (or rather copied…) by a TimerJob (“User Profile Service Application_LanguageAndRegionSync”). This TimerJob will only work on profiles where ‘SPS-RegionalSettings-Initialized‘ is set to true. Additionally that job runs every minute, if not changed by an admin.

So, the final (and working) script to deploy language settings to users looks like this:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles") | out-null
$ctx = [Microsoft.Office.Server.ServerContext]::GetContext((Get-SPWebApplication | Select -First 1))
$upm = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager -ArgumentList @($ctx)
$lang = "de-DE,en-US"
$enum = $upm.GetEnumerator()
while ($enum.MoveNext()) {
$up = $enum.Current
write-host "$($up.DisplayName) ($($up.AccountName))"
$up["SPS-MUILanguages"].Value = $lang
$up["SPS-ContentLanguages"].Value= $lang
$up["SPS-RegionalSettings-Initialized"].Value = $true
$up.Commit()
}
Get-SPTimerJob | ?{ $_.Name -like "*user*profile*languageandregion*" } | %{ $_.RunNow() }

Note lines 15 and 19 where the initialized-property is set and the TimerJob is immediately started, respectively. After running that script everything looks good:

SharePoint language settings are correctly displayed in the users mysite

What else is to say?

  • language-codes must be correctly capitalized: “en-US” works, while “en-us” does not.
  • lists of language-codes must not contain spaces: “en-GB,en-CA” works, while “en-GB, en-CA” does not.