簡短描述
本文說明 $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 模組路徑才會加上前置詞。 否則,會如定義使用用戶範圍 $env:PSModulePath。
PowerShell 7 啟動
在 Windows 中,對於大多數環境變數而言,如果用戶範圍變數存在,新進程只會使用該值,即使相同名稱的計算機範圍變數存在也一樣。
在 PowerShell 7 中, PSModulePath 其處理方式與在 Windows 上處理環境變數的方式 Path 類似。 在 Windows 上, Path 的處理方式與其他環境變數不同。 啟動程式時,Windows 會將用戶範圍 Path 與計算機範圍 Path結合。
- 擷取用戶範圍
PSModulePath - 與進程繼承
PSModulePath環境變數比較- 如果相同:
- 將 AllUsers
PSModulePath附加至Path環境變數語意之後的結尾 - Windows
System32路徑來自定義的PSModulePath計算機,因此不需要顯式添加
- 將 AllUsers
- 如果不同,請將使用者視為明確修改它,且不要附加 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 系統模組路徑
- 拿掉
$PSHOME模組路徑的 PS7
會移除 PS7 路徑,讓 PS7 模組不會在 Windows PowerShell 中載入。 啟動 Windows PowerShell 時會使用 WinPSModulePath 值。
從 Windows PowerShell 啟動 PowerShell 7
PowerShell 7 啟動會繼續 as-is,並新增 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)