Sunday, March 23, 2008 11:28 AM bart

Windows PowerShell 2.0 Feature Focus - Script Internationalization

Two weeks ago I did a little tour through Europe spreading the word on a couple of our technologies including Windows PowerShell 2.0. In this blog series I'll dive into a few features of Windows PowerShell 2.0. Keep in mind though it's still very early and things might change towards RTW - all samples presented in this series are based on the CTP which is available over here.

 

Introduction

Imagine you're working for a company that operators in different countries or regions with different languages. Or you're creating a product that will be used by customers around the globe. Hard-coding messages in one language isn't likely going to be the way forward in such a case. Unfortunately with the first release of Windows PowerShell copy-paste localization of scripts was all too common. In this post we'll take a look at the Windows PowerShell 2.0 Script Internationalization feature.

 

String tables

In order to allow for localization, string tables are used quite often. The idea of a string table is to have key-value pairs that contain the (to-be) localized strings in order to separate the logic from the real string messages. Windows PowerShell 2.0 has this new cmdlet called ConvertFrom-StringData which is described as: "Converts a string containing one or more "name=value" pairs to a hash table (associative array)." If you read a little further in the get-help output you'll see the following:

The ConvertFrom-StringData cmdlet is considered to be a safe cmdlet that can be used in the DATA section of a script or function. When used in a DATA section, the contents of the string must conform to the rules for a DATA section. For details, see about_data_section.

Data sections are new to Windows PowerShell 2.0 and deserve a post on their own. For the purpose of this post, it suffices to say that a data section is a section used in script that can only contain data-operations and therefore it only supports a subset of the PowerShell language.

Let's use ConvertFrom-StringData on its own for now:

image

In here I'm using a so-called "here-string" that spans multiple lines, each line containing a key = value pair.

 

Localizable scripts

Time to put the pieces together and create a localizable script:

Data msgTable
{
ConvertFrom-StringData @'
    helloWorld = Hello, World :-).
    errorMsg = Something went horribly wrong :-(.
'@
}

Write-Host $msgTable.helloWorld
Throw $msgTable.errorMsg

Here's the result:

image

In the fragment above, notice the use of the Data keyword to denote a data section. In the remainder of the script, $msgTable is used as the variable to denote the hash table created by the ConvertFrom-StringData invocation in the data section.

 

Localized string tables

We already achieved some decoupling between the code and the messages, simply by putting the messages in a separate table. Now we have to blend in the actual culture of the system, which is exposed as $UICulture now:

image

We don't need to use this variable directly though. Using the new Import-LocalizedData cmdlet we can make PowerShell search for the right string table by investigating the directory structure. The idea is to have .psd1 files (a new extension) that contain localized string tables in subdirectories that denote the culture specified by language code and region code:

C:\temp\PS2\I18N\demo.ps1
C:\temp\PS2\I18N\nl-BE\demo.psd1
C:\temp\PS2\I18N\fr-FR\demo.psd1

Let's create the nl-BE\demo.psd1 file:

ConvertFrom-StringData @'
    helloWorld = Hallo, Wereld!
    errorMsg = Oeps! Dit ging vreselijk fout.
'@

Just copy the contents of the data section to a separate .psd1 file and translate it. Such files are "data files" (hence the d in the name) and substitute the contents of a data section. This doesn't happen magically of course, we need to call Import-LocalizedData in our script:

Data msgTable
{
ConvertFrom-StringData @'
    helloWorld = Hello, World :-).
    errorMsg = Something went horribly wrong :-(.
'@
}

Import-LocalizedData -bindingVariable msgTable

Write-Host $msgTable.helloWorld
Throw $msgTable.errorMsg

Import-LocalizedData extracts the $UICulture and tries to find the right .psd1 file. When found, the contents of the file are assigned to the binding variable which points at a data section.

Now when we run on an nl-BE machine, we'll see the following:

image

Enjoy!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Filed under:

Comments

# Windows PowerShell 2.0 Feature Focus - Script Debugging

Wednesday, March 26, 2008 10:18 PM by B# .NET Blog

Two weeks ago I did a little tour through Europe spreading the word on a couple of our technologies including