30

I need to run some PowerShell scripts across various operating systems. Most of them are in English version, however, some are localized for example German, French, Spanish, etc. The problem is local system administrators mostly do not now PowerShell and in the case the script fails and throws an error at them, instead of reading it they just send screenshots of such error messages to me and if the cause to this error is not obvious I am stuck with typing it to g. translate to find out what is going on.

Is there a switch I can run the whole script or single command with or a parameter or any other way to force errors in PowerShell to be displayed in English instead of the language that is default for that particular machine?

streamofstars
  • 705
  • 1
  • 10
  • 14

2 Answers2

23

You can change the pipeline thread's CurrrentUICulture like so:

[Threading.Thread]::CurrentThread.CurrentUICulture = 'fr-FR'; Get-Help Get-Process

I'm on an English system but before I executed the line above, I updated help like so:

Update-Help -UICulture fr-FR

With that, the Get-Help call above gave me French help on my English system. Note: if I put the call to Get-Help on a new line, it doesn't work. Confirmed that PowerShell resets the CurrentUICulture before the start of each pipeline which is why it works when the commands are in the same pipeline.

In your case, you would need to have folks install English help using:

Update-Help -UICulture en-US

And then execute your script like so:

[Threading.Thread]::CurrentThread.CurrentUICulture = 'en-US'; .\myscript.ps1
Keith Hill
  • 194,368
  • 42
  • 353
  • 369
  • 1
    `$ENUS="[Threading.Thread]::CurrentThread.CurrentUICulture = 'en-US'"` then `invoke-expression $ENUS; Get-Help Get-Process` _"invoke-expression $ENUS;"_ is little shorter if you need to run many commands. – anton_rh Apr 28 '17 at 15:55
  • 1
    Don't forget to run PowerShell with elevated privileges in order to execute `Update-Help`. – Alexandre Jun 04 '20 at 22:43
  • @anton_rh … or you can put the culture change command in %HOMEDRIVE%%HOMEPATH%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 to make the culture change permanent for all PS executions. – Alexandre Jun 04 '20 at 22:54
9

[Threading.Thread]::CurrentThread.CurrentUICulture only affects to current one-liner, so you can use it for execution of single .ps1 file.

If you want to change messages to English throughout every command in a PowerShell window, you have to change the culture setting cached in PowerShell runtime with reflection like this:

# example: Set-PowerShellUICulture -Name "en-US"

function Set-PowerShellUICulture {
    param([Parameter(Mandatory=$true)]
          [string]$Name)

    process {
        $culture = [System.Globalization.CultureInfo]::CreateSpecificCulture($Name)

        $assembly = [System.Reflection.Assembly]::Load("System.Management.Automation")
        $type = $assembly.GetType("Microsoft.PowerShell.NativeCultureResolver")
        $field = $type.GetField("m_uiCulture", [Reflection.BindingFlags]::NonPublic -bor [Reflection.BindingFlags]::Static)
        $field.SetValue($null, $culture)
    }
}

(from https://gist.github.com/sunnyone/7486486)

SATO Yusuke
  • 1,600
  • 15
  • 39
  • 1
    Nice workaround; fortunately, it is no longer needed in PowerShell [Core] v6+. To change the `CurrentCulture` (number, currency, date formats) rather than the `CurrentUICulture`, modify the non-public `m_Culture` field instead: (While modifying non-public fields via reflection is generally ill-advised, it should be fine in this case, given that Windows PowerShell (versions up to v5.1) will see no new development.) – mklement0 Jul 26 '20 at 15:05
  • 2
    (Despite the formatting, this function works.) `function Set-PowerShellCulture { param([Parameter(Mandatory)] [cultureinfo] $culture) [System.Reflection.Assembly]::Load('System.Management.Automation'). GetType('Microsoft.PowerShell.NativeCultureResolver'). GetField('m_Culture', 'NonPublic, Static'). SetValue($null, $culture) } ` – mklement0 Jul 26 '20 at 15:05
  • Another thing worth noting: Windows PowerShell _statically_ initializes `$PSUICulture` and `$PSCulture` and therefore these variables do _not_ reflect the effective culture set by these workarounds; however, `Get-UICulture` / `Get-Culture` as well as `[cultureinfo]::CurrentUICulture` / `[cultureinfo]::CurrentCulture` do. – mklement0 Jul 27 '20 at 16:43