這是我開始寫 PowerShell 模組時常遇到的問題,迷惑了一陣子才恍然大悟。問題主要發生在模組開發者身上,情境是對模組改版重新 Publish,升級或重新安裝模組測試,有時能正確更新,有時卻一直用到舊版,有時還會誤以為沒修好,白繞一大圈。

例如之前文章的例子:Repository 上已經有 1.1.0 版,Update-Module 後再檢查,版本還是 1.0.0,加上 -Verbose 再 Update-Module 一次,告知已經安裝過了。但看到的明明是 1.0.0 呀!

再來一個當初讓我超迷惑的案例。先前研究出快速打包發行 PS 模組的流程,我曾嘗試先發行 1.0.0 版(其中加了一個 Test-PSModDemoVersion 用來區別版號:

function Test-PSModDemoVersion {
    return "V1.1.0"
}

發行後安裝,執行 Test-PSModDemoVersion 如預期得到 V1.0.0。接著修改 Test-PSModDemoVersion 改回傳 V1.1.0,修改 psd1 ModuleVersion = "1.1.0" 後再發行 1.1.0 版,然後 Uninstall-Modoule,再重新 Install-Module,心想這樣總會換成 1.1.0 了吧?結果 Test-PSModDemoVersion 傳回的仍是 V1.0.0。鬼打牆了一陣子,才搞懂是自己觀念不清誤解了模組安裝與匯入(Import-Module)。

模組安裝與模組載入是兩項獨立作業,安裝是指將 nupkg 下載解壓縮到 C:\Users\UserName\Documents\WindowsPowerShell\Modules (-Scope CurrentUser) 或 C:\Program Files\WindowsPowerShell\Modules 的過程,而載入是指將模組載入到目前工作階段的過程。繼續上面的範例,剛才 Unintall-Module 1.0.0 再 Install-Module 1.1.0,之後連續 Uninstall-Module 兩次到系統回傳已沒有 PSModeDemo 可以移除,Test-PSModDemoVersion 依然可用,它是先前被載入工作階段的 1.0.0 版:

最後,回到前面的 Update-Module 無效問題,一樣也是安裝與載入觀念混淆才造成問題。Install-Module 後我雖然沒有使用該模組,但 Get-Module -Name PSModDemo 也會載入 1.0.0 PSModDemo 模組,此時 Update-Module PSModDemo 其實有安裝並加入 1.1.0 (注意:Update-Module 時會新舊版本並存),但再次執行 Get-Module -Name PSModDemo 看到仍是剛才已經載入的 1.0.0,讓我誤以為沒更新再執行一次 Update-Module,得到 Skipping installed module 訊息。

以下實驗用 Get-Command -ListImported 可觀察已匯入的模組,證明執行 Get-Module -Name PSModDemo 後 PSModDemo 即出現在匯入模組。

搞懂這層關聯,對於之間有時會更新有時不會我有了答案(要看更新前有沒有匯入舊版),也才知道另開一個 PowerShell 視窗測試比較準確小技巧的原理(另開的工作階段一定沒有匯入舊版模組),未來遇到要同一工作階段測試多個版本的場合,下個 Remove-Module 或是 Import-Module -Force 就不再會被版本弄到昏頭轉向。

The loaded PowerShell module will not be updated after Install-Module and how to force update them.


Comments

# by Huang

和COM+與GAC有異曲同工之妙XD

Post a comment