Skip to content

PowerShell Core doesn't inherit PSModulePath environment variable from the environment #6850

Closed

Description

@Jaykul

Windows PowerShell correctly inherits environment variables from the environment -- although it may add paths to these variables, it doesn't ignore the existing environment.

PowerShell Core sets the PSModulePath -- completely ignoring and overwriting the existing environment, including the default values set in the Windows System Properties control panel...

This makes PowerShell Core's PSModulepath basically impossible to manage, since it can only be set reliably in a machine profile script --which depend on the install location of the shell, which changes with each release!!

Steps to reproduce

From Windows PowerShell run:

$Env:PSModulePath
pwsh -noprofile -command { $Env:PSModulePath }
pwsh -noprofile -command { powershell -noprofile -command { $Env:PSModulePath } }

From pwsh run:

$Env:PSModulePath
PowerShell -noprofile -command { $Env:PSModulePath }

Expected behavior

pwsh should respect it's environment.

Actual behavior

pwsh overwrites it's environment

Environment data

> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      6.0.2
PSEdition                      Core
GitCommitId                    v6.0.2
OS                             Microsoft Windows 10.0.17134
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Activity

  1. SteveL-MSFT commented on May 10, 2018

    @SteveL-MSFT
    Member

    There's explicit code clearing the variable

  2. Jaykul commented on May 10, 2018

    @Jaykul
    ContributorAuthor

    yes, but that code is based on the incorrect (or rather, outdated) assumptions that "The machine-wide and user-wide environment variables are only meaningful for full ps"

    First of all, since PowerShell itself does not set those environment variables, there is no basis for this assumption. These are environment variables under the control of the user. You have no right to ignore them.

    Second, as noted on #2636, many of the core modules do work. You've even released a module predicated on the fact that this is, in fact, not true 😉

    We can't on the one hand claim that many (or most) modules will just work, and on the other hand say that the environment variable is so toxic that we can't trust users (and enterprises) to deal with it properly. Especially since this breaks all reasonable expectations regarding environment variables.

  3. BrucePay commented on May 10, 2018

    @BrucePay
    Collaborator

    Maybe we should have another environment variable $ENV:PSModulePathCore. On startup, if PowerShell Core sees this variable, it uses it otherwise it falls back to $ENV:PSModulePath. With two variables, then powershell can call pwsh and pwsh can call powershell and everything works. And eventually we can create a PowerShellCommon module directory for modules that work with both and that both variables include.

  4. Jaykul commented on May 11, 2018

    @Jaykul
    ContributorAuthor

    A separate $Env:PSCoreModulePath environment variable kind-of makes sense.

    However, there are probably a lot of scripts and modules using $Env:PSModulePath ... I mean, at a minimum, people's profiles, and modules like PSDepend. Would you just read it and overwrite $Env:PSModulePath? Would that help?

    Could we rely on the modules themselves setting CompatiblePSEditions, and let each version of PowerShell ignore modules that aren't compatible? (Actually, sure this wouldn't work, nevermind. Most of the modules that I'm concerned with are legacy modules which aren't going to be updated with CompatiblePSEdition any time soon, but which still work ... )

    Bear in mind that in the near future, the more frustrating problem is Windows PowerShell. As new modules come out which take advantage of PowerShell Core functionality, Windows PowerShell won't be able to use them, and it does inherit the environment variable, already.

  5. BrucePay commented on May 11, 2018

    @BrucePay
    Collaborator

    I mean, at a minimum, people's profiles

    There are different profiles for desktop and core. You have to expend effort to get them to share common code and work properly. (e.g. no loading winform assemblies in your Core profile). So you put edition-specific tweaks in the appropriate profile.

    However, there are probably a lot of scripts and modules using $Env:PSModulePath

    Most scripts and modules depend on the module path being set correctly for the PS edition they are using. With separate variables, by default they will only load modules from the module directories associated with their shell edition. For things that work directly with PSModulePath, they'll have to be updated to understand PowerShell Core.

    Could we rely on the modules themselves setting CompatiblePSEditions, and let each version of PowerShell ignore modules that aren't compatible?

    Without separate 'edition' directories, how do I have both "core" and "desktop" install paths for a given module/version? (Nuget does this with <package>/<version>/lib/<editionEquivalent> but that would require changing both Core and Windows Powershell so it is unlikely to happen.)

    Bear in mind that in the near future, the more frustrating problem is Windows PowerShell. As new modules come out which take advantage of PowerShell Core functionality, Windows PowerShell won't be able to use them, and it does inherit the environment variable, already.

    All the more reason to have separate module paths. I should be able to do

    powershell {
        Get-ADComputer ...
    }
    

    from pwsh.exe and it should just work.

  6. SteveL-MSFT commented on May 11, 2018

    @SteveL-MSFT
    Member

    Separate env vars makes sense to me. I think Bruce Payette (@BrucePay)'s proposal makes sense to respect user defined env vars and keep existing behavior for compatibility reasons, although I would call it PSCoreModulePath

  7. kilasuit commented on May 16, 2018

    @kilasuit
    Collaborator

    Separate env vars doesn't make sense to me

    but neither was the decision to overwrite the existing 1 on pwsh loading, although I can understand WHY it happened, it doesn't mean I agree that the decision was the right course of action either back then or now going forward.

    I'd personally opt for reverting the explicit code that changed this as IMO this wasn't an ideal change to make

    Otherwise you'd need to change pwsh and a number of other tools, like PowerShellGet to have more unneeded points of complexity where reverting this would in my opinion make much more sense going forward

  8. SteveL-MSFT commented on May 16, 2018

    @SteveL-MSFT
    Member

    @PowerShell/powershell-committee reviewed this and agrees that this issue warrants an RFC. Bruce Payette (@BrucePay) has offered to author the RFC.

  9. added
    Committee-ReviewedPS-Committee has reviewed this and made a decision
    Breaking-Changebreaking change that may affect users
    and removed
    Review - CommitteeThe PR/Issue needs a review from the PowerShell Committee
    on May 16, 2018
  10. iSazonov commented on Jan 15, 2019

    @iSazonov
    Collaborator

    Steve Lee (@SteveL-MSFT) Taking in account #8635 could you please force the RFC?

  11. SteveL-MSFT commented on Jan 18, 2019

    @SteveL-MSFT
    Member

    I believe Bruce Payette (@BrucePay) still plans to author this

  12. BrucePay commented on Jan 18, 2019

    @BrucePay
    Collaborator

    Steve Lee (@SteveL-MSFT) Joey Aiello (@joeyaiello) The existing RFC PR is here: PowerShell/PowerShell-RFC#133 Perhaps we can discuss this in the next committee RFC meeting on Monday.

  13. morsley commented on Aug 6, 2019

    @morsley

    Any update to where this is at? Just re-installed pwsh on a machine and it clobbered my psmodulepath for Windows powershell which broke psreadline - immediately noticeable.

  14. marcinsmialek commented on Aug 6, 2019

    @marcinsmialek

    While this isn't the solution to this problem, this may be a handy workaround, at least it's how I deal with this issue right now:
    From PowerShell Core:

    1. Install it with remoting / enable remoting
    2. Install-Module WindowsCompatibility
    3. Import-WinModule LegacyModule
    4. Run commands from the LegacyModule shim
  15. iSazonov commented on Aug 6, 2019

    @iSazonov
    Collaborator

    #10300 is pulled to resolve the issue and others based on PowerShell Committee conclusion.

  16. MarcoPeraza commented on Oct 9, 2022

    @MarcoPeraza

    This is broken again, at least on insider builds and latest versions of pwsh.

  17. bedesv commented on Apr 15, 2024

    @bedesv

    I'm getting this issue with Get-FileHash on Powershell Core v7.4.2.
    image

    Line causing the error:
    powershell -c "foreach ($file in Get-ChildItem '%TARGET_LOCATION%') { Get-FileHash -Algorithm MD5 $file.FullName }"

    Get-FileHash : The term 'Get-FileHash' is not recognized as the name of a cmdlet, function, script file, or operable
    program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At line:1 char:68
    + ... Get-ChildItem 'C:\temp' -Filter enabler-*.zip) { Get-FileHash -Algori ...
    +                                                      ~~~~~~~~~~~~
        + CategoryInfo          : ObjectNotFound: (Get-FileHash:String) [], CommandNotFoundException
        + FullyQualifiedErrorId : CommandNotFoundException
    
  18. potatoday commented on Feb 19, 2025

    @potatoday

    Can't even compute a hash. I see the problem. Powershell is run by committee. Just like MS altogether these days, fix something break something else.

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

    Breaking-Changebreaking change that may affect usersCommittee-ReviewedPS-Committee has reviewed this and made a decisionResolution-FixedThe issue is fixed.WG-Enginecore PowerShell engine, interpreter, and runtime

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions