diff --git a/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs b/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs index e2c446f5ac..fde3618e56 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs @@ -1172,6 +1172,42 @@ namespace System.Management.Automation return result.ToString(); } + /// + /// The available module path scopes. + /// + public enum PSModulePathScope + { + /// The users module path. + User, + + /// The Builtin module path. This is where PowerShell is installed (PSHOME). + Builtin, + + /// The machine module path. This is the shared location for all users of the system. + Machine + } + + /// + /// Retrieve the current PSModulePath for the specified scope. + /// + /// The scope of module path to retrieve. This can be User, Builtin, or Machine. + /// The string representing the requested module path type. + public static string GetPSModulePath(PSModulePathScope scope) + { + if (scope == PSModulePathScope.User) + { + return GetPersonalModulePath(); + } + else if (scope == PSModulePathScope.Builtin) + { + return GetPSHomeModulePath(); + } + else + { + return GetSharedModulePath(); + } + } + /// /// Checks the various PSModulePath environment string and returns PSModulePath string as appropriate. /// diff --git a/test/powershell/engine/Module/ModulePath.Tests.ps1 b/test/powershell/engine/Module/ModulePath.Tests.ps1 index a18b4fc3ff..aabbb28950 100644 --- a/test/powershell/engine/Module/ModulePath.Tests.ps1 +++ b/test/powershell/engine/Module/ModulePath.Tests.ps1 @@ -202,3 +202,48 @@ Describe "SxS Module Path Basic Tests" -tags "CI" { $out.Split([System.IO.Path]::PathSeparator, [System.StringSplitOptions]::RemoveEmptyEntries) | Should -Not -BeLike $validation } } + +Describe "ModuleIntrinsics.GetPSModulePath API tests" -tag @('CI', 'RequireAdminOnWindows', 'RequireSudoOnUnix') { + BeforeAll { + # create a local repostory and install a module + $localSourceName = [Guid]::NewGuid().ToString("n") + $localSourceLocation = Join-Path $PSScriptRoot assets + Register-PSRepository -Name $localSourceName -SourceLocation $localSourceLocation -InstallationPolicy Trusted -ErrorAction SilentlyContinue + Install-Module -Force -Scope AllUsers -Name PowerShell.TestPackage -Repository $localSourceName -ErrorAction SilentlyContinue + Install-Module -Force -Scope CurrentUser -Name PowerShell.TestPackage -Repository $localSourceName -ErrorAction SilentlyContinue + + $testCases = @( + @{ Name = "User" ; Expected = $IsWindows ? + (Resolve-Path ([Environment]::GetFolderPath("Personal") + "\PowerShell\Modules")).Path : + (Resolve-Path ([System.Management.Automation.Platform]::SelectProductNameForDirectory("USER_MODULES"))).Path + } + @{ Name = "Machine" ; Expected = $IsWindows ? + [Environment]::GetFolderPath("ProgramFiles") + "\PowerShell\Modules" : + (Resolve-Path ([System.Management.Automation.Platform]::SelectProductNameForDirectory("SHARED_MODULES"))).Path + } + @{ Name = "Builtin" ; Expected = (Resolve-Path (Join-Path $PSHOME Modules)).Path } + ) + # resolve the paths to ensure they are in the correct format + $currentModulePathElements = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Foreach-Object { (Resolve-Path $_).Path } + } + + AfterAll { + Unregister-PSRepository -Name $localSourceName -ErrorAction SilentlyContinue + } + + It "The value '' should return the proper value" -testcase $testCases { + param ( $Name, $Expected ) + $result = [System.Management.Automation.ModuleIntrinsics]::GetPSModulePath($name) + $result | Should -not -BeNullOrEmpty + # spot check pshome, the user and shared paths may not be present + if ( $name -eq "PSHOME") { + $result | Should -Be $Expected + } + } + + It "The current module path should contain the expected paths for ''" -testcase $testCases { + param ( $Name, $Expected ) + $mPath = (Resolve-Path ([System.Management.Automation.ModuleIntrinsics]::GetPSModulePath($name))).Path + $currentModulePathElements | Should -Contain $mPath + } +} diff --git a/test/powershell/engine/Module/assets/PowerShell.TestPackage.3.2.1.nupkg b/test/powershell/engine/Module/assets/PowerShell.TestPackage.3.2.1.nupkg new file mode 100644 index 0000000000..bc3a6d9b09 Binary files /dev/null and b/test/powershell/engine/Module/assets/PowerShell.TestPackage.3.2.1.nupkg differ