Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -910,14 +910,23 @@ public static string GetModulePath(string currentProcessModulePath, string hklmM
string systemModulePathToUse = string.IsNullOrEmpty(hklmMachineModulePath) ? psHomeModulePath : hklmMachineModulePath;

currentProcessModulePath = AddToPath(currentProcessModulePath, personalModulePathToUse, 0);
currentProcessModulePath = AddToPath(currentProcessModulePath, systemModulePathToUse, -1);

int insertIndex = -1;
#if !UNIX
string windowsPowerShellModulePath = GetWindowsPowerShellPSHomeModulePath();
// If the Windows PowerShell Module path is already present, insert the system module path
// ($PSHOME/Modules) before it.
insertIndex = PathContainsSubstring(currentProcessModulePath, windowsPowerShellModulePath);
#endif
currentProcessModulePath = AddToPath(currentProcessModulePath, systemModulePathToUse, insertIndex);
}

// if we reached this point - always add <Program Files> location to EVT.Process
// everything below is the same behaviour as WMF 4 code

// index of $PSHome\Modules in currentProcessModulePath
int indexOfPSHomeModulePath = PathContainsSubstring(currentProcessModulePath, psHomeModulePath);

// if $PSHome\Modules not found (psHomePosition == -1) - append <Program Files> location to the end;
// if $PSHome\Modules IS found (psHomePosition >= 0) - insert <Program Files> location before $PSHome\Modules
currentProcessModulePath = AddToPath(currentProcessModulePath, sharedModulePath, indexOfPSHomeModulePath);
Expand Down
29 changes: 29 additions & 0 deletions test/powershell/engine/Module/ModulePath.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,33 @@ Describe "SxS Module Path Basic Tests" -tags "CI" {
$paths -contains $customeModules | Should -BeTrue
}

It 'Ensures $PSHOME\Modules is inserted correctly when launched from a different version of PowerShell' -Skip:(!($IsCoreCLR -and $IsWindows)) {
# When launched from a different version of PowerShell, PSModulePath contains the other version's PSHOME\Modules path
# and the Windows PowerShell modoule path. THe other version's module path should be removed and this version's
# PSHOME\Modules path should be inserted before Windows PowerShell module path.
$winpwshModulePath = [System.IO.Path]::Combine([System.Environment]::SystemDirectory, "WindowsPowerShell", "v1.0", "Modules");
$pwshModulePath = Join-Path -Path $PSHOME -ChildPath 'Modules'

# create a fake 'other version' $PSHOME and $PSHOME\Modules
$fakeHome = Join-Path -Path $TestDrive -ChildPath 'fakepwsh'
$fakeModulePath = Join-Path -Path $fakeHome -ChildPath 'Modules'

$null = New-Item -Path $fakeHome -ItemType Directory
$null = New-Item -Path $fakeModulePath -ItemType Directory

# powershell looks for these to files to determine the directory is a pwsh directory.
Set-Content -Path "$fakeHome\pwsh.exe" -Value "fake pwsh.exe"
Set-Content -Path "$fakeHome\pwsh.deps.json" -Value 'fake pwsh.deps.json'

# replace the actual pwsh module path with the fake one.
$fakeModulePath = $env:PSModulePath.Replace($pwshModulePath, $fakeModulePath, [StringComparison]::OrdinalIgnoreCase)

$newModulePath = & $powershell -nopro -c '$env:PSModulePath'
$pwshIndex = $newModulePath.IndexOf($pwshModulePath, [StringComparison]::OrdinalIgnoreCase)
$wpshIndex = $newModulePath.IndexOf($winpwshModulePath, [StringComparison]::OrdinalIgnoreCase)
# ensure both module paths exist and the pwsh module path occurs before the Windows PowerShell module path
$pwshIndex | Should -Not -Be -1
$wpshIndex | Should -Not -Be -1
$pwshIndex | Should -BeLessThan $wpshIndex
}
}