diff --git a/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs b/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs index b687e5027635..c10ef3db9b40 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs @@ -1275,11 +1275,13 @@ private static string UpdatePath(string path, string pathToAdd, ref int insertIn if (!string.IsNullOrEmpty(pathToAdd)) { path = AddToPath(path, pathToAdd, insertIndex); - insertIndex = path.IndexOf(Path.PathSeparator, PathContainsSubstring(path, pathToAdd)); - if (insertIndex != -1) + foreach (string addedSubPath in pathToAdd.Split(Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries)) { - // advance past the path separator - insertIndex++; + int newInsertIndex = PathContainsSubstring(path, addedSubPath) + addedSubPath.Length + 1; + if (newInsertIndex > insertIndex) + { + insertIndex = newInsertIndex; + } } } return path; diff --git a/test/powershell/engine/Module/ModulePath.Tests.ps1 b/test/powershell/engine/Module/ModulePath.Tests.ps1 index 5861455e726b..c1f584a3c72a 100644 --- a/test/powershell/engine/Module/ModulePath.Tests.ps1 +++ b/test/powershell/engine/Module/ModulePath.Tests.ps1 @@ -3,25 +3,22 @@ Describe "SxS Module Path Basic Tests" -tags "CI" { BeforeAll { - if ($IsWindows) - { + if ($IsWindows) { $powershell = "$PSHOME\pwsh.exe" $ProductName = "WindowsPowerShell" - if ($IsCoreCLR -and ($PSHOME -notlike "*Windows\System32\WindowsPowerShell\v1.0")) - { - $ProductName = "PowerShell" + if ($IsCoreCLR -and ($PSHOME -notlike "*Windows\System32\WindowsPowerShell\v1.0")) { + $ProductName = "PowerShell" } $expectedUserPath = Join-Path -Path $HOME -ChildPath "Documents\$ProductName\Modules" $expectedSharedPath = Join-Path -Path $env:ProgramFiles -ChildPath "$ProductName\Modules" - $userConfigPath = "~/Documents/powershell/powershell.config.json" - } - else - { + } else { $powershell = "$PSHOME/pwsh" $expectedUserPath = [System.Management.Automation.Platform]::SelectProductNameForDirectory("USER_MODULES") $expectedSharedPath = [System.Management.Automation.Platform]::SelectProductNameForDirectory("SHARED_MODULES") - $userConfigPath = "~/.config/powershell/powershell.config.json" } + $pwshUserDir = Split-Path $PROFILE.CurrentUserCurrentHost + if (!(Test-Path $pwshUserDir)) { New-Item -ItemType Directory -Path $pwshUserDir } + $userConfigPath = Join-Path $pwshUserDir powershell.config.json $userConfigExists = $false if (Test-Path $userConfigPath) { @@ -201,6 +198,19 @@ Describe "SxS Module Path Basic Tests" -tags "CI" { $out = & $powershell -noprofile -command '$env:PSModulePath' $out.Split([System.IO.Path]::PathSeparator, [System.StringSplitOptions]::RemoveEmptyEntries) | Should -Not -BeLike $validation } + + It 'PSModulePath set in powershell.config.json allows for multiple values' -Skip:(!$IsCoreCLR -or $skipNoPwsh) { + try { + $userConfig = '{ "PSModulePath": "' + "a$([System.IO.Path]::PathSeparator)b" + '"}' + Set-Content -Path $userConfigPath -Value $userConfig -Force + $out = & $powershell -noprofile -command 'powershell.exe -noprofile -command `$env:PSModulePath' + $psModulePaths = $out.Split([System.IO.Path]::PathSeparator, [System.StringSplitOptions]::RemoveEmptyEntries) + $psModulePaths | Should -Contain a + $psModulePaths | Should -Contain b + } finally { + Remove-Item -Path $userConfigPath -Force + } + } } Describe "ModuleIntrinsics.GetPSModulePath API tests" -tag @('CI', 'RequireAdminOnWindows', 'RequireSudoOnUnix') {