Second Life of a Hungarian SharePoint Geek

August 11, 2011

Getting and setting language dependent field titles using PowerShell

Filed under: MUI, PowerShell, SP 2010 — Tags: , , — Peter Holpar @ 22:43

The Multilingual User Interface (MUI) in SharePoint 2010 makes it possible to set language dependent titles and descriptions for your fields, lists, content types and web sites. The list of all affected types and properties as well as a short introduction of MUI can be read on MSDN.

As you can read there, the localization of these objects is done through the SPUserResource class and its Value property, that gets / sets the localized value based on the CurrentUICulture property of the Thread.CurrentThread object. It means that instead of calling a method with a CultureInfo parameter to get / set for example a field title, you should first set the CurrentUICulture to the CultureInfo you would like to work with:

Thread.CurrentThread.CurrentUICulture = yourCulture;

Then get / set the Title property of your SPField object as you did in WSS 3.0:

field.Title = title;

The above procedure shows it is pretty straightforward in C#, but recently I had to do something similar using PowerShell. I found it to be not trivial, and would like to share the lessons I’ve learnt.

My first approach was based on this post to simply set the CurrentUICulture as I did using C#, but it does not work for me. After setting the CurrentUICulture to German (de-DE) I tried to get its value in the next command, but it was still (or again?) English (en-US), so when I set the Title, it was set for English, not for German.

The solution for this issue can be to run the second command in the same line like this:

[Threading.Thread]::CurrentThread.CurrentCulture = $culture;[Threading.Thread]::CurrentThread.CurrentCulture

But the above format is not so nice and hard to use and read if you need to work with a lot of fields / languages.

I found the following Using-Culture function for PowerShell on  Stack Overflow:

function Using-Culture (
   [System.Globalization.CultureInfo]   $culture = (throw "USAGE: Using-Culture -Culture culture -Script {…}"),
   [ScriptBlock]
   $script = (throw "USAGE: Using-Culture -Culture culture -Script {…}"))
   {
     $OldCulture = [Threading.Thread]::CurrentThread.CurrentCulture
     $OldUICulture = [Threading.Thread]::CurrentThread.CurrentUICulture
         try {
                 [Threading.Thread]::CurrentThread.CurrentCulture = $culture
                 [Threading.Thread]::CurrentThread.CurrentUICulture = $culture
                 Invoke-Command $script
         }
         finally {
                 [Threading.Thread]::CurrentThread.CurrentCulture = $OldCulture
                 [Threading.Thread]::CurrentThread.CurrentUICulture = $OldUICulture
         }
}

Using this function, it was easy to query the field titles (in this case for all fields with English Title begins with “title”):

$web = Get-SPWeb http://SP2010
$fields = $web.Fields
$fields | Where-Object { $_.Title -like "title*" } | ForEach-Object { Using-Culture de-DE { $_.TitleResource.Value } }

Or a more compact version of the last line:

$fields | ? { $_.Title -like "title*" } | % { Using-Culture de-DE { $_.TitleResource.Value } }

My first approach to set the value for multiple fields was the next one:

$fields | ? { $_.Title -like "title*" } | % { Using-Culture de-DE { $_.TitleResource.Value = "Titel"; $_.Update("True") } }

But it resulted the following error:

An error occurred while enumerating through a collection: Collection was modified; enumeration operation may not execute..

To create a solution for this task I assembled first a new array of fields using the IDs of matching fields, then iterated through this array, set the field title and updated the field:

$fields | ? { $_.Title -like "title*" } | % { $web.Fields[$_.Id] } | % { Using-Culture de-DE { $_.TitleResource.Value = "Titel"; $_.Update("True") } }

Advertisements

3 Comments »

  1. Thanks for the post. Your code works great for me on fields that don’t already have a resource string defined in their CAML XML declaration in a feature. On the other hand, when the field is defined in a feature CAML XML your code doesn’t work. For one reason I can’t modify the feature so I’m trying to override this resource string using your technique to set the TitleResource. It appears to work when I inspect the value right after setting it and updating the field and web. But once I release the SPField instance and get it again the TitleResource is back to its original value. Any thoughts on what might be the cause of this?

    Comment by JohnC — June 6, 2012 @ 12:16

  2. You could use TitleResource.GetValueForUICulture() method for this:
    $_.TitleResource.GetValueForUICulture($web.UICulture)

    Comment by Anders Rask — July 25, 2012 @ 11:44

  3. Thanks for clear description, it was very useful for me.

    Comment by Ivan Krupsky — March 6, 2015 @ 20:09


RSS feed for comments on this post. TrackBack URI

Leave a 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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: