Miscellaneous minor updates to WinCompat (#11980)

* Filter PSModulePath when starting PS 5.1. Removing PS-Core-specific paths from PSModulePath of WinCompat process (Windows PS).
* Make implicit WinCompat respect NoClobber and Scope parameters
* Add ErrorAction.Ignore when searching for WinPSCompatSession
This commit is contained in:
Andrew 2020-03-09 23:31:44 -07:00 committed by GitHub
parent 86ea202bae
commit 704b0e74ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 6 deletions

View file

@ -2359,7 +2359,7 @@ namespace Microsoft.PowerShell.Commands
{
if (importingModule)
{
IList<PSModuleInfo> moduleProxies = ImportModulesUsingWinCompat(new string[] { moduleManifestPath }, null, new ImportModuleOptions());
IList<PSModuleInfo> 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 @@ namespace Microsoft.PowerShell.Commands
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<PSSession>();
if (results.Count > 0)
{

View file

@ -93,13 +93,16 @@ namespace System.Management.Automation.Runspaces
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");

View file

@ -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" {

View file

@ -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) {