During my tinkering with PS 5.1 under Win 10, related to the objective of question Fully change language (including Culture) for the current PowerShell session, I came across a couple of related questions.
Where is the Windows setting associated with the UICulture? I did not find the "Keyboard and Languages" tab of the "Region and Language" control panel as indicated here.
Can this be persistently changed from within PS? All I found so far only persist in a session.
The setting Settings -> Time and Language -> Language -> Windows display language shows "Español (España)", and PS gives
> Get-UICulture ; [System.Threading.Thread]::CurrentThread.CurrentUICulture ; [CultureInfo]::CurrentUICulture ;
LCID Name DisplayName
---- ---- -----------
1033 en-US English (United States)
1033 en-US English (United States)
1033 en-US English (United States)
without any intervening changes and in a session just launched.
In .NET, cultures (System.Globalization.CultureInfo
) are used to control two related, but independent aspects of (human) culture-specific for-display representations:
The effective UI culture, reflected in [cultureinfo]::CurrentUICulture
, controls the (human) language that should be used for UI elements and end-user messages, such as error messages.
On Windows, its value is inherited from the so-called Windows display language, which is a persistent, user-specific setting that you can modify as described below.
In PowerShell, you can also query the effective UI culture via the automatic $PSUICulture
variable (reports the culture name only) or the Get-UICulture
cmdlet (reports a [cultureinfo]
instance).
Caveat: In Windows PowerShell, the value reported is the one that was in effect at session start-up time (which was the then-current persisted value), so any in-session changes are not reflected. This problem has been corrected in PowerShell (Core) 7.
The effective culture, reflected in [cultureinfo]::CurrentCulture
, controls the formats used to represent numbers, currency values, and date/time values.
On Windows, its value is inherited from the active locale, a.k.a. regional format, which are persistent, user-specific settings that you can modify as described below.
In PowerShell, you can also query the effective UI culture via the automatic $PSCulture
variable (reports the culture name only) Get-Culture
cmdlet (reports a [cultureinfo]
instance).
Caveat: In Windows PowerShell, the value reported is the one that was in effect at session start-up time, so any in-session changes are not reflected. This problem has been corrected in PowerShell [Core] v6+.
UI culture, a.k.a Windows display language:
On Windows 10, open the Settings application (e.g., via Start Menu), go to category Time & Language
, then click on Language
in the sidebar on the left.
Shortcuts:
Open the Settings app quickly:
start ms-settings:
(works from cmd
too).In Start Menu, simply type "Language" and select Language Settings
from the result - this takes you directly to the relevant page in the Settings app.
Run intl.cpl
to open the legacy Region
Control Panel applet and click on the Language preferences
link, which takes you to the relevant page in the Settings app.
Culture, a.k.a Regional format (locale):
On Windows 10, open the Settings application (e.g., via Start Menu), go to category Time & Language
, then click on Region
in the sidebar on the left, then select the desired culture under Regional format
(the Region
setting at the top does not control the culture).
Shortcuts:
In Start Menu, simply type "Regional format" and select Set regional format
from the result - this takes you directly to the relevant page in the Settings app.
Run intl.cpl
to open the legacy Region
Control Panel applet and select the desired culture from the Format:
drop-down list.
Note:
These settings apply to .NET and non-.NET applications equally, assuming these applications are designed to respect the user's regional formats (locale, culture) and display language (UI culture) and come with language-specific resources.
By contrast, making in-session-only changes via [cultureinfo]::CurrentUICulture
/ [cultureinfo]::CurrentCulture
(see below) applies to .NET applications only.
Persistent, current-user changes (equivalents of the GUI methods):
UI culture, a.k.a Windows display language:
There is no cmdlet, but in Windows 8 / Windows Server 2012 R2 and above you can use the
Set-UICulture
Set-WinUILanguageOverride
cmdlet.
Note that the language pack for the language associated with the targeted culture must either come with the system or must have been downloaded previously.
Important: The change doesn't take effect until you either log off and back on or reboot.
Culture, a.k.a Regional format (locale):
Use the Set-Culture
cmdlet, available in Windows 8 / Windows Server 2012 R2 and above.
Important: The change only takes effect in future PowerShell sessions, but no logoff / reboot is required.
In-session-only changes:
Important: Such changes are apply only to .NET-based applications. Therefore, calling a non-.NET console application from a PowerShell session in which culture was changed will have no impact on that console application. However, the change does take effect for calls to PowerShell cmdlets, scripts and functions. Even though the scope of the change is technically limited to the current thread, PowerShell also propagates the change to code executed in new threads (Start-ThreadJob
and ForEach-Object -Parallel
) as well as code executed on remote machines, via PowerShell remoting (e.g., Invoke-Command
). Curiously, however, as of PowerShell 7.0, background jobs (Start-Job
), which run in child processes, do not inherit the calling thread's culture - see this GitHub issue.
You can assign to [cultureinfo]::CurrentUICulture
/ [cultureinfo]::CurrentCulture
to change the UI culture / culture for the current thread (only, non-persistently); e.g., the following command outputs the current date and time using the French culture:
[cultureinfo]::CurrentCulture = 'fr-FR'; Get-Date
Caveat: Due to a bug in Windows PowerShell, [cultureinfo]::CurrentUICulture
and [cultureinfo]::CurrentCulture
are unexpectedly reset to the session start-up values after every interactively submitted command; this problem has been fixed in PowerShell [Core] v6+ - see this answer.
The upshot is that if you want to run entire PowerShell sessions with different cultures than persistently configured, you can place assignments to [cultureinfo]::CurrentUICulture
and [cultureinfo]::CurrentCulture
in your $PROFILE
file in PowerShell [Core] v6+, but you'll need a workaround for Windows PowerShell - see this answer.
$PSUICulture
and $PSCulture
and therefore these variables do not reflect the effective culture set by the workaround (which relies on modifying a non-public field); however, Get-UICulture
/ Get-Culture
as well as [cultureinfo]::CurrentUICulture
/ [cultureinfo]::CurrentCulture
do.