Skip to content

Set-Culture should support setting the current session's culture also / optionally only #3833

Closed

Description

Note: As of v6-beta.1, Set-Culture isn't part of PowerShell Core yet, but I'm assuming it will be at some point (if technically feasible).

Set-Culture currently only changes the current user account's culture persistently, for future sessions.

Especially given that Get-Culture already reflects in-session changes of the culture (though it's not entirely clear at this point whether that's the intent - see #3831 ), it would be helpful to additionally support also / only setting the current session's culture.

Note that even without changes, the current help topic deserves updating to make it clear that the current session is not affected by the call.

Perhaps an optional -Scope parameter that supports the following values could be introduced:

  • CurrentUser ... (persistently) set culture for the current user account for future sessions only
  • Session ... (transiently) set culture for the current session only
  • CurrentUserAndSession ... (persistently) current user account + current session.

For backward compatibility, CurrentUser would have to be the default.

Environment data

PowerShell Core v6.0.0-beta (v6.0.0-beta.1)

Activity

  1. iSazonov commented on Oct 8, 2017

    @iSazonov
    Collaborator

    Steve Lee (@SteveL-MSFT) Have we plan to implement Set-Culture?

    It seems we can change a culture for current thread only.

  2. added
    Up-for-GrabsUp-for-grabs issues are not high priorities, and may be opportunities for external contributors
    HacktoberfestPotential candidate to participate in Hacktoberfest
    on Oct 8, 2017
  3. SteveL-MSFT commented on Oct 8, 2017

    @SteveL-MSFT
    Member

    Ilya (@iSazonov) no immediate plans

  4. iSazonov commented on Oct 9, 2017

    @iSazonov
    Collaborator

    We could use DefaultThreadCurrentCulture.
    The problem is that we have some appdomains:

    Steve Lee (@SteveL-MSFT) Dongbo Wang (@daxian-dbw) Jason Shirk (@lzybkr) Could you please comment? Is it possible to enumerate appdomains and set a culture?

  5. mklement0 commented on Oct 22, 2018

    @mklement0
    ContributorAuthor

    Ilya (@iSazonov): CultureInfo.DefaultThreadCurrentCulture is a per-application default, which I don't think is appropriate for our needs.

    Looking at this again months later:

    Presumably, we don't want to get into supporting persistent locale (culture) changes on Unix-like platforms, because there are no easy, standardized solutions.[1]

    As far as I'm aware, there's no support in .NET Core for this, just as there is no support for persisting environment variables in general ([environment]::SetEnvironmentVariable() doesn't support the User and Machine targets on Unix, and, similarly, our own RFC for enhanced environment-variable support only targets persistence support on Windows).

    This means that Set-Culture would only support -Scope Session on Unix and would therefore have to be the default there - which deviates from the default behavior (implied -Scope CurrentUser) in Windows PowerShell.

    That said, the same deviation already exists in the extant Get-Culture cmdlet, which reports the current-thread culture (only and invariably) in PowerShell Core on all platforms vs. the persisted user culture (only and invariably) in Windows PowerShell (irrespective of the thread's current culture).

    In short: I think what is called for is:

    • Make Set-Culture default to -Scope Session on all platforms, and support only Session on Unix-like platforms.

      • This makes it the PowerShell-idiomatic equivalent of [cultureinfo]::CurrentCulture = ...
    • On Windows, also support -Scope CurrentUser (current Windows PowerShell behavior) and -Scope CurrentUserAndSession for updating the user's default culture for future sessions and optionally also the current one.


    [1] Some pointers: On macOS, defaults write -g AppleLocale <local-id> updates the current user's locale persistently. On Debian-like Linux distros such as Ubuntu it is file /etc/default/locale that stores the default locale, but system-wide. I'm unclear on how it works in other Linux distros. However, user-level defaults on Linux would generally require modifying user-level initialization files, which are shell-specific.

  6. mklement0 commented on Oct 22, 2018

    @mklement0
    ContributorAuthor

    Taking a step back:

    In Windows PowerShell:

    • Get-Culture is built on the assumption that the culture won't change in-session, as it only ever reflects the persisted user-level setting.

      • Only if someone changes the culture in-session using the .NET framework directly (with [cultureinfo]::CurrentCulture = ...) do they see a discrepancy between the (thread's) current culture and the value reported by Get-Culture (and $PSCulture and $host.CurrentCulture).
    • Similarly, Set-Culture only updates the persisted setting without changing the in-session culture.

    In PowerShell Core:


    The Windows PowerShell *-Culture cmdlets were seemingly built with just reflecting / updating the persisted culture setting in mind, irrespective of in-session changes.

    In PowerShell Core we don't have support for that:

    • Get-Culture already always reflects the current culture - whether it is the persisted setting or was changed in-session

      • However, the behavior is consistent with Windows PowerShell as long as no in-session changes are made.
    • If we were to implement Set-Culture to default to the session only, it would result in fundamentally different behavior than in Windows PowerShell, which is maybe too problematic.

    So, if consistency with Windows PowerShell's Set-Culture is paramount, the choices are:

    • Continue to hold off on implementing Set-Culture in PS Core.

      • Add instructions to the Get-Culture and Set-Culture help topics to show how to change the current culture in-session using the .NET framework.
    • Implement it (as suggested in the initial post), but with the same default behavior as in Windows PowerShell, which means:

      • On Unix-like platforms, the only command form that will work is Set-Culture -Scope Session ..., and neglecting to specify -Scope Session will have to result in a not-implemented (statement-terminating) error.

      • On Windows, the default behavior is as in Windows PowerShell (-Scope CurrentUser implied), with the (not-extant in WinPS) options to also change the in-session culture (-Scope CurrentUserAndSession) or just the in-session culture (-Scope Session).

    Note that the price for this nod to consistency with Windows PowerShell would be an asymmetry between Get-Culture and Set-Culture in PS Core:

    In terms of the proposed Set-Culture implementation, Get-Culture's default behavior is conceptually -Scope Session (and again we'd lack the ability to implement -Scope CurrentUser on Unix), whereas Set-Culture's would be -Scope CurrentUser.

  7. iSazonov commented on Oct 22, 2018

    @iSazonov
    Collaborator

    Michael Klement (@mklement0) Thanks! We could start with -Scope Session.

  8. mklement0 commented on Oct 22, 2018

    @mklement0
    ContributorAuthor

    Yes, Ilya (@iSazonov), but we need to decide on whether:

    • -Scope Session should be the default - which would make it consistent with PS Core Get-Culture, but incompatible with Windows PowerShell's Set-Culture.

    • -Scope CurrentUser should be the default, to align (conceptually) with Windows PowerShell, which, however, makes it asymmetrical with PS Core Get-Culture and requires explicit use of -Scope Session for in-session changes (which would be the only scope supported on Unix, at least for now; in other words: something like Set-Culture de-DE would fail without -Scope Session).

  9. iSazonov commented on Feb 4, 2019

    @iSazonov
    Collaborator

    Steve Lee (@SteveL-MSFT) Could PowerShell Committee consider the cmdlet and defaults options (keep backward compatibility with Windows PowerShell or consistency with Get-Culture)?

  10. SteveL-MSFT commented on Feb 6, 2019

    @SteveL-MSFT
    Member

    @PowerShell/powershell-committee discussed this and would accept setting culture for PowerShell at system, user scopes, and process scope. The cmdlets would modify powershell.config.json and pwsh should read this on startup and set culture. Because these are PowerShell specific, recommendation is to call it Set-PSCulture. If there is a need to set system culture, that's an ask for Windows to create such a cmdlet. Also have new Get-PSCulture cmdlets that are symmetric to Set-PSCulture. Current Get-Culture would be deprecated. Set-PSCulture would be expected to update $PSCulture

  11. 10 remaining items

  12. iSazonov commented on Mar 1, 2019

    @iSazonov
    Collaborator

    Which ones do you disagree with?

    Root problem is that there is no standard api for setting a culture on OS level. Therefore, everything else looks like a personal preference - in every possible scenario, one sees a problem and the other benefits.

  13. mklement0 commented on Mar 1, 2019

    @mklement0
    ContributorAuthor

    you'd want to switch interface language of the tool on the fly.

    That's exactly what Set-Culture would enable you to do (at least if we also make it set [System.Threading.Thread]::CurrentThread.CurrentUICulture, which we should):

    Temporarily change the culture, for the duration of the session (or until changed again later in the session).

    On a related note, it would be handy to have a command for running one or more commands with a given culture and then revert to the previous one; here's what I personally use, gratefully adapted from an ancient blog post by Keith Hill (@rkeithhill)

    PS> Use-Culture ru-RU { Get-Date }
    пятница, 1 марта 2019 г. 13:53:21
  14. mklement0 commented on Mar 1, 2019

    @mklement0
    ContributorAuthor

    Root problem is that there is no standard api for setting a culture on OS level.

    It is a problem and it is unfortunate, but not one that must necessarily be solved by us.

    Only supporting -Scope Session (process) for Set-Culture on Unix-like platforms and defaulting to that is the best we can do under the circumstances:

    • It allows in-session changes, supporting the scenario you mentioned, for instance.

    • It allows users to place a Set-Culture call in their $PROFILE, if they really want to do that.

      • For the reasons stated, such an approach is not for everyone and compromises the robustness of cross-shell scripting / calling the PowerShell CLI from - at least as long as PowerShell still sources $PROFILE even in non-interactive scenarios (you can work around that with disciplined use of -noprofile, but note that if the culture were baked into powershell.config.json, you wouldn't even have that option).

    Should CoreFx APIs someday allow changing the culture persistently on Unix, we can enable it in Set-Culture then.

  15. iSazonov commented on Mar 13, 2019

    @iSazonov
    Collaborator
  16. mklement0 commented on Mar 14, 2019

    @mklement0
    ContributorAuthor

    The analyzer warning you link to recommends settings (and getting) [CultureInfo]::CurrentCulture] instead of [System.Threading.Thread]::CurrentThread.CurrentCulture], which in .NET Core is a must for cross-thread use.

    While that makes sense, we wouldn't be setting the culture for a different thread anyway, however (and assigning to [CultureInfo]::CurrentCulture] still only changes the targeted thread's culture).

    So how does this fit into our conversation?

    On a related note, however, with respect to in-session changes (the only kind we can currently provide on Unix, as discussed):

    As a shell that provides an environment for external programs as well, we want to change the culture for them too - which assigning to [CultureInfo]::CurrentCulture] by itself doesn't do:

    • On Unix-like platforms, as stated, we change the culture for external programs launched thereafter by also setting the relevant locale environment variable, LANG.

    • On Windows, regrettably, we seemingly cannot do this, which is a limitation we'd have to document (setting [cultureinfo]::DefaultThreadCurrentCulture only sets the default for (all threads in) the current application domain, and has no effect on external processes, whether they run managed code or not; the Windows API also seems to offer no process-wide setting).

  17. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  18. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  19. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  20. microsoft-github-policy-service commented on Nov 23, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

  21. rapettif commented on Jul 22, 2025

    @rapettif

    Maybe it could be a bit odd, but if compatibility with Windows Powershell is to be mantained, then the defaults should be the same, even if the defaults don't work on linux (should throw an error). Even if that means that you always need to specify a scope in linux, because the default scope is not supported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Committee-ReviewedPS-Committee has reviewed this and made a decisionIssue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassifResolution-No ActivityIssue has had no activity for 6 months or moreUp-for-GrabsUp-for-grabs issues are not high priorities, and may be opportunities for external contributorsWG-Cmdletsgeneral cmdlet issues

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions