- WMI 和 PowerShell 的 CIM cmdlet 可以讓你有效率地查詢和修改本機和遠端管理資訊。
- 使用 WSMan 或 DCOM 的 CimSession 可以安全相容地存取現代和傳統網路設備。
- 進階函數、模組、作業和 DSC 的使用使 PowerShell 成為完整的基礎架構自動化語言。
- PowerShell 將本機、遠端、Azure 和 Microsoft 365 管理整合到一個環境中,從而減少了重複的手動任務。
如果你從事 Windows 系統管理工作,遲早會接觸到PowerShell、WMI 和進階自動化。這不僅僅是知道如何運行幾個命令的問題:當你管理幾十台甚至幾百台伺服器時,你需要一種嚴謹、結構化且安全的方法來收集資訊、應用更改和重複執行任務,而不會崩潰……或破壞任何東西。
接下來,我們將以冷靜而全面的方式探討如何利用WMI、CIM 和 PowerShell 遠端通訊來實現從簡單查詢到複雜基礎架構場景的自動化。我們還將了解所有這些如何與模組、後台任務、Azure、Microsoft 365 以及一些能夠真正提升系統管理員日常工作的高級功能相結合。
PowerShell 增強功能和進階自動化概述
Windows PowerShell 自早期版本以來已經發生了巨大的變化,其中很大一部分變化發生在 Windows Server 2012 中,遠端通訊得到了改進,可用的 cmdlet 得到了擴展,調試、後台作業和受限端點等功能也變得更加容易,從而提高了安全性。
這個環境的核心理念之一是,管理員無需編寫大量程式碼即可建立類似 cmdlet 的行為,這得益於其高級功能、可重複使用模組和全面的幫助系統。這意味著,您無需依賴分散的圖形工具,即可建立一套連貫的腳本和模組,從而自動執行伺服器、網路、Active Directory、Azure 或 Microsoft 365 的管理流程。
在進階自動化領域,諸如非同步執行任務的作業、工作流程、基於配置的 PowerShell DSC 管理以及 JEA(Just Enough Administration,恰好足夠管理)或 PowerShell Web Access 等安全選項等功能也很突出,從而可以詳細控制每個人可以做什麼以及從哪裡可以做。
整個生態系統與 WMI 和 CIM 特別契合,因為作業系統公開的管理資訊(硬體、服務、進程、網路配置、已安裝的軟體等)變成了一組對象,您可以使用專為批量自動化設計的 PowerShell 命令來查詢、篩選和修改這些對象。
WMI 和 CIM:關鍵概念和實際區別
Windows 管理規格(Windows Management Instrumentation,簡稱WMI)是一種獨立於 PowerShell 的技術,多年來一直是 Windows 系統的一部分。它公開了一個包含作業系統、硬體和眾多應用程式管理資訊的儲存庫。雖然 WMI 本身並不依賴 PowerShell,但 PowerShell 卻廣泛利用 WMI 來實現任務自動化。
PowerShell 生態系中 WMI 的自然繼承者是CIM(通用資訊模型)cmdlet,它是在 PowerShell 3.0 中引入的。這些 cmdlet 被分組在 CimCmdlets 模組中,其中包括 Get-CimInstance、Get-CimClass、New-CimInstance、Invoke-CimMethod、Register-CimIndicationEvent、Set-CimInstance 和 Remove-CimInstance 等指令。
在舊版的 Windows PowerShell 中,例如 Windows 10 PowerShell 5.1 或 Windows 11 PowerShell,您仍然可以找到經典的 WMI cmdlet(Get-WmiObject、Invoke-WmiMethod、Register-WmiEvent、Remove-WmiObject 和 Set-WmiInstance)。但是,這些 cmdlet 已被棄用,不再包含在 PowerShell 6 及更高版本中,因此它們僅對維護舊腳本或審查舊程式碼有用。
當有人談到「使用 CIM cmdlet 查詢 WMI」時,這並不矛盾:CIM cmdlet 仍然可以存取 WMI 訊息,但它們使用的是更現代的協定(例如 WSMan)和更一致的 API。實際上,對於新開發項目,您應該專注於 CIM,只有在需要遷移或理解舊腳本時才考慮使用 WMI cmdlet。
過去,許多管理員使用 VBScript 和 WQL 查詢語言來查詢 WMI,例如,連接到root\CIMV2命名空間並查詢 Win32_BIOS 等類別。如今,只需傳遞 -Query 參數,即可使用 Get-CimInstance 重複使用相同的 WQL 查詢,這大大簡化了從 VBScript 到 PowerShell 的過渡,而無需從頭開始重寫邏輯。
Get-CimInstance 的實際應用和高效查詢
對於日常工作,使用 PowerShell 查詢 WMI 最自然的方式是使用帶有 -ClassName 參數的 Get-CimInstance 命令,而不是編寫完整的 WQL 查詢。例如,要取得 BIOS 訊息,可以使用 Get-CimInstance -ClassName Win32_BIOS,即可取得一個包含 Manufacturer、Name、SerialNumber 或 SMBIOSBIOSVersion 等屬性的物件。
由於 PowerShell 中一切皆對象,因此很容易篩選並選擇所需內容。如果您只對序號感興趣,可以將結果透過管道傳遞給 `Select-Object -Property SerialNumber`,或使用 `Select-Object -ExpandProperty SerialNumber` 輸出一個簡單的字串,而不是包含該屬性的物件。另一種常用的方法是使用點語法(`Get-CimInstance ...`).SerialNumber`)直接存取該值。
值得注意的是,預設情況下,WMI 查詢傳回的屬性數量會比實際需要的數量要多。在本機上,這通常沒什麼問題,但當需要查詢大量遠端電腦時,就會增加處理時間和不必要的網路流量。這時,`Get-CimInstance` 指令的 `-Property` 參數就派上了用場,它允許您限制從來源檢索哪些屬性。
例如,透過指定 `-Property SerialNumber` 參數,可以減少資料傳輸量,從而加快查詢速度,提高查詢效率,尤其是在大規模應用時。這種「只請求所需資料」的概念在設計運行於數十台甚至數百台機器上的庫存或審計腳本時至關重要。
總而言之,無論您是處理特定類別、舊版 WQL 查詢,還是要優化檢索的特定屬性, Get-CimInstance 都能在簡單性(一條命令列)和靈活性之間取得強大的平衡。
使用 CIM、會話和 WSMan/DCOM 協定進行遠端諮詢
當你離開本機電腦並開始存取遠端電腦時,權限、通訊協定和效能等多個因素都會影響結果。雖然許多人認為 PowerShell “危險”,但事實是它不會賦予你任何額外的權限:你擁有的權限與使用圖形介面或其他任何工具時完全相同,不多也不少。
如果您嘗試在權限不足的情況下執行 `Get-CimInstance -ComputerName Server -ClassName Win32_BIOS` 指令,將會收到「拒絕存取」錯誤。這並非 PowerShell 本身出現故障,而是因為您目前正在執行會話的使用者沒有存取 WMI 中該資訊的權限。當然,您可以以網域管理員身分開啟控制台,但這會導致所有命令都以該權限執行,這在許多環境中都是不必要的風險。
建議遵循最小權限原則,僅在必要時提升權限。在支援 `-Credential` 參數的 cmdlet 中,您可以僅為相關指令指定備用憑證。然而,`Get-CimInstance` 並沒有直接接受 `-Credential` 參數,而 `CimSessions` 則提供了一個優雅的解決方案。
CimSession 是與遠端電腦建立的持久連接,您可以使用 `New-CimSession` 命令建立該連接,並傳遞電腦名稱和憑證(例如,`New-CimSession -ComputerName dc01 -Credential (Get-Credential)`)。此會話儲存在一個變數中,例如`$CimSession`,然後可以透過使用 `Get-CimInstance` 命令的 `-CimSession` 參數而不是 `-ComputerName` 參數來重複使用該會話,從而允許您將多個查詢合併到單一連線中。
除了憑證要求外,Get-CimInstance 預設使用WSMan 協定(基於 WinRM)。這表示遠端電腦必須具有 WSMan 堆疊版本 3.0 或更高版本,通常 PowerShell 3.0 及更高版本都包含此版本。您可以使用 `Test-WSMan -ComputerName RemoteComputer` 指令檢查電腦上的 WSMan 堆疊版本,並驗證「Stack」值是否為 3.0 或更高才能使用此連線方法。
CIM 會話與 DCOM 和向後相容性
基於 Get-WmiObject 的舊版 WMI cmdlet 依賴DCOM 協議,而舊版 Windows 仍然支援該協議。問題在於,在較新的系統中,防火牆通常會預設阻止 DCOM,因此需要手動開啟特定連接埠才能正常使用,這可能會違反組織的安全性策略。
CIM cmdlet 提供了一個強大的折衷方案:您可以使用`New-CimSessionOption -Protocol Dcom`建立會話選項,將其儲存到變數(例如 `$DCOM`)中,然後使用 `New-CimSession` 將它們組合起來,產生一個使用 DCOM 而不是 ManWS 的 CimSession。這讓您可以連接到非常老舊的伺服器,甚至是早於 Windows Server 2000 的伺服器,這些伺服器甚至沒有安裝 PowerShell。
通常情況下,將網域管理員憑證或提升權限帳戶的憑證儲存在變數中(例如,`$Cred = Get-Credential`)會很方便,這樣就不需要每次都輸入。然後,使用類似 `New-CimSession -ComputerName sql03 -SessionOption $DCOM -Credential $Cred` 的命令,可以透過 DCOM 啟動與不支援 WSMan 但支援 WMI 的舊伺服器之間的 CimSession。
從腳本編寫者的角度來看,主要優勢在於`Get-CimInstance` 的輸出不會因協定而異:無論使用 WSMan 或 DCOM,都能獲得相同的物件和屬性。這大大簡化了邏輯,因為可以將對對應協議的檢測封裝在一個函數中,讓其餘程式碼始終透明地處理 CimSession。
事實上,建立自訂函數來測試 WSMan(使用 Test-WSMan),並在 WSMan 不可用時自動使用 New-CimSessionOption 切換到 DCOM,這種做法非常常見。這樣,您就可以在包含現代伺服器和傳統伺服器的混合環境中標準化 CimSession 的創建,而無需在所有腳本中重複編寫連接邏輯。
CimSessions 的管理、清單和清理
當您開始大量使用 CimSession 時,請務必追蹤它們,以避免建立不必要的連線。使用Get-CimSession 命令,您可以列出所有開啟的會話,查看它們指向的計算機,以及它們使用的協定(WSMAN 或 DCOM),這對於診斷連線或驗證問題非常有用。
您也可以將這些現有會話檢索到一個變數中,例如$CimSession = Get-CimSession,並在單一命令 Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS 中使用這些會話,以便一次查詢多台電腦,並將 WSMan 和 DCOM 會話合併到同一作業中。
分析完這些資訊後,最好關閉會話,以免不必要的資源佔用。 Get -CimSession | Remove-CimSession cmdlet可以一次從目前設定檔中刪除所有活動的 CimSession。或者,您也可以將特定會話傳遞給 Remove-CimSession cmdlet,以便僅關閉其中的一部分。
這種方式可以讓你控制連接和斷開連接的週期,強烈建議在規劃任務、自動化運行手冊或持續整合管道中使用腳本,因為如果不明確規劃清理工作,可能會導致會話掛起。
PowerShell 作為一種全面的自動化語言
除了 WMI 和 CIM 之外,PowerShell 已發展成為一種通用的自動化語言,其功能遠遠超出了典型的 Windows 管理腳本。市面上有許多書籍和課程專門介紹其高級功能,涵蓋了從在 Linux 和 Windows 上安裝 PowerShell,到透過 NuGet 開發可分發模組,甚至包括 Visual Studio Code 等現代開發環境等方方面面。
通常,入門的關鍵在於深入理解PowerShell 的高級功能,這些功能可讓您定義參數、執行驗證、產生結構化輸出,並像使用原生 cmdlet 一樣存取整合幫助。在此基礎上,將程式碼組織成模組有助於維運團隊的協作,因為您可以對這些模組進行版本控制,並將其發佈到內部或公共的基於 NuGet 的儲存庫中。
使用自訂物件和類別也至關重要,這為建立比傳統線性腳本更豐富的資料模型打開了大門。這使您可以封裝業務邏輯、重複使用結構,並為您的管理團隊設計內部 API,所有這些都由 PowerShell 引擎提供支援。
在高階自動化領域,後台作業和工作流程發揮著至關重要的作用,它們能夠管理非同步任務、在不阻塞控制台的情況下執行耗時較長的操作,以及協調跨多台機器的複雜序列。這些功能非常適合對 WMI/CIM 進行批次查詢和遠端管理場景,在這些場景中,通常需要等待系統完成變更或傳回資料。
另一個關鍵元件是 PowerShell DSC(期望狀態配置),它允許您定義基礎架構(角色、功能、服務、檔案、安全設定等)的期望配置,並重複套用這些狀態。結合透過 WMI/CIM 獲取的信息,您可以檢測偏差、主動糾正偏差,並以更少的人工幹預維護一致的環境。
使用 PowerShell 進行本地、遠端和雲端管理
在本機層面,PowerShell 提供了用於管理 Active Directory 網域服務、設定網路和管理伺服器的 cmdlet。在 Windows 10 及更高版本中,這種整合更加深入,使您能夠自動執行從建立網站到管理 Active Directory 物件和設定網路介面卡的所有操作。
PSProviders 和 PSDrives是兩個鮮為人知但非常有用的元件,它們允許您將不同的儲存位置(檔案系統、註冊表、Active Directory 等)視為可導航的磁碟機。因此,您可以使用與瀏覽硬碟相同的語法,在遠端電腦上建立 Active Directory 群組、註冊表項或資料夾結構。
在遠端管理方面,PowerShell 整合了一套強大的功能,可以連接到一台或多台電腦並代表您執行命令。您可以使用持久的 PSSession 會話、進階遠端處理技術、一對多場景(同時管理多台伺服器)或一對一場景(用於偵錯特定案例)。當然,所有這些都必須遵循遠端存取的架構和安全模型。
如今,雲端運算也扮演著至關重要的角色。透過Azure PowerShell 和 Azure Cloud Shell,您可以直接從命令列管理虛擬機器、儲存和訂閱。如果您管理混合式環境或完全託管在 Azure 上的環境,安裝 Azure PowerShell 模組並熟悉它們幾乎是必不可少的。
另一方面,PowerShell 也已成為管理 Microsoft 365(包括 Exchange Online、SharePoint Online、Teams、使用者和授權)的首選工具。從建立和管理帳戶到管理 Exchange Online 資源(包括群組、SharePoint 網站和 Microsoft Teams),所有操作都可以透過腳本進行協調,從而大幅減少 Web 入口網站上的手動工作。
腳本編寫、流程和最佳實踐
要充分利用 WMI 和 CIM 的高階自動化功能,掌握PowerShell 的管道模型至關重要。與其他 shell 不同,PowerShell 傳遞的不是純文本,而是完整的對象,這使您可以非常精確地選擇、排序、測量、篩選、枚舉和轉換資訊。
學習使用管道需要正確使用選擇和篩選 cmdlet,理解如何列舉複雜對象,以及如何在命令和腳本之間傳遞資料而不丟失資訊。有條不紊地使用變數、陣列和雜湊表可以強化這些技能,它們充當臨時資料結構,用於建立更高級的邏輯。
下一步是編寫腳本:將命令打包成可重複使用的腳本,並新增流程控制(if、for、foreach)、從 CSV 檔案或其他格式匯入資料、處理使用者輸入、錯誤處理和事件日誌記錄等功能。所有這些都使您能夠從孤立的命令過渡到更強大、更內建的工具。
在採用 WMI/CIM 的大規模自動化環境中,故障排除和錯誤處理尤其重要,因為網路中斷、權限配置錯誤或類別缺失等問題都可能導致流程中斷,除非進行妥善管理。借助 try/catch 區塊、可設定的錯誤操作和詳細的日誌記錄,您可以更有效地預測和應對這些情況。
最後,所有與函數和模組相關的工作都構成了一個完整的閉環:您對腳本進行簽名以確保其完整性,將函數打包成模組,將這些模組分發到內部或公共存儲庫中,並在組織內部創建一個共享工俱生態系統。這樣,任何關於 WMI、CIM 或遠端處理的新開發都能整合到一個連貫且易於維護的套件中。
將上述所有技術——WMI/CIM、遠端會話、腳本、非同步作業、DSC、Azure 和 Microsoft 365——結合起來,便可建立以 PowerShell 高階自動化為核心的管理環境。憑藉紮實的最佳實踐基礎、對 CimSessions(包括 WSMan 和 DCOM)的巧妙運用以及模組化的腳本設計,您可以比僅僅依賴圖形嚮導或獨立工具更有效率、更安全地管理異質基礎架構。


