本章主要探討 PowerShell 的模塊化,因爲 PowerShell Core 現版本下已經移植的模塊較少以及存在大量強依賴於平臺的功能(例如 Hyper-V 相應的管理模塊),此處主要依照 Windows PowerShell 實現:linux
Get-Module
啓動一個 mcr.microsoft.com/powershell:centos-7
官方容器能夠發現其默認的引入了三個模塊,即:shell
Microsoft.PowerShell.Management
和 Microsoft.PowerShell.Utility
,用於提供 PowerShell 基本語法實現Script
模塊用於提供 PowerShell 具體的運行環境PS /> $PSVersionTable.OS Linux 4.9.93-linuxkit-aufs #1 SMP Wed Jun 6 16:55:56 UTC 2018 PS /> Get-Module ModuleType Version Name ExportedCommands ---------- ------- ---- ---------------- Manifest 6.1.0.0 Microsoft.PowerShell.Management {Add-Content, Clear-Content, Clear-Item, Clear-ItemPropert... Manifest 6.1.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object...} Script 2.0.0 PSReadLine {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PS...
同時能夠經過爲 Get-Module
附加參數 -ListAvailable
以列出可用的 Module,從現版本看有 10 個:centos
PS /> (Get-Module -ListAvailable).Length 10
反觀 Windows 10 Build 17134 上 PowerShell 所擁有的 Module,有 85 個之多:模塊化
PS C:\Users\chuny> $PSVersionTable.BuildVersion.Major 10 PS C:\Users\chuny> (Get-Module -ListAvailable).Length 85
但這個問題能夠辯證的看,雖然 macOS / Linux 平臺上的 PowerShell Core 只擁有少的可憐的基本模塊,但得益於 GNU 計劃的原生 CLI 工具,實際上並不輸 Windows,仍然拿 Hyper-V 模塊舉例,微軟經過提供 PowerShell Hyper-V Module 使能其基於 CLI 的管理功能,開源世界的競品 QEMU/KVM 等,均經過提供相應的二進制以進行管理,所以 PowerShell Core 在此時只是純粹的「命令行膠水」,但這不影響其「與原生功能構成平臺」的能力。工具
以基礎模塊 Microsoft.PowerShell.Utility
爲例,全部模塊均以 .psd1
的 PowerShell 字典格式存儲於文件中,而運行時會根據平臺鏈接到對應的 .Net 實例中:學習
# Windows PS C:\Users\chuny> (Get-Module -Name Microsoft.PowerShell.Utility).Path C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1 # Linux PS /> (Get-Module -Name Microsoft.PowerShell.Utility).Path /opt/microsoft/powershell/6/Modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 # 該字典指向以下遞歸模塊 PS /opt/microsoft/powershell/6> cat /opt/microsoft/powershell/6/Modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 | grep NestedModules NestedModules="Microsoft.PowerShell.Commands.Utility.dll","Microsoft.PowerShell.Utility.psm1" # 廬山真面目,便是這個 DLL PS /opt/microsoft/powershell/6> Get-Item ./Microsoft.PowerShell.Commands.Utility.dll Directory: /opt/microsoft/powershell/6 Mode LastWriteTime Length Name ---- ------------- ------ ---- ------ 9/10/18 8:30 PM 1718784 Microsoft.PowerShell.Commands.Utility.dll
Import/Remove-Module
經過 Get-Command
找到 Microsoft.PowerShell.Core
即 PowerShell Core 對於 Module 一共提供了 4 個 cmdlet,除去用於新建模塊的 Add-Module
和上節中的 getter 方法,剩下兩個即是加載與卸載:ui
PS C:\Users\chuny> Get-Command -Noun Module | Where-Object {$_.Source.ToString() -eq "Microsoft.PowerShell.Core"} CommandType Name Version Source ----------- ---- ------- ------ Cmdlet Get-Module 3.0.0.0 Microsoft.PowerShell.Core Cmdlet Import-Module 3.0.0.0 Microsoft.PowerShell.Core Cmdlet New-Module 3.0.0.0 Microsoft.PowerShell.Core Cmdlet Remove-Module 3.0.0.0 Microsoft.PowerShell.Core
以常見的 TroubleshootingPack
即錯誤調試工具包模塊爲例(很遺憾,截至當前 PowerShell Core 還未包含統一的跨平臺,且因爲 Linux 的崩潰沒有一個統一且良好的收集體系,用戶態崩潰信息分散且通常不會觸發 coredump,所以也很難給出這樣的統一排錯工具包):命令行
# Windows PowerShell PS C:\Users\chuny> (Get-Module).Name.Contains("TroubleshootingPack") False # 加載模塊 PS C:\Users\chuny> Import-Module TroubleshootingPack PS C:\Users\chuny> (Get-Module).Name.Contains("TroubleshootingPack") True # 該模塊共提供了兩個 cmdlet PS C:\Users\chuny> (Get-Module -Name TroubleshootingPack).ExportedCmdlets Key Value --- ----- Get-TroubleshootingPack Get-TroubleshootingPack Invoke-TroubleshootingPack Invoke-TroubleshootingPack PS C:\Users\chuny> (Get-TroubleshootingPack -Path "C:\Windows\diagnostics\system\Apps").RootCauses Name ---- 你已使用臨時配置文件登陸 用戶賬戶控制已禁用 須要 Microsoft 賬戶 臨時 Internet 文件位置已更改 懸掛或崩潰的應用
卸載模塊即爲反操做:調試
PS C:\Users\chuny> Remove-Module -Name TroubleshootingPack PS C:\Users\chuny> (Get-Module).Name.Contains("TroubleshootingPack") False
實際上,當一個模塊還未被引入,直接調用其內部的 cmdlet 時,PowerShell 將完成自動引入的過程,但在腳本製做時應嚴格禁止這樣的默認引入,以免可能的命名衝突,並在引用前檢查目標模塊是否能夠被引用成功。code