PowerShell 7 Module Path Overview
PowerShell 7 Module Path Overview
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 .