diff --git a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs index 8c71d4be4b7..986e1deff51 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs @@ -2359,7 +2359,7 @@ internal PSModuleInfo LoadModuleManifest( { if (importingModule) { - IList moduleProxies = ImportModulesUsingWinCompat(new string[] { moduleManifestPath }, null, new ImportModuleOptions()); + IList moduleProxies = ImportModulesUsingWinCompat(new string[] { moduleManifestPath }, null, options); // we are loading by a single ManifestPath so expect max of 1 if (moduleProxies.Count > 0) @@ -4799,6 +4799,7 @@ internal static PSSession GetWindowsPowerShellCompatRemotingSession() using var ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace); ps.AddCommand(commandInfo); ps.AddParameter("Name", WindowsPowerShellCompatRemotingSessionName); + ps.AddParameter("ErrorAction", ActionPreference.Ignore); var results = ps.Invoke(); if (results.Count > 0) { diff --git a/src/System.Management.Automation/engine/hostifaces/PowerShellProcessInstance.cs b/src/System.Management.Automation/engine/hostifaces/PowerShellProcessInstance.cs index 5ea05bd2c0f..736a229d09d 100644 --- a/src/System.Management.Automation/engine/hostifaces/PowerShellProcessInstance.cs +++ b/src/System.Management.Automation/engine/hostifaces/PowerShellProcessInstance.cs @@ -93,13 +93,16 @@ public PowerShellProcessInstance(Version powerShellVersion, PSCredential credent LoadUserProfile = true, #endif }; - +#if !UNIX if (startingWindowsPowerShell51) { _startInfo.ArgumentList.Add("-Version"); _startInfo.ArgumentList.Add("5.1"); - } + // if starting Windows PowerShell, need to remove PowerShell specific segments of PSModulePath + _startInfo.Environment["PSModulePath"] = ModuleIntrinsics.GetWindowsPowerShellModulePath(); + } +#endif _startInfo.ArgumentList.Add("-s"); _startInfo.ArgumentList.Add("-NoLogo"); _startInfo.ArgumentList.Add("-NoProfile"); diff --git a/test/powershell/Modules/Microsoft.PowerShell.Core/CompatiblePSEditions.Module.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Core/CompatiblePSEditions.Module.Tests.ps1 index 7ae3a77de9d..c9929eed965 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Core/CompatiblePSEditions.Module.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Core/CompatiblePSEditions.Module.Tests.ps1 @@ -355,6 +355,20 @@ Describe "Import-Module from CompatiblePSEditions-checked paths" -Tag "CI" { Set-Location $pwdBackup } } + + It "-NoClobber and -Scope work with implicit WinCompat" -TestCases $failCases -Skip:(-not $IsWindows) { + param($Editions, $ModuleName, $Result) + try + { + Set-Item function:Test-$ModuleName {"OriginalFunctionImplementation"} + Import-Module $ModuleName -Force -WarningAction Ignore -Scope Local -NoClobber + & "Test-$ModuleName" | Should -BeExactly "OriginalFunctionImplementation" + } + finally + { + Remove-Item function:Test-$ModuleName + } + } } Context "Imports from absolute path" { @@ -429,6 +443,7 @@ Describe "Additional tests for Import-Module with WinCompat" -Tag "Feature" { $ModuleName = "DesktopModule" $ModuleName2 = "DesktopModule2" $basePath = Join-Path $TestDrive "WinCompatModules" + $allModules = @($ModuleName, $ModuleName2) Remove-Item -Path $basePath -Recurse -ErrorAction SilentlyContinue # create an incompatible module that generates an error on import New-EditionCompatibleModule -ModuleName $ModuleName -CompatiblePSEditions "Desktop" -Dir $basePath -ErrorGenerationCode '1/0;' @@ -538,6 +553,62 @@ Describe "Additional tests for Import-Module with WinCompat" -Tag "Feature" { $out | Should -BeExactly 'CouldNotAutoloadMatchingModule' } } + + Context "Tests around PSModulePath in WinCompat process" { + BeforeAll { + $pwsh = "$PSHOME/pwsh" + Add-ModulePath $basePath + $ConfigPath = Join-Path $TestDrive 'powershell.config.json' + } + + AfterAll { + Restore-ModulePath + } + + AfterEach { + Get-Module $allModules | Remove-Module -Force + } + + It 'WinCompat process does not inherit PowerShell-Core-specific paths' { + # these paths were copied from test\powershell\engine\Module\ModulePath.Tests.ps1 + $pscoreUserPath = Join-Path -Path $HOME -ChildPath "Documents\PowerShell\Modules" + $pscoreSharedPath = Join-Path -Path $env:ProgramFiles -ChildPath "PowerShell\Modules" + $pscoreSystemPath = Join-Path -Path $PSHOME -ChildPath 'Modules' + + $pscorePaths = $env:psmodulepath + $pscorePaths | Should -BeLike "*$pscoreUserPath*" + $pscorePaths | Should -BeLike "*$pscoreSharedPath*" + $pscorePaths | Should -BeLike "*$pscoreSystemPath*" + + Import-Module $ModuleName2 -UseWindowsPowerShell -Force -WarningAction Ignore + $s = Get-PSSession -Name WinPSCompatSession + $winpsPaths = Invoke-Command -Session $s -ScriptBlock {$env:psmodulepath} + $winpsPaths | Should -Not -BeLike "*$pscoreUserPath*" + $winpsPaths | Should -Not -BeLike "*$pscoreSharedPath*" + $winpsPaths | Should -Not -BeLike "*$pscoreSystemPath*" + } + + It 'WinCompat process inherits user added paths' { + $mypath = Join-Path $env:SystemDrive MyDir + $originalModulePath = $env:PSModulePath + try { + $env:PSModulePath += ";$mypath" + Import-Module $ModuleName2 -UseWindowsPowerShell -Force -WarningAction Ignore + $s = Get-PSSession -Name WinPSCompatSession + $winpsPaths = Invoke-Command -Session $s -ScriptBlock {$env:psmodulepath} + $winpsPaths | Should -BeLike "*$mypath*" + } + finally { + $env:PSModulePath = $originalModulePath + } + } + + It 'Windows PowerShell does not inherit path defined in powershell.config.json' { + '{ "PSModulePath": "C:\\MyTestDir" }' | Out-File -Force $ConfigPath + $winpsPaths = & $pwsh -NoProfile -NonInteractive -settingsFile $ConfigPath -c "Import-Module $ModuleName2 -UseWindowsPowerShell -WarningAction Ignore;`$s = Get-PSSession -Name WinPSCompatSession;Invoke-Command -Session `$s -ScriptBlock {`$env:psmodulepath}" + $winpsPaths | Should -Not -BeLike "*MyTestDir*" + } + } } Describe "PSModulePath changes interacting with other PowerShell processes" -Tag "Feature" { diff --git a/test/powershell/engine/Module/ModulePath.Tests.ps1 b/test/powershell/engine/Module/ModulePath.Tests.ps1 index 00f5d51bf1a..952908edb4f 100644 --- a/test/powershell/engine/Module/ModulePath.Tests.ps1 +++ b/test/powershell/engine/Module/ModulePath.Tests.ps1 @@ -165,9 +165,9 @@ Describe "SxS Module Path Basic Tests" -tags "CI" { It 'Windows PowerShell does not inherit PowerShell paths' -Skip:(!$IsWindows) { $out = powershell.exe -noprofile -command '$env:PSModulePath' - $out | Should -Not -Contain $expectedUserPath - $out | Should -Not -Contain $expectedSharedPath - $out | Should -Not -Contain $expectedSystemPath + $out | Should -Not -BeLike "*$expectedUserPath*" + $out | Should -Not -BeLike "*$expectedSharedPath*" + $out | Should -Not -BeLike "*$expectedSystemPath*" } It 'Windows PowerShell inherits user added paths' -Skip:(!$IsWindows) {