0% found this document useful (0 votes)
117 views4 pages

PowerShell 7 Module Path Overview

The $env:PSModulePath environment variable contains locations that PowerShell searches to find modules. By default, it includes system-wide, user-installed, and application-specific module locations. PowerShell recursively searches each folder in the path for module files. The PSModulePath can be modified to add additional module locations for the current session or permanently across sessions.

Uploaded by

Viktor Zipenjuk
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
117 views4 pages

PowerShell 7 Module Path Overview

The $env:PSModulePath environment variable contains locations that PowerShell searches to find modules. By default, it includes system-wide, user-installed, and application-specific module locations. PowerShell recursively searches each folder in the path for module files. The PSModulePath can be modified to add additional module locations for the current session or permanently across sessions.

Uploaded by

Viktor Zipenjuk
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

2/2/24, 4:06 PM about PSModulePath - PowerShell | Microsoft Learn

about_PSModulePath
Article03/24/2023

Short description
This article describes the purpose and usage of the $env:PSModulePath environment variable.

Long description
The $env:PSModulePath environment variable contains a list of folder locations that are searched to find
modules and resources. PowerShell recursively searches each folder for module ( .psd1 or .psm1 ) files.

Install-Module has a Scope parameter that allows you to specify whether the module is installed for the
current user or for all users. For more information, see Install-Module.

By default, the effective locations assigned to $env:PSModulePath are:

System-wide locations: These folders contain modules that ship with PowerShell. These modules are
stored in the $PSHOME\Modules folder.
On Windows, modules installed in the AllUsers scope are stored
in $env:ProgramFiles\WindowsPowerShell\Modules .
On non-Windows systems, modules installed in the AllUsers scope are stored
in /usr/local/share/powershell/Modules .

User-installed modules: On Windows, modules installed in the CurrentUser scope are typically
stored in the $HOME\Documents\WindowsPowerShell\Modules folder. The specific location of
the Documents folder varies by version of Windows and when you use folder redirection. Also, Microsoft
OneDrive can change the location of your Documents folder. You can verify the location of
your Documents folder using the following command: [Environment]::GetFolderPath('MyDocuments') .

On non-Windows systems, modules installed in the CurrentUser scope are stored in


the $HOME/.local/share/powershell/Modules folder.

Application specific modules: Setup programs can install modules in other directories, such as
the Program Files folder on Windows. The installer package may or may not append the location to
the $env:PSModulePath .

PowerShell PSModulePath construction


The value of $env:PSModulePath is constructed each time PowerShell starts. The value varies by version of
PowerShell and how it's launched.

Windows PowerShell startup


Windows PowerShell uses the following logic to construct the PSModulePath at startup:

[Link] 1/4
2/2/24, 4:06 PM about PSModulePath - PowerShell | Microsoft Learn

If PSModulePath doesn't exist, combine CurrentUser, AllUsers, and the $PSHOME modules paths
If PSModulePath does exist:
If PSModulePath contains $PSHOME modules path:
AllUsers modules path is inserted before $PSHOME modules path
else:
Just use PSModulePath as defined since the user deliberately removed the $PSHOME location

The CurrentUser module path is prefixed only if the User scope $env:PSModulePath doesn't exist. Otherwise,
the User scope $env:PSModulePath is used as defined.

PowerShell 7 startup
In Windows, for most environment variables, if the User-scoped variable exists, a new process uses that value
only even if a Machine-scoped variable of the same name exists.

In PowerShell 7, PSModulePath is treated similar to how the Path environment variable is treated on
Windows. On Windows, Path is treated differently from other environment variables. When a process is
started, Windows combines the User-scoped Path with the Machine-scoped Path .

Retrieve the User-scoped PSModulePath


Compare to process inherited PSModulePath environment variable
If the same:
Append the AllUsers PSModulePath to the end following the semantics of the Path environment
variable
The Windows System32 path comes from the machine defined PSModulePath so does not need to
be added explicitly
If different, treat as though user explicitly modified it and don't append AllUsers PSModulePath
Prefix with PS7 User, System, and $PSHOME paths in that order
If [Link] contains a user scoped PSModulePath , use that instead of the default for
the user
If [Link] contains a system scoped PSModulePath , use that instead of the default for
the system

Unix systems don't have a separation of User and System environment variables. PSModulePath is inherited
and the PS7-specific paths are prefixed if not already defined.

Starting Windows PowerShell from PowerShell 7


For this discussion, Windows PowerShell means both [Link] and powershell_ise.exe .

The value of $env:PSModulePath is copied to WinPSModulePath with the following modifications:

Remove PS7 the User module path


Remove PS7 the System module path
Remove PS7 the $PSHOME module path

The PS7 paths are removed so that PS7 modules don't get loaded in Windows PowerShell.
The WinPSModulePath value is used when starting Windows PowerShell.

[Link] 2/4
2/2/24, 4:06 PM about PSModulePath - PowerShell | Microsoft Learn

Starting PowerShell 7 from Windows PowerShell


The PowerShell 7 startup continues as-is with the addition of inheriting paths that Windows PowerShell
added. Since the PS7-specific paths are prefixed, there is no functional issue.

Module search behavior


PowerShell recursively searches each folder in the PSModulePath for module ( .psd1 or .psm1 ) files. This
search pattern allows multiple versions of the same module to be installed in different folders. For example:

Output

Directory: C:\Program Files\WindowsPowerShell\Modules\PowerShellGet

Mode LastWriteTime Length Name


---- ------------- ------ ----
d---- 8/14/2020 5:56 PM [Link]
d---- 9/13/2019 3:53 PM 2.1.2

By default, PowerShell loads the highest version number of a module when multiple versions are found. To
load a specific version, use Import-Module with the FullyQualifiedName parameter. For more information,
see Import-Module.

Modifying PSModulePath
For most situations, you should be installing modules in the default module locations. However, you may
have a need to change the value of the PSModulePath environment variable.

For example, to temporarily add the C:\Program Files\Fabrikam\Modules directory to $env:PSModulePath for
the current session, type:

PowerShell

$Env:PSModulePath = $Env:PSModulePath+";C:\Program Files\Fabrikam\Modules"

The semi-colon ( ; ) in the command separates the new path from the path that precedes it in the list. On
non-Windows platforms, the colon ( : ) separates the path locations in the environment variable.

Modifying PSModulePath in non-Windows


To change the value of PSModulePath for every session in a non-Windows environment, add the previous
command to your PowerShell profile.

[Link] 3/4
2/2/24, 4:06 PM about PSModulePath - PowerShell | Microsoft Learn

Modifying PSModulePath in Windows


To change the value of PSModulePath in every session, edit the registry key storing the PSModulePath values.
The PSModulePath values are stored in the registry as unexpanded strings. To avoid permanently saving
the PSModulePath values as expanded strings, use the GetValue method on the subkey and edit the value
directly.

The following example adds the C:\Program Files\Fabrikam\Modules path to the value of
the PSModulePath environment variable without expanding the un-expanded strings.

PowerShell

$key = (Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Session


Manager').OpenSubKey('Environment', $true)
$path = $[Link]('PSModulePath','','DoNotExpandEnvironmentNames')
$path += ';%ProgramFiles%\Fabrikam\Modules'
$[Link]('PSModulePath',$path,[[Link]]::ExpandString)

To add a path to the user setting, change the registry provider from HKLM:\ to HKCU:\ .

PowerShell

$key = (Get-Item 'HKCU:\').OpenSubKey('Environment', $true)


$path = $[Link]('PSModulePath','','DoNotExpandEnvironmentNames')
$path += ';%ProgramFiles%\Fabrikam\Modules'
$[Link]('PSModulePath',$path,[[Link]]::ExpandString)

See also
about_Modules

[Link] 4/4

Common questions

Powered by AI

Adjusting the PSModulePath environment variable is necessary when you need to include additional directories for module discovery, such as when developing custom modules or using third-party modules that aren't stored in default locations. Modifications might be necessary to temporarily or permanently include paths specific to an application or development environment. The consequences of such modifications can include unintended conflicts if multiple paths contain modules of the same name or different versions, potentially leading to module load conflicts or unexpected behavior .

On Windows systems, paths in the PSModulePath environment variable are separated by semi-colons, while on non-Windows systems, they're separated by colons. Additionally, Windows has separate user and system environment variable scopes, while non-Windows systems do not have this separation. This means that while Windows combines paths at startup from both scopes, non-Windows systems inherit paths directly without differentiation, necessitating different path management practices depending on the platform .

To temporarily include a new module directory in the PSModulePath for the current PowerShell session, you can simply modify the $Env:PSModulePath environment variable by appending the new path. For Windows, the command would use a semi-colon as a separator: $Env:PSModulePath += ';C:\NewModulePath'. On non-Windows platforms, the colon is used as a separator. This change is effective only for the current session and does not persist across sessions .

To change the PSModulePath permanently in a Windows environment, you must modify the registry entry that stores the PSModulePath values. This involves using the registry editor to add paths without expanding the unexpanded strings, which avoids automatically saving expanded paths that would require careful edits each time to prevent path corruption. Using the GetValue method retrieves the current value without expanding, and the SetValue method sets the new path. A potential pitfall includes inadvertently expanding the environment variables during this process, which could lead to incorrect path resolution .

The WinPSModulePath is significant as it ensures that modules specific to PowerShell 7 do not interfere with Windows PowerShell operations. It is used when starting Windows PowerShell from PowerShell 7. During this process, the PS7-specific paths such as the User, System, and PSHome module paths are removed from the path inherited by Windows PowerShell. This separation helps maintain compatibility and prevents loading of incompatible modules across different PowerShell versions .

PowerShell 7 combines the User-scoped PSModulePath with the System-scoped PSModulePath, similar to how the Path environment variable is handled on Windows. This differs from Windows PowerShell, where the User-scoped variable overrides the System-scoped variable if it exists. Additionally, PowerShell 7 prefixes its specific paths during startup, which means that modules specific to PowerShell 7 are not loaded when starting Windows PowerShell because the PS7 paths are removed from the WinPSModulePath .

On a Windows system, PowerShell searches for modules in different paths depending on whether they are user-installed or system-wide installations. System-wide modules are stored in the $PSHOME\Modules folder and, if installed for all users, in $env:ProgramFiles\WindowsPowerShell\Modules. User-installed modules are typically stored in the $HOME\Documents\WindowsPowerShell\Modules folder. The location of the Documents folder can vary by Windows version and configurations like folder redirection or OneDrive integration .

PowerShell distinguishes between user-scoped and system-scoped PSModulePath handling. If the user-scoped PSModulePath is present, it is usually prioritized over the system-scoped version. The powershell.config.json file allows further customization: if it contains a user-scoped PSModulePath entry, that value supersedes the default for the user. Similarly, a system-scoped PSModulePath in the file takes precedence over the system default. This allows for granular control over module path configuration on a per-user or system-wide basis .

To modify the PSModulePath in a non-Windows PowerShell environment so a new directory is included for module discovery, you can temporarily add a directory for the current session using the $Env:PSModulePath variable. For persistent changes across all sessions, it's necessary to add the desired path modification to the PowerShell profile script. Unlike on Windows, in non-Windows systems, the paths are separated by colons rather than semi-colons. It is important to ensure that the new path does not conflict with existing paths and is correctly formatted to be recognized by PowerShell's module discovery process .

PowerShell uses a recursive search pattern in the directories specified in the PSModulePath to locate module files, which allows multiple versions of the same module to be installed in different folders. By default, PowerShell loads the module with the highest version number when multiple versions are found. To explicitly load a specific version, the Import-Module command with the FullyQualifiedName parameter can be used. This behavior ensures that updated modules are prioritized unless specified otherwise, facilitating effective version management in complex environments .

You might also like