简短说明
本文介绍 $env:PSModulePath 环境变量的用途和用法。
长说明
$env:PSModulePath 环境变量包含搜索以查找模块和资源的文件夹位置的列表。 PowerShell 以递归方式搜索每个文件夹的模块(.psd1 或 .psm1)文件。
Install-Module 具有 Scope 参数,可用于指定是为当前用户还是所有用户安装模块。 有关详细信息,请参阅 Install-Module。
默认情况下,分配给 $env:PSModulePath 的有效位置为:
系统范围的位置:这些文件夹包含 PowerShell 附带的模块。 这些模块存储在
$PSHOME\Modules文件夹中。- 在 Windows 上,安装在 AllUsers 范围内的模块存储在
$env:ProgramFiles\WindowsPowerShell\Modules中。 - 在非 Windows 系统上,安装在 AllUsers 作用域中的模块存储在
/usr/local/share/powershell/Modules中。
- 在 Windows 上,安装在 AllUsers 范围内的模块存储在
用户安装的模块:在 Windows 上,安装在 CurrentUser 范围内的模块通常存储在
$HOME\Documents\WindowsPowerShell\Modules文件夹中。Documents文件夹的特定位置因 Windows 版本和使用文件夹重定向而异。 此外,Microsoft OneDrive 可以更改Documents文件夹的位置。 您可以使用以下命令验证文件夹的位置Documents:[Environment]::GetFolderPath('MyDocuments')。在非 Windows 系统上,安装在 CurrentUser 范围内的模块存储在
$HOME/.local/share/powershell/Modules该文件夹中。特定于应用程序的模块:安装程序可以将模块安装在其他目录中,例如
Program FilesWindows 上的文件夹。 安装程序包可能会也可能不会将位置$env:PSModulePath附加到 .
PowerShell PSModulePath 构造
每次启动 PowerShell 时,都会构造 $env:PSModulePath 的值。
该值因 PowerShell 版本及其启动方式而异。
Windows PowerShell 启动
在启动时,Windows PowerShell 使用以下逻辑构造 PSModulePath:
- 如果
PSModulePath不存在,请合并 CurrentUser、AllUsers和$PSHOME模块路径 - 如果
PSModulePath存在:- 如果
PSModulePath包含$PSHOME模块路径:-
AllUsers 模块路径插入到
$PSHOME模块路径之前
-
AllUsers 模块路径插入到
- 还:
- 按照定义,只需使用
PSModulePath,因为用户故意删除了$PSHOME位置。
- 按照定义,只需使用
- 如果
仅当用户范围 不存在时,$env:PSModulePath 模块路径才具有前缀。 否则,将按定义使用 User 范围 $env:PSModulePath。
PowerShell 7 启动
在 Windows 中,对于大多数环境变量,如果存在用户范围的变量,则新进程仅使用该值,即使存在同名的计算机范围的变量也是如此。
在 PowerShell 7 中, PSModulePath 其处理方式与在 Windows 上处理环境变量的方式 Path 类似。 在 Windows 上, Path 的处理方式与其他环境变量不同。 当启动进程时,Windows 会将用户范围的 Path 与计算机范围的 Path组合在一起。
- 检索用户范围的
PSModulePath - 与进程继承的
PSModulePath环境变量进行比较- 如果相同:
- 请根据 环境变量的语义,将
PSModulePathPath追加到末尾。 - Windows
System32路径来自定义的PSModulePath计算机,因此不需要显式添加
- 请根据 环境变量的语义,将
- 如果两者不同,则可以认为用户显式修改了它,不要追加 AllUsers
PSModulePath
- 如果相同:
- 按该顺序以 PS7 用户、系统和
$PSHOME路径为前缀- 如果
powershell.config.json包含用户范围的PSModulePath,请使用该路径,而不是用户的默认路径 - 如果
powershell.config.json包含系统范围的PSModulePath,请使用该路径,而不是系统的默认路径
- 如果
Unix 系统没有用户和系统环境变量的分离。
PSModulePath 是继承的,如果尚未定义,则特定于 PS7 的路径会带有前缀。
从 PowerShell 7 启动 Windows PowerShell
对于此讨论,Windows PowerShell 意味着 powershell.exe 和 powershell_ise.exe。
将 $env:PSModulePath 的值复制到 WinPSModulePath,并进行以下修改:
- 删除 PS7 用户模块路径
- 删除 PS7 系统模块路径
- 删除 PS7 的
$PSHOME模块路径
删除 PS7 路径,以便 PS7 模块不会在 Windows PowerShell 中加载。 启动 Windows PowerShell 时,将使用 WinPSModulePath 值。
从 Windows PowerShell 启动 PowerShell 7
PowerShell 7 启动按原样继续,添加了 Windows PowerShell 所添加的继承路径。 由于 PS7 特定路径具有前缀,因此没有功能问题。
模块搜索行为
PowerShell 以递归方式在 PSModulePath 中搜索模块(.psd1 或 .psm1)文件中的每个文件夹。 此搜索模式允许将同一模块的多个版本安装在不同的文件夹中。 例如:
Directory: C:\Program Files\WindowsPowerShell\Modules\PowerShellGet
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 8/14/2020 5:56 PM 1.0.0.1
d---- 9/13/2019 3:53 PM 2.1.2
默认情况下,当找到多个版本时,PowerShell 会加载模块的最高版本号。 若要加载特定版本,请将 Import-Module 与 FullyQualifiedName 参数结合使用。 有关详细信息,请参阅 Import-Module。
修改 PSModulePath
在大多数情况下,应在默认模块位置安装模块。 但是,您可能需要更改环境变量的值 PSModulePath 。
例如,若要在当前会话中暂时将 C:\Program Files\Fabrikam\Modules 目录添加到 $env:PSModulePath,请键入:
$Env:PSModulePath = $Env:PSModulePath+";C:\Program Files\Fabrikam\Modules"
命令中的分号(;)将新路径与列表中前面的路径分隔开来。 在非 Windows 平台上,冒号(:)分隔环境变量中的路径位置。
在非 Windows 中修改 PSModulePath
若要更改非 Windows 环境中每个会话 PSModulePath 的值,请将上一个命令添加到 PowerShell 配置文件。
在 Windows 中修改 PSModulePath
若要更改每个会话中 PSModulePath 的值,请编辑存储 PSModulePath 值的注册表项。
PSModulePath 值作为 未展开 字符串存储在注册表中。 若要避免将 PSModulePath 值永久保存为 扩展 字符串,请对子项使用 GetValue 方法并直接编辑值。
以下示例将 path 添加到 C:\Program Files\Fabrikam\Modules 环境变量的值 PSModulePath ,而不扩展未展开的字符串。
$key = (Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager').OpenSubKey('Environment', $true)
$path = $key.GetValue('PSModulePath','','DoNotExpandEnvironmentNames')
$path += ';%ProgramFiles%\Fabrikam\Modules'
$key.SetValue('PSModulePath',$path,[Microsoft.Win32.RegistryValueKind]::ExpandString)
要向用户设置添加路径,请将注册表提供程序从 HKLM:\ 更改为 HKCU:\。
$key = (Get-Item 'HKCU:\').OpenSubKey('Environment', $true)
$path = $key.GetValue('PSModulePath','','DoNotExpandEnvironmentNames')
$path += ';%ProgramFiles%\Fabrikam\Modules'
$key.SetValue('PSModulePath',$path,[Microsoft.Win32.RegistryValueKind]::ExpandString)