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 @@ -1152,6 +1152,11 @@ private static string AddToPath(string basePath, string pathToAdd, int insertPos
else
result.Append(Path.PathSeparator + subPathToAdd);
}
else if (insertPosition > result.Length)
{
// handle case where path is a singleton with no path seperator already
result.Append(Path.PathSeparator).Append(subPathToAdd);
}
else // insert at the requested location (this is used by DSC (<Program Files> location) and by 'user-specific location' (SpecialFolder.MyDocuments or EVT.User))
{
result.Insert(insertPosition, subPathToAdd + Path.PathSeparator);
Expand All @@ -1164,9 +1169,7 @@ private static string AddToPath(string basePath, string pathToAdd, int insertPos
}

/// <summary>
/// Checks the various PSModulePath environment string and returns PSModulePath string as appropriate. Note - because these
/// strings go through the provider, we need to escape any wildcards before passing them
/// along.
/// Checks the various PSModulePath environment string and returns PSModulePath string as appropriate.
/// </summary>
public static string GetModulePath(string currentProcessModulePath, string hklmMachineModulePath, string hkcuUserModulePath)
{
Expand Down Expand Up @@ -1196,11 +1199,6 @@ public static string GetModulePath(string currentProcessModulePath, string hklmM
{
currentProcessModulePath += hklmMachineModulePath; // += EVT.Machine
}

#if !UNIX
// Add Windows Modules path
currentProcessModulePath = $"{currentProcessModulePath}{Path.PathSeparator}{s_windowsPowerShellPSHomeModulePath}";
#endif
}
// EVT.Process exists
// Now handle the case where the environment variable is already set.
Expand Down Expand Up @@ -1281,9 +1279,16 @@ internal static string GetWindowsPowerShellModulePath()
private static string SetModulePath()
{
string currentModulePath = GetExpandedEnvironmentVariable(Constants.PSModulePathEnvVar, EnvironmentVariableTarget.Process);
#if !UNIX
// if the current process and user env vars are the same, it means we need to append the machine one as it's incomplete
// otherwise, the user modified it and we should use the process one
if (string.CompareOrdinal(GetExpandedEnvironmentVariable(Constants.PSModulePathEnvVar, EnvironmentVariableTarget.User), currentModulePath) == 0)
{
currentModulePath = currentModulePath + Path.PathSeparator + GetExpandedEnvironmentVariable(Constants.PSModulePathEnvVar, EnvironmentVariableTarget.Machine);
}
#endif
string allUsersModulePath = PowerShellConfig.Instance.GetModulePath(ConfigScope.AllUsers);
string personalModulePath = PowerShellConfig.Instance.GetModulePath(ConfigScope.CurrentUser);

string newModulePathString = GetModulePath(currentModulePath, allUsersModulePath, personalModulePath);

if (!string.IsNullOrEmpty(newModulePathString))
Expand Down
36 changes: 19 additions & 17 deletions test/powershell/engine/Module/ModulePath.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,19 @@ Describe "SxS Module Path Basic Tests" -tags "CI" {

$env:PSModulePath = ""
$defaultModulePath = & $powershell -nopro -c '$env:PSModulePath'
$pathSeparator = [System.IO.Path]::PathSeparator

$paths = $defaultModulePath -split [System.IO.Path]::PathSeparator
$paths = $defaultModulePath.Replace("$pathSeparator$pathSeparator", "$pathSeparator") -split $pathSeparator

if ($IsWindows)
{
$paths.Count | Should -Be 4
$expectedPaths = 3 # user, shared, pshome
$userPaths = [System.Environment]::GetEnvironmentVariable("PSModulePath", [System.EnvironmentVariableTarget]::User)
$expectedPaths += $userPaths ? $userPaths.Split($pathSeparator).Count : 0
$machinePaths = [System.Environment]::GetEnvironmentVariable("PSModulePath", [System.EnvironmentVariableTarget]::Machine)
$expectedPaths += $machinePaths ? $machinePaths.Split($pathSeparator).Count : 0

$paths.Count | Should -Be $expectedPaths
}
else
{
Expand All @@ -85,10 +92,7 @@ Describe "SxS Module Path Basic Tests" -tags "CI" {
$paths[0].TrimEnd([System.IO.Path]::DirectorySeparatorChar) | Should -Be $expectedUserPath
$paths[1].TrimEnd([System.IO.Path]::DirectorySeparatorChar) | Should -Be $expectedSharedPath
$paths[2].TrimEnd([System.IO.Path]::DirectorySeparatorChar) | Should -Be $expectedSystemPath
if ($IsWindows)
{
$paths[3].TrimEnd([System.IO.Path]::DirectorySeparatorChar) | Should -Be $expectedWindowsPowerShellPSHomePath
}
$defaultModulePath | Should -BeLike "*$expectedWindowsPowerShellPSHomePath*"
}

It "Works with pshome module path derived from a different PowerShell instance" -Skip:(!$IsCoreCLR -or $skipNoPwsh) {
Expand All @@ -104,18 +108,11 @@ Describe "SxS Module Path Basic Tests" -tags "CI" {
$env:PSModulePath = $fakePSHomeModuleDir
$newModulePath = & $powershell -nopro -c '$env:PSModulePath'
$paths = $newModulePath -split [System.IO.Path]::PathSeparator

$paths.Count | Should -Be 4

$paths[0] | Should -Be $expectedUserPath
$paths[1] | Should -Be $expectedSharedPath
$paths[2] | Should -Be $expectedSystemPath
$paths[3] | Should -Be $fakePSHomeModuleDir
if ($IsWindows)
{
$expectedWindowsPowerShellPSHomePath | Should -Not -BeIn $paths
}

} finally {

## Remove 'powershell' and 'pwsh.deps.json' from the fake PSHome folder
Expand Down Expand Up @@ -180,9 +177,14 @@ Describe "SxS Module Path Basic Tests" -tags "CI" {
}

It 'Windows PowerShell does not inherit path defined in powershell.config.json' -Skip:(!$IsWindows) {
$userConfig = '{ "PSModulePath": "myUserPath" }'
Set-Content -Path $userConfigPath -Value $userConfig -Force
$out = pwsh -noprofile -command 'powershell.exe -noprofile -command $env:PSModulePath'
$out | Should -Not -BeLike 'myUserPath;*'
try {
$userConfig = '{ "PSModulePath": "myUserPath" }'
Set-Content -Path $userConfigPath -Value $userConfig -Force
$out = pwsh -noprofile -command 'powershell.exe -noprofile -command $env:PSModulePath'
$out | Should -Not -BeLike 'myUserPath;*'
}
finally {
Remove-Item -Path $userConfigPath -Force
}
}
}