Skip to content

Fix $env:PSModulePath for starting powershell within pwsh and vice versa #9957

Closed

Description

Based on @PowerShell/powershell-committee decision at PowerShell/PowerShell-RFC#133 (comment), we should:

  • PSCore6 currently will create $env:PSModulePath from config.json file, a new setting EnvVarToAppendToPSModulePath with value PSModulePath (this means the $PSHOME/Modules and user paths are first, then appends the $env:PSModulePath from the system)
  • Some logic needs to be retained so child PSCore6 trims any duplicates in $env:PSModulePath
  • When pwsh is started, we preserve the original $env:PSModulePath. Have whitelist to special case powershell.exe and powershell_ise.exe so when they are started within pwsh, they receive the original $env:PSModulePath. In all other cases, they inherit the current $env:PSModulePath.
  • Since modules are auto-discovered by newest version and not by order of the path, there is a scenario where starting different versions of pwsh from pwsh may result in unexpected behavior.

Activity

  1. iSazonov commented on Jun 20, 2019

    @iSazonov
    Collaborator

    I'd can grab this in near future. (Although there are already a lot of my PRs without review)

  2. SteveL-MSFT commented on Jun 20, 2019

    @SteveL-MSFT
    MemberAuthor

    Ilya (@iSazonov) I'll ask the team to spend more time on PR reviews to get the number back down. Thanks for your continued contributions!

  3. iSazonov commented on Jun 25, 2019

    @iSazonov
    Collaborator

    Steve Lee (@SteveL-MSFT) Please clarify about:

    PSCore6 currently will create $env:PSModulePath from config.json file, a new setting EnvVarToAppendToPSModulePath with value PSModulePath (this means the $PSHOME/Modules and user paths are first, then appends the $env:PSModulePath from the system)

    It seems already implemented by Dongbo Wang (@daxian-dbw)

    private static string SetModulePath()
    {
    string currentModulePath = GetExpandedEnvironmentVariable(Constants.PSModulePathEnvVar, EnvironmentVariableTarget.Process);
    string allUsersModulePath = PowerShellConfig.Instance.GetModulePath(ConfigScope.AllUsers);
    string personalModulePath = PowerShellConfig.Instance.GetModulePath(ConfigScope.CurrentUser);

    I guess that we need only replace writing to the pwsh process $env:PSModulePath with saving the module paths in global static variable s_psModulePath.

  4. JustinGrote commented on Oct 17, 2019

    @JustinGrote
    Contributor

    I get bit by this one often when calling powershell inside pwsh, because it ends up loading the "newer" microsoft.powershell.utility and for whatever reason import-powershelldatafile doesn't materialize, so I get lots of issues about import-powershelldatafile command not found.

    A simple try/catch on a not found to force import the PS5.1 version resolves the issue, but it'd be nice not to have to do it in the first place :)

  5. iSazonov commented on Oct 18, 2019

    @iSazonov
    Collaborator

    Justin Grote (@JustinGrote) You could try artifact from #10300 and feedback how it works for you.

  6. rjmholt commented on Oct 24, 2019

    @rjmholt
    Collaborator

    Since modules are auto-discovered by newest version and not by order of the path, there is a scenario where starting different versions of pwsh from pwsh may result in unexpected behavior.

    Is this true? What's the recommendation being made here?

  7. JustinGrote commented on Nov 15, 2019

    @JustinGrote
    Contributor

    Here's a lightweight fix you can put at the beginning of your script/profile or after any time you may have loaded some core libraries, it only does anything if this condition is met.

    The ideal fix would be that Windows Powershell Import-Module wouldn't load modules that have PSCompatibleEdition as 'Core' only, but we wouldn't be able to rely on that downstream functionality being available.

    Another option would be to proxy the import-module command and add the logic to filter out the core-only items until #11057 is merged.

    function Reset-WinPSModules {
        if ($PSEdition -eq 'Desktop') {
            Get-Module | Where-Object CompatiblePSEditions -eq 'Core' | foreach {
                $moduleToImport = Get-Module $PSItem.Name -ListAvailable | Where-Object CompatiblePSEditions -match 'Desktop' | Sort-Object Version -Descending | Select-Object -First 1
                if ($moduleToImport) {
                    write-verbose "Reloading $($PSItem.Name) with Windows Powershell-compatible version $($moduleToImport.version)"
                    Remove-Module $PSItem
                    Import-Module $moduleToImport -Force -Verbose:$false
                } else {
                    throw "A core-only version of the $($PSItem.Name) module was detected as loaded and no Windows Powershell Desktop-compatible equivalent was found in the PSModulePath. Please copy a Desktop-Compatible version of the module to your PSModulePath."
                }
            }
        }
    }
    Reset-WinPSModules
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Issue-Enhancementthe issue is more of a feature request than a bugResolution-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