Windows PowerShell:封裝與散發自訂 Windows PowerShell 工具
您可以利用 Dot-source 功能實現一些有趣的功能,但如果您不夠謹慎,它也可能會帶來一些問題。
Don Jones
Dot-source 是一種巧妙的技巧,但如果您不再需要某些命令,或者如果您後來發現某些命令與其他內容衝突,卻很難刪除這些命令。 當我們在上個月將一個命令變為獨立的、參數化的可重用工具之後,我發現我們需要解決兩個問題。
我們將該工具構建為 Windows PowerShell 高級函數,有時也稱為“腳本 Cmdlet”。第一個問題是,腳本本身難以使用。 該腳本包含一個函數,因此如果只運行該腳本,不會發生任何事。 您要麼修改該腳本並添加用來運行該函數的命令,要麼通過 Dot-source 將該腳本轉移到 Shell 中,才能使該函數成為一個全域命令。
另一問題是,該腳本包含兩個函數。 第一個函數是 Get-OSInfo,是我希望使用者使用的函數。 第二個函數是 OSInfoWorker,它完成了所有實際的工作。 但是,我不希望使用者直接執行這個函數。 如果使用 Dot-source 方式,則沒有辦法隱藏 OSInfoWorker(或者按照程式師的說法,將它變為私有)。 將腳本轉變成腳本模組可解決這兩個問題。
瞭解模組
Windows PowerShell 支援三種基本的模組類型:二進位、腳本和清單模組。 二進位模組包含一個在 Visual Studio 中生成的 DLL,用於向 Shell 添加 Cmdlet、提供程式或其他元素。 腳本模組僅僅是指:單一的腳本,可向 Shell 添加一個或多個函數。 清單模組可真正包含多個元件,例如二進位擴展程式、腳本等等。 腳本模組最容易創建,因此我們選擇使用腳本模組。
腳本模組有三項要求:
- 它必須是有效的 Windows PowerShell 腳本,主要由要添加到 Shell 中的函陣列成。
- 它必須具有 .psm1 檔副檔名,而不是 .ps1 檔副檔名。
- 它必須位於電腦上的特定資料夾中
最後一條要求實際上不過是為方便起見而提供的一項建議。 在安裝時,Windows PowerShell 會定義一個新的系統級環境變數,名為 PSModulePath。 此環境變數的工作方式與系統的 Path 環境變數非常相似。 它包含 Shell 在按名稱查找模組時自動搜索的資料夾。
預設情況下,會定義兩個模組路徑。 其中一個位於 System32 資料夾層次結構下。 此路徑供 Microsoft 提供的模組使用。 另一個位於您的 Documents 資料夾中,供您自己的模組使用。 我們將使用這一個路徑。 當然,您可以在 PSModulePath 中修改或添加路徑,例如,定義您的團隊用來集中存儲共用模組的路徑。
我們使用的路徑是 \[My ]Documents\WindowsPowerShell\Modules。 在 Windows XP,此路徑為“My Documents”。 而在 Windows Vista 及更高版本中,此路徑僅為“Documents”。 預設情況下,WindowsPowerShell 資料夾不存在。 您必須自行創建。 預設情況下,Modules 子資料夾也不存在,因此您也需要自行創建。
如果不將您的模組放到某個 PSModulePath 位置中,則只需在載入模組時,指定完整的路徑和檔案名。 這種方式對於常用模組不是很方便,因此我傾向于將其放到 PSModulePath 中定義的路徑下。
構建模組
我將在上個月的腳本末尾加上三個命令(您可以在此下載修訂後的腳本):
New-Alias goi Get-OSInfo
Export-ModuleMember -function Get-OSInfo
Export-ModuleMember -alias goi
第一個命令定義一個別名“goi”。它用於我的 Get-OSInfo 函數。 其他兩個命令僅當您在腳本模組中使用它們時才會生效。
預設情況下,當您將一個模組導入 Shell 中時,將公開提供該模組中的每個函數。 但是當您使用 Export-ModuleMember 時,則只會公開提供那些明確命名的函數和別名。
我的“goi”別名以及 Get-OSInfo 函數就能由任何使用此模組的使用者使用。 而我未指定的函數 OSInfoWorker 將被隱藏。 您仍然可以在模組本身內部使用任何函數來調用 OSInfoWorker,但它不能直接在模組外使用,因為它是私有函數。
添加了這些命令後,我需要為該腳本指定適當的名稱並將其放到適當的位置。 我選擇將此模組命名為“MyModule”。因此,該指令檔的路徑應當為 \[My ]Documents\WindowsPowerShell\Modules\MyModule\MyModule.psm1。
該腳本必須放到 Modules 的子資料夾中。 子資料夾和指令檔本身的名稱都必須與模組名相同。 做完此操作後,我就可以運行 Import-Module MyModule 來載入我的模組。
這是向其他使用者分發腳本的一種簡單而又有效的方法。 我可以根據需要,在這一個檔中包含任意數量的函數和別名。 只要將其放到正確的位置(或者有人願意指定完整路徑),其他使用者就能輕鬆載入該模組,並使用這些函數。
Don Jones 是 Concentrated Technology 的創始人,他會在 ConcentratedTech.com 上解答有關 Windows PowerShell 和其他技術的問題。 他也是 Nexus.Realtimepublishers.com 的撰稿人,他的許多著作還在他的網站上以電子版的形式提供。
獲取更多內容
下載本月文章隨附的示例代碼。
註冊即將截止,請趕快註冊參加 Jones 親自主持的獨家動手體驗工作室,該工作室為期三天,與 TechMentor Spring 2011 在同一地點舉行。 有關詳情,請訪問 TechMentorEvents.com。