Using-Culture -Culture culture -Script {scriptblock}

Using-Culture -Culture culture -Script {scriptblock}

Rate This
  • Comments 6

One of the traditional challenges with scripting is dealing with different CULTURES.  Imagine the case where you are writing a script and you'll have to parse datetime string from different cultures.  If it was just one culture, you could set the process culture and be done with it.  Here is a function that allows you to run a portion of a script in a different culture:

Function Using-Culture (
[System.Globalization.CultureInfo]$culture = (throw "USAGE: Using-Culture -Culture culture -Script {scriptblock}"),
[ScriptBlock]$script= (throw "USAGE: Using-Culture -Culture culture -Script {scriptblock}"))
{
    $OldCulture = [System.Threading.Thread]::CurrentThread.CurrentCulture
   
trap 
    {
        [System.Threading.Thread]::CurrentThread.CurrentCulture = $OldCulture
    }

    [System.Threading.Thread]::CurrentThread.CurrentCulture = $culture
    Invoke-Command $script
    [System.Threading.Thread]::CurrentThread.CurrentCulture = $OldCulture
}

Here is an example of it working:


[332:]MSH> using-culture ar-IQ {get-date}

30 تشرين الثاني, 2005 09:01:38 ص


[332:]MSH> using-culture ar-IQ {$global:d=[DateTIme]::Parse("30 تشرين الثاني, 2005 09:01:38 ص")}
[332:]MSH> $d

Wednesday, November 30, 2005 9:01:38 AM


[332:]MSH> using-culture de-de {get-date}

Mittwoch, 30. November 2005 09:02:29
[332:]MSH> using-culture de-de {$global:d=[DateTIme]::Parse("Mittwoch, 30. November 2005 09:02:29")}
[332:]MSH> $d

Wednesday, November 30, 2005 9:02:29 AM

 

The great thing about this approach is that you can put any code you want into the script block.  It can be a single cmd, a pipeline or a full script.

Enjoy!

Jeffrey P. Snover [MSFT]

[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]

Leave a Comment
  • Please add 8 and 5 and type the answer here:
  • Post
  • I received an error saying : Invoke-Command not a cmdlet, function,...

    In fact, it must be replaced by :

    $ExecutionContext.InvokeCommand.InvokeScript(@script)

  • Hello,

    thanks for this post. Very helpful.

    Actually there is a problem. This works as long as you are calling PS command. Yet if you create a new COM based applicatoin (e.g. =New-Object -ComObject Excel.Application) this does not work. The new COM object will create it's own thread(s) and that thread(s) will use the default culture - not the one of the PS thread.

    Any idea how to get around this?

    This is important as there is a bug in Office

    http://support.microsoft.com/default.aspx?scid=kb;en-us;320369

    I run a Vista Ultimate in German (i must be fool to run something in German) but my Office is English -> automation of Office from withing PS does not work.

  • PingBack from http://www.keyongtech.com/2831682-how-do-i-explicitly-set

  • PingBack from http://www.keyongtech.com/2834166-ctp-culture-and-office-still

  • I tried the function in the following context

    Function Using-Culture (

    [System.Globalization.CultureInfo]$culture = (throw "USAGE: Using-Culture -Culture culture -Script {scriptblock}"),

    [ScriptBlock]$script= (throw "USAGE: Using-Culture -Culture culture -Script {scriptblock}")

    ) {

    $OldCulture = [System.Threading.Thread]::CurrentThread.CurrentCulture

    trap

    {

    [System.Threading.Thread]::CurrentThread.CurrentCulture = $OldCulture

    }

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

    Invoke-expression "$script"

    [System.Threading.Thread]::CurrentThread.CurrentCulture = $OldCulture

    }

    Get-Date

    Using-Culture -Culture 'en-US' -Script {

    Get-Date

    $file = "C:\VMware\Projects\MTS\VirtProject\DRSRules\AntiAffinity.xlsx"

    $excel = New-Object -comobject Excel.Application

    $excel.Visible = $true

    $workbooks = $excel.Workbooks.Open( $file )

    $worksheets = $workbooks.Worksheets

    $worksheet = $worksheets.Item(1)

    $range = $worksheet.UsedRange

    foreach($row in $range.Rows) {

    foreach($col in $row.Columns) {

    echo $col.Text

    }

    }

    }

    and here is what I got:

    Dienstag, 12. Mai 2009 17:12:43

    Tuesday, May 12, 2009 5:12:43 PM

    Exception calling "Open" with "1" argument(s): "Old format or invalid type library. (Exception from HRESULT: 0x80028018 (TYPE_E_INVDATAREAD))"

    At :line:4 char:35

    + [ScriptBlock]$script= (throw "USAG <<<< E: Using-Culture -Culture culture -Script {scriptblock}")

    Any idea, why the culture is accepted by the get date, but not by the MS excel?

  • hello :)

    pls how i have to do for "recalcul" the excel sheet ?

    my best regard

    arnold

Page 1 of 1 (6 items)