13

Is there any PowerShell equivalent for:

Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

? Or how to set the force all stringfications to obey a culture independently from the machine configurations?

Jader Dias
  • 88,211
  • 155
  • 421
  • 625

6 Answers6

7

I think this will work:

$currentThread = [System.Threading.Thread]::CurrentThread
$culture = [System.Globalization.CultureInfo]::InvariantCulture
$currentThread.CurrentCulture = $culture
$currentThread.CurrentUICulture = $culture

This idea came from:

Link

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Jader Dias
  • 88,211
  • 155
  • 421
  • 625
7

This is the function I use for testing string/formats in other cultures:

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    
    }
}
Keith Hill
  • 194,368
  • 42
  • 353
  • 369
5

For WinServer2012 and Win8 you can use Set-Culture. As Set-Culture sets the culture for your user, you'd have to open another powershell instance to benefit from that. Also it does not change the culture of running ps instances. Of course you could start up a new powershell instance in your current instance then. This is not exactly what is asked for, but closely related.

Would be neat, if they'd port that back to Win7 and Server 2008 or make it a feature of powershell itselft.

mbx
  • 6,292
  • 6
  • 58
  • 91
  • The linked document says "Sets the user culture for the current user account." - so it seems it doesn't just set this for the current process but globally. – Sebastian Krysmanski Mar 24 '16 at 14:17
  • 1
    @SebastianKrysmanski The behaviour is in fact a bit odd. It changes the culture of the user as promised but your powershell instance keeps its culture: Open up a powershell, `Get-Culture` (gives en-US), then `Set-Culture de-DE`, using `Get-Culture` gives en-US again and a `date` formats as usual. But when you open up another powershell and `Get-Culture` it gives de-DE, `date` formats like Germans would do. – mbx Mar 24 '16 at 16:57
3

This answer deals with the current culture, which determines settings such as date format, currency, number formatting, collating sequence, ...; by contrast, the current UI culture, determines the UI language (menus, error messages, ...); All elements discussed below have UI-culture analogs (e.g., Get-UICulture vs. Get-Culture, $PSUICulture vs. $PSCulture EXCEPT Set-Culture, for which there is no analog.

Changing to a different culture:

In the .NET Framework v4.6 and higher, you can now assign to [cultureinfo]::CurrentCulture (previously, it was read-only[1]; the [cultureinfo] PS type accelerator was introduced in PSv3); e.g.:

[cultureinfo]::CurrentCulture = 'de-DE'

is equivalent to (which also works in v4.5 or lower, down to at least v2):

[System.Threading.Thread]::CurrentThread.CurrentCulture = 'de-DE'

CAVEAT: PowerShell uses the invariant culture in string-related contexts, irrespective of what the current culture is - see this answer of mine.

  • Both methods change the culture for the current PowerShell instance (thread) only.

    • Caveat [fixed in PowerShell Core as of at least v6.0.2]: As has been noted, in order to try this in an interactive PowerShell session, enter all commands on a single line, because the culture-changing effect is limited to a single command line (this still applies on PSv3+, even though consoles there run in STA mode by default); e.g., to print a German date:
      [cultureinfo]::CurrentCulture = 'de-DE'; Get-Date # must be on same line
  • For a persistent culture change for the current user, use the Set-Culture cmdlet, but, as noted in mbx's helpful answer, this change only takes effect for future PowerShell instances, NOT the current one.


Querying culture settings:

  • [cultureinfo]::CurrentCulture and [System.Threading.Thread]::CurrentThread.CurrentCulture reflect the current PowerShell instance's effective culture.

  • By contrast, the Get-Culture cmdlet (PSv3+) and the automatic $PSCulture variable (PSv3+; read-only) invariably reflect the current PowerShell instance's culture at startup time; i.e., they always reflect the current user's persistently configured culture at the time the current PowerShell instance was started (irrespective of instance-only changes via [cultureinfo]::CurrentCulture = ... or future persistent changes via Set-Culture performed in that instance).


[1] See the docs; to determine whether you have at least v4.6 installed, look for the Version: value in the output from Get-Item 'registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full'.
Note that the framework version is distinct from the CLR (runtime) version as reported by $PSVersionTable.CLRVersion; for instance, the v4.6 framework is based on the v4.0 CLR - see the docs.

mklement0
  • 382,024
  • 64
  • 607
  • 775
1

See here for details of ObjectCmdletBase.Culture Property.

Gets and sets the value of the Culture parameter of the derived cmdlet.

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
  • As I know nothing of PowerShell, could you provide a simple snippet that I could past on the first line of each script I have here so it will stringfy accordingly to the InvariantCulture? – Jader Dias Nov 05 '10 at 11:09
  • Actually there is a better method here, with examples: http://blogs.msdn.com/b/powershell/archive/2006/04/25/583235.aspx – Steve Townsend Nov 05 '10 at 11:24
1

Set-Culture works on local server but it does not work when you run it on remote computer

Invoke-Command -ComputerName $server -ScriptBlock{
            #Requires -RunAsAdministrator
            Set-Culture -CultureInfo en-GB; 
            Set-TimeZone -Id "GMT Standard Time" 
        }
Julian
  • 886
  • 10
  • 21
Ignore
  • 41
  • 5
  • This is what happens in remote server: {Get-UICulture - ui culture does not change}, {Get-Culture - current culture changes}. However it works fine when you run set-culture on local computer without the scriptblock. set-culture changes the ui culture too. – Ignore Jan 22 '19 at 13:43