24/7/365 Support

Write Culture-Aware Scripts in PowerShell

Problem

You want to ensure that your script works well on computers from around the world.

Solution

To write cultureaware scripts, keep the following guidelines in mind as you develop your scripts:

  • Create dates, times, and numbers using PowerShell’s language primitives.
  • Compare strings using PowerShell’s builtin operators.
  • Avoid treating user input as a collection of characters.
  • Use Parse() methods to convert user input to dates, times, and numbers.

Discussion

Writing cultureaware programs has long been isolated to the world of professional software developers. It’s not that users of simple programs and scripts can’t benefit from culture awareness though. It has just frequently been too difficult for nonprofessional programmers to follow the best practices. PowerShell makes this much easier than traditional programming languages however.

As your script travels between different cultures, several things change.

Date, time, and number formats

Most cultures have unique date, time, and number formats. To ensure that your script works in all cultures, PowerShell first ensures that its language primitives remain consistent no matter where your script runs. Even if your script runs on a machine in France (which uses a comma for its decimal separator), you can always rely on the statement $myDouble = 3.5 to create a number halfway between three and four. Likewise, you can always count on the statement $christmas = [DateTime] "12/ 25/2007" to create a date that represents Christmas in 2007—even in cultures that write dates in the order of day, month, year.

Culturally aware programs always display dates, times, and numbers using the preferences of that culture. This doesn’t break scripts as they travel between cultures and is an important aspect of writing cultureaware scripts. PowerShell handles this for you, as it uses the current culture’s preferences whenever it displays data.

If your script asks the user for a date, time, or number, make sure that you respect the format of the user’s culture’s when you do so. To convert user input to a specific type of data, use that type’s Parse() method.

$userInput = ReadHost "Please enter a date" $enteredDate = [DateTime]::Parse($userInput)

So, to ensure that your script remains cultureaware with respect to dates, times, and number formats, simply use PowerShell’s language primitives when you define them in your script. When you read them from the user, use Parse() methods when you convert them from strings.

Complexity of user input and file content

English is a rare language in that its alphabet is so simple. This leads to all kinds of programming tricks that treat user input and file content as arrays of bytes or simple plaintext (ASCII) characters. In most international languages, these tricks fail. In fact, many international symbols take up two characters’ worth of data in the string that contains them.

PowerShell uses the standard Unicode format for all stringbased operations: reading input from the user, displaying output to the user, sending data through the pipeline, and working with files.

Although PowerShell fully supports Unicode, the powershell.exe commandline host does not output some characters correctly, due to limitations in the Windows console system. Graphical PowerShell hosts

(such as the several thirdparty PowerShell IDEs) are not affected by these limitations however.

If you use PowerShell’s standard features when working with user input, you do not have to worry about its complexity. If you want to work with individual characters or words in the input, though, you will need to take special precautions. The System. Globalization.StringInfo class lets you do this in a culturally aware way. For more information about working with the StringInfo class, see http://msdn2.microsoft. com/enus/library/7h9tk6x8(vs.71).aspx.

So, to ensure that your script remains culturally aware with respect to user input, simply use PowerShell’s support for string operations whenever possible.

Capitalization rules

Acommon requirement in scripts is to compare user input against some predefined text (such as a menu selection). You normally want this comparison to be case insensitive, so that “QUIT” and “qUiT” mean the same thing.

The most common way to accomplish this is to convert the user input to uppercase or lowercase:

## $text comes from the user, and contains the value "quit" if($text.ToUpper() eq "QUIT") { ... }

Unfortunately, explicitly changing the capitalization of strings fails in subtle ways when run in different cultures, as many cultures have different capitalization and comparison rules. For example, the Turkish language includes two types of the letter “I”: one with a dot, and one without. The uppercase version of the lowercase letter “i” corresponds to the version of the capital “I” with a dot, not the capital “I” used in QUIT. That example causes the above string comparison to fail on a Turkish system.

To compare some input against a hardcoded string in a caseinsensitive manner, the better solution is to use PowerShell’s –eq operator without changing any of the casing yourself. The –eq operator is caseinsensitive and cultureneutral by default:

PS >$text1 = "Hello" PS >$text2 = "HELLO" PS >$text1 –eq $text2 True

So, to ensure that your script remains culturally aware with respect to capitalization rules, simply use PowerShell’s caseinsensitive comparison operators whenever possible.

Sorting rules

Sorting rules frequently change between cultures.

PS >UseCulture enUS { "Apple","Æble" | SortObject } Æble Apple PS >UseCulture daDK { "Apple","Æble" | SortObject } Apple Æble

To ensure that your script remains culturally aware with respect to sorting rules, assume that output is sorted correctly after you sort it—but don’t depend on the actual order of sorted output.

Other guidelines

For other resources on these factors for writing culturally aware programs, see http:// msdn2.microsoft.com/enus/library/h6270d0z(vs.71).aspx and http://www.microsoft. com/globaldev/getwr/steps/wrguide.mspx .

Help Category:

Get Windows Dedicated Server

Only reading will not help you, you have to practice it! So get it now.

Processor RAM Storage Server Detail
Intel Atom C2350 1.7 GHz 2c/2t 4 GB DDR3 1× 1 TB (HDD SATA) Configure Server
Intel Atom C2350 1.7 GHz 2c/2t 4 GB DDR3 1× 128 GB (SSD SATA) Configure Server
Intel Atom C2750 2.4 GHz 8c/8t 8 GB DDR3 1× 1 TB (HDD SATA) Configure Server
Intel Xeon E3-1230 v2 3.3 GHz 4c/8t 16 GB DDR3 1× 256 GB (SSD SATA) Configure Server
Intel Atom C2350 1.7 GHz 2c/2t 4 GB DDR3 1× 250 GB (SSD SATA) Configure Server

What Our Clients Say