PowerShell 學習筆記 - 2 PS Module

PowerShell 學習筆記 - 2 PS Module

本章主要探討 PowerShell 的模塊化,因爲 PowerShell Core 現版本下已經移植的模塊較少以及存在大量強依賴於平臺的功能(例如 Hyper-V 相應的管理模塊),此處主要依照 Windows PowerShell 實現:linux

獲取模塊加載信息 Get-Module

啓動一個 mcr.microsoft.com/powershell:centos-7 官方容器能夠發現其默認的引入了三個模塊,即:shell

  • Microsoft.PowerShell.ManagementMicrosoft.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

相關文章
相關標籤/搜索