- WMI 和 CIM
- 瞭解 WMI 和 CIM
- CIM 和 WMI 結構
- CIM 和 WMI 中的存儲庫
- 命名空間
- 類
- 實例
- 查找文檔
- 實際案例
- 查詢配置信息
- 列出本地存儲庫命名空間和類
- 類名前綴的意義
- 查詢語言查詢實例
- 獲取實例
- 篩選實例(Filter)
- WQL(WMI Query Language)
- 連接到遠程計算機
- WMI 連接
- CIM 連接
- 查詢存儲庫類
- 創建會話對象
- 使用會話
- 配置會話選項
- 移除會話
- 查詢和操作存儲庫對象
- 發現存儲庫對象的方法
- 調用存儲庫對象的方法
- 直接調用
- 使用Invoke-WmiMethod
- 使用Invoke-CimMethod
- 瞭解 WMI 和 CIM
WMI 和 CIM
瞭解 WMI 和 CIM
CIM 和 WMI 結構
PowerShell
|
v
CIM Cmdlets (Get-CimInstance)
|
v
WMI Service (CIMOM, winmgmt)
|
v
Provider (Win32_Service, Win32_Process, etc.)
|
v
操作系統內核 / 硬件
什麼是 WMI 和 CIM?
- WMI (Windows Management Instrumentation)
- 微軟的實現,用來管理和監控 Windows 系統資源(進程、服務、網絡、硬件…)。
- 底層基於 CIM (Common Information Model) 標準。
- CIM (Common Information Model)
- 由 DMTF(分佈式管理任務組)制定的一個 國際標準。
- 它規定了“如何用統一的對象模型描述系統資源”。
- 換句話説,CIM 是“標準規範”,而 WMI 是“微軟的實現”。
可以把 CIM/WMI 架構想象成一個三層模型:
+---------------------+
| 管理應用 (PowerShell, MMC, 腳本) |
+---------------------+
| WMI / CIMOM (管理基礎層) |
+---------------------+
| Providers (提供者) |
+---------------------+
| 底層操作系統 / 硬件 / 服務 |
頂層:管理應用
- 這是你接觸到的層,例如:
- PowerShell (
Get-CimInstance,Get-WmiObject) - 圖形化工具(任務管理器、事件查看器)
- 第三方監控軟件(如 SCCM, Nagios 插件)
- PowerShell (
應用不會直接訪問硬件,而是通過 WMI/CIM API。
中間層:CIMOM / WMI 服務
- CIMOM (CIM Object Manager) 是核心管理引擎。
在 Windows 中就是 WMI 服務 (winmgmt)。 - 功能:
- 接收應用請求(查詢、修改)
- 調用正確的 Provider
- 返回對象化的數據
- 協議:
- WMI 早期 → 基於 DCOM(RPC)
- CIM 新架構 → 支持 WS-Man (Web Services Management)
底層:Providers(提供程序)
- Provider = “翻譯官”,把底層資源包裝成 CIM/WMI 對象。
- 每種資源有不同 Provider,例如:
- Win32_Process → 管理進程
- Win32_Service → 管理服務
- Win32_OperatingSystem → 獲取操作系統信息
當你運行如下命令:
Get-WmiObject Win32_Service
實際流程是:
- PowerShell 請求 CIMOM
- CIMOM 找到負責“服務”的 Provider
- Provider 向 Windows Service Control Manager (SCM) 取數據
- 數據包裝成對象返回給你
CIM 與 WMI 的關係
| 特性 | WMI (舊) | CIM (新) |
|---|---|---|
| 標準性 | 微軟私有實現 | DMTF 標準 |
| 通信 | DCOM/RPC | WS-Man (跨平台) |
| Cmdlet | Get-WmiObject (已過時) |
Get-CimInstance |
| 跨平台 | 僅限 Windows | 可用於 Linux/VMware/網絡設備 |
從 PowerShell 3.0 開始,微軟推薦 用 CIM cmdlet (
Get-CimInstance) 替代 WMI,因為它基於開放協議 WS-Man,能支持遠程和跨平台。
從 PowerShell 3.0 開始,微軟推薦 用 CIM cmdlet (Get-CimInstance) 替代 WMI,因為它基於開放協議 WS-Man,能支持遠程和跨平台。
示例:
# 獲取操作系統信息
Get-CimInstance -ClassName Win32_OperatingSystem
# 獲取所有服務
Get-CimInstance -ClassName Win32_Service
# 獲取進程
Get-CimInstance -ClassName Win32_Process | Select-Object Name, ProcessId
你看到的 Win32 類*,其實就是 Provider 暴露出來的 WMI 類,遵循 CIM 模型。
CIM 和 WMI 中的存儲庫
命名空間
查看命令
Get-CimInstance -Namespace root -ClassName __Namespace
返回的某些命名空間可能包括:
- subscription
- DEFAULT
- CIMV2
- msdtc
- Cli
- Intel_ME
- SECURITY
- HyperVCluster
- SecurityCenter2
- RSOP
- Intel
- PEH
- StandardCimv2
- WMI
- directory
- Policy
- virtualization
- Interop
- Hardware
- ServiceModel
- SecurityCenter
- Microsoft
- Appv
- dcim
類
- 實例 = 類的實際對象。
- 如果類是“模板”,實例就是“真實存在的那個”。
Win32_Process類 → 定義進程的屬性(名稱、PID、路徑…)- 實例 → 每一個正在運行的進程 (
notepad.exe,explorer.exe)
這些類是 Provider 暴露出來的
實例
- 實例 = 類的實際對象。
- 如果類是“模板”,實例就是“真實存在的那個”。
Win32_Process類 → 定義進程的屬性(名稱、PID、路徑…)- 實例 → 每一個正在運行的進程 (
notepad.exe,explorer.exe)
Get-CimInstance -ClassName Win32_Process | Select Name, ProcessId
輸出:
Name ProcessId
---- ---------
explorer.exe 1234
powershell.exe 5678
- 這裏
Win32_Process是類,而每一行就是它的實例。
查找文檔
列出所有可用的類(探索命名空間)
WMI 信息按"命名空間"組織,最常用的是 root\cimv2
# 列出 root\cimv2 命名空間下的所有類(會非常多!)
Get-CimClass -Namespace root\cimv2
# 更實用的方法:按關鍵詞過濾類名
Get-CimClass -ClassName "*Process*" -Namespace root\cimv2
Get-CimClass -ClassName "*Network*" -Namespace root\cimv2
Get-CimClass -ClassName "*User*" -Namespace root\cimv2
查看類的詳細定義(自我文檔化)
找到感興趣的類後,用 Get-CimClass 查看其詳細定義:
# 查看 Win32_Process 類的完整定義
$processClass = Get-CimClass -ClassName Win32_Process
# 查看這個類有哪些屬性(Properties)
$processClass.CimClassProperties | Select-Object Name, Type, Flags
# 查看這個類有哪些方法(Methods)- 這非常重要!
$processClass.CimClassMethods
獲取類的實例並查看實際數據
這是最常用的操作——獲取實際數據
# 獲取所有進程實例
Get-CimInstance -ClassName Win32_Process
# 獲取特定進程(如 notepad)
Get-CimInstance -ClassName Win32_Process -Filter "Name='notepad.exe'"
# 只選擇需要的屬性(類似 SQL SELECT)
Get-CimInstance -ClassName Win32_Process | Select-Object Name, ProcessId, CommandLine, WorkingSetSize
調用類的方法執行操作
WMI 類的真正威力在於它們的方法,這讓你能遠程執行管理操作。
示例:終止遠程進程
# 找到要終止的進程
$notepadProcess = Get-CimInstance -ClassName Win32_Process -Filter "Name='notepad.exe'"
# 調用 Terminate 方法
Invoke-CimMethod -InputObject $notepadProcess -MethodName Terminate
示例:創建新進程(遠程執行命令)
# 準備調用 Create 方法的參數
$methodArgs = @{
CommandLine = "calc.exe" # 要啓動的命令或程序
}
# 在本地或遠程計算機上啓動計算器
Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments $methodArgs
# 更復雜的例子:在遠程計算機上執行
$remoteCimSession = New-CimSession -ComputerName "Server01"
Invoke-CimMethod -CimSession $remoteCimSession -ClassName Win32_Process -MethodName Create -Arguments $methodArgs
實際案例
案例 1:快速系統信息收集(用於安全基線核查)
# 收集關鍵系統信息
$systemInfo = @{
OS = Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object Caption, Version, InstallDate
Computer = Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object Name, Domain, Manufacturer, Model
BIOS = Get-CimInstance -ClassName Win32_BIOS | Select-Object SerialNumber, Version
Hotfixes = Get-CimInstance -ClassName Win32_QuickFixEngineering | Select-Object HotFixID, InstalledOn
}
$systemInfo | Format-List
案例 2:監控網絡共享(檢測異常共享)
# 獲取所有網絡共享
$shares = Get-CimInstance -ClassName Win32_Share
# 篩選出可疑的共享(如 ADMIN$ 被非管理員賬户訪問,或異常命名的共享)
$suspiciousShares = $shares | Where-Object {
$_.Name -like "*temp*" -or
$_.Path -notlike "C:*" -or
$_.Description -like "*admin*"
}
if ($suspiciousShares) {
Write-Warning "發現可疑網絡共享:"
$suspiciousShares | Format-Table Name, Path, Description
}
案例 3:用户和登錄會話審計
# 獲取當前登錄的用户會話
$logonSessions = Get-CimInstance -ClassName Win32_LogonSession
foreach ($session in $logonSessions) {
$logonType = switch ($session.LogonType) {
2 { "交互式" }
3 { "網絡" }
10 { "遠程交互" }
default { "其他: $($session.LogonType)" }
}
Write-Host "登錄ID: $($session.LogonId), 類型: $logonType, 開始時間: $($session.StartTime)"
}
-
微軟官方文檔:
- Win32 類:在搜索引擎中搜索 "Win32_Process class Microsoft"
- 直接訪問:
https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-provider
-
使用
Get-CimClass的-Property和-Method參數:
# 專門查看方法的詳細信息
(Get-CimClass -ClassName Win32_Process).CimClassMethods
# 查看特定方法的參數
$processClass = Get-CimClass -ClassName Win32_Process
$processClass.CimClassMethods["Create"].Parameters
- 第三方 WMI 瀏覽器工具:
- 如
WMI Explorer等圖形化工具,可以更直觀地瀏覽整個 WMI 架構。
- 如
查詢配置信息
列出本地存儲庫命名空間和類
- 為什麼要列出命名空間?
因為 WMI/CIM 的所有類都是按照命名空間分組的(就像文件夾)。要想知道有哪些類能用,先得知道有哪些命名空間。
命令方式:
- 用 WMI(支持遞歸):
Get-WmiObject -Namespace root -List -Recurse | Select -Unique __NAMESPACE
這裏 -Recurse 能讓它把 root 下的所有子命名空間都展開。
- 用 CIM(更現代,但不能遞歸):
Get-CimInstance -Namespace root -ClassName __Namespace
然後你可以逐層查看,靠 Tab 自動補全 來探索下一級命名空間。
補充説明:有些命名空間需要管理員權限,所以要 提升 PowerShell權限,否則會報錯。
- 為什麼要列出類?
當你要完成某個管理任務時,你需要知道有沒有合適的 WMI/CIM 類能用。
舉例:想管理進程 → 找類 → 發現有Win32_Process。
命令方式:
- WMI:
Get-WmiObject -Namespace root\CIMv2 -List
- CIM
Get-CimClass -Namespace root\CIMv2
排序,方便查找:
Get-CimClass -Namespace root\CIMv2 | Sort CimClassName
類名前綴的意義
在 root\CIMv2 命名空間裏你會注意到兩種前綴:
CIM_→ 抽象類,是基礎定義,通常不會直接拿來用。Win32_→ 具體實現類,帶有 Windows 特定的信息。
舉例:
CIM_OperatingSystem(抽象概念:操作系統)Win32_OperatingSystem(Windows 系統的具體實現,能拿到屬性,比如版本號、安裝日期等)
系統類:
- 你可能看到一些類名前綴是
__(雙下劃線),比如__Namespace。 - 這些是 系統類,主要被 WMI/CIM 內部使用,比如管理存儲庫本身,不是直接管理資源。
猜測類名:
存儲庫本身沒有“搜索引擎”,所以找類名有點像猜謎。
可以用 關鍵字搜索類名:
Get-CimClass *network* | Sort CimClassName
這會返回類名中帶有 “network” 的所有類。
但注意,它不能搜類的“描述信息”,因為存儲庫裏只存儲類定義,沒有説明文檔。
查詢語言查詢實例
什麼是實例?
- 類:是“定義”。比如
Win32_LogicalDisk定義了磁盤的屬性(盤符、大小、類型…)。 - 實例:是“實際對象”。比如你電腦上的 C盤、D盤,它們就是
Win32_LogicalDisk類的兩個實例。
所以,查詢實例就是:從類裏拿出具體的對象及其屬性。
獲取實例
WMI:
Get-WmiObject -Class Win32_LogicalDisk
CIM(推薦的現代方法):
Get-CimInstance -ClassName Win32_LogicalDisk
注意:
- 輸出格式不同,但信息相同。
- CIM 支持 Tab 補全類名,更方便。
篩選實例(Filter)
默認會返回該類的 所有實例,比如所有磁盤。
但我們通常只想要部分 → 可以加 -Filter。
語法規則:
- 這裏的篩選器 不是 PowerShell 運算符,而是 WMI/CIM 專用運算符(更像 SQL 語法)
| 比較操作 | WMI/CIM 運算符 | PowerShell 運算符 |
|---|---|---|
| 等於 | = |
-eq |
| 不等於 | <> |
-ne |
| 大於 | > |
-gt |
| 小於 | < |
-lt |
| 小於或等於 | <= |
-le |
| 大於或等於 | >= |
-ge |
| 通配符匹配 | LIKE(% 是通配符) |
-like(* 是通配符) |
| 且 | AND |
-and |
| 或 | OR |
-or |
例子:只要本地磁盤(DriveType=3)
Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3"
或者
Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType=3"
解釋:
DriveType是一個數字枚舉:- 3 = 本地固定磁盤(硬盤/SSD)
- 5 = 光驅(DVD)
- 2 = 可移動磁盤(U盤)
所以必須查類文檔來知道數字含義。
WQL(WMI Query Language)
直接用 SQL 風格的語句,更直觀:
Get-CimInstance -Query "SELECT * FROM Win32_LogicalDisk WHERE DriveType = 3"
或者
Get-WmiObject -Query "SELECT * FROM Win32_LogicalDisk WHERE DriveType = 3"
解釋:
SELECT * FROM 類名→ 獲取所有實例WHERE 條件→ 加過濾條件- 語法和 SQL 類似,但功能比 SQL 簡化(因為是 SQL 的子集)
連接到遠程計算機
WMI 連接
使用 -ComputerName 參數指定遠程計算機的名稱或 IP 地址
可以指定多個計算機名稱,以便在單個語句中在多台計算機上運行該命令
可以將計算機名稱作為逗號分隔列表、包含多個計算機名稱的數組或者將生成計算機名稱集合的括號命令作為字符串對象提供
使用 -Credential 參數指定備用用户名
如果僅指定用户名,系統會提示輸入密碼
如果使用 Get-Credential cmdlet 將用户名和密碼存儲在變量中,則可以引用該變量來消除密碼提示
Get-WmiObject -ComputerName LON-DC1 -Credential ADATUM\Administrator -Class Win32_BIOS
指定多個時,如果連接到一台計算機失敗,該命令將生成一條錯誤消息,並繼續嘗試剩餘的計算機。
CIM 連接
使用 -ComputerName 參數為與遠程計算機的臨時連接提供支持
但是CIM沒有 -Credential 參數來指定備用憑據,如果要使用備用憑據,則需要創建 CIM 會話
Get-CimInstance -ComputerName LON-DC1 -Classname Win32_BIOS
查詢存儲庫類
創建會話對象
創建會話時,應將其存儲在變量中供以後參考。 創建會話並將其存儲在變量中的基本語法是:
$s = New-CimSession -ComputerName LON-DC1
可以同時創建多個會話:
$sessions = New-CimSession -ComputerName LON-CL1,LON-DC1
創建會話時,PowerShell 不會立即建立連接。 當 cmdlet 使用 CIM 會話時,PowerShell 將連接到指定的計算機,然後在 cmdlet 完成時,PowerShell 會終止連接。
使用會話
將會話存儲到變量中後,可使用 -CimSession 參數來通過 CIM cmdlet 引用它。 下面的示例使用一個包含多個會話的變量:
Get-CimInstance -CimSession $sessions -ClassName Win32_OperatingSystem
配置會話選項
利用會話選項對象,可以為會話指定多個設置。 創建新會話時,可指定會話選項對象來配置會話。 下面的示例使用 DCOM 而不是 WS-MAN 來創建會話:
$opt = New-CimSessionOption -Protocol Dcom
$DcomSession = New-CimSession -ComputerName LON-DC1 -SessionOption $opt
Get-CimInstance -ClassName Win32_BIOS -CimSession $DcomSession
上述代碼中的第一行創建一個會話選項對象,它指定應使用 DCOM 協議進行連接
第二行使用該會話選項對象創建新的會話,並將其存儲在變量中
最後一行使用會話來查詢會話中定義的遠程計算機,並返回所請求的信息
移除會話
創建會話後,它會在 PowerShell 實例關閉之前一直保存在內存中並可供使用。 可使用 Remove-CimSession cmdlet 手動移除會話。 下面的示例移除變量中包含的一個或多個會話:
# 若你設置sessions的時候,這個變量控制的是多個主機的話,那你這一下子就可以移除全部了
$sessions | Remove-CimSession
若要移除特定遠程計算機的會話,可查詢該計算機的會話,然後將其移除,如以下示例所示:
Get-CimSession -ComputerName LON-DC1 | Remove-CimSession
若要移除所有會話,請運行以下命令:
Get-CimSession | Remove-CimSession
查詢和操作存儲庫對象
發現存儲庫對象的方法
查詢類的實例時,可以使用 Get-Member cmdlet 發現可用於該類型對象的方法
以下示例介紹如何使用 Get-Member 查看 Win32_Service 實例的屬性和方法:
Get-WmiObject -Class Win32_Service | Get-Member -MemberType Method
或者
Get-CimInstance -ClassName Win32_Service | Get-Member -MemberType Method
還可以使用 Get-CimClass 查看可用於特定類的方法:
Get-CimClass -Class Win32_Service | Select-Object -ExpandProperty CimClassMethods
調用存儲庫對象的方法
若要在對象上使用方法,可以調用該方法
或者可以使用 Invoke-WmiMethod 或 Invoke-CimMethod cmdle
如果使用 cmdlet,則使用的 cmdlet 需要與正在使用的對象類型匹配
直接調用
如果已將 Windows Management Instrumentation (WMI) 對象加載到變量中,通常會使用直接調用
可以通過指定變量名稱、點 (.) 和該方法來調用可用於該對象類型的方法
此方法類似於顯示變量中包含的對象屬性值的方式。 以下示例將後台處理程序服務作為 WMI 對象進行查詢,然後調用 StopService 方法。
$WmiSpoolerService = Get-WmiObject -Class Win32_Service -Filter "Name='Spooler'"
$WmiSpoolerService.StopService()
上一個示例中的 StopService 方法不需要為其傳遞任何參數,因此括號內沒有值。 如果調用需要參數的方法,則參數的值將放在括號中。 以下示例將啓動模式參數的值設置為 Manual:
$WmiSpoolerService.ChangeStartMode("Manual")
若要確定方法所需的參數,則應查看該方法的類的相關文檔。 請注意,WMI 方法的參數需要按特定順序傳遞。 若要標識順序,可以使用 GetMethodParameters() 方法。 以下示例查詢 Change 方法的參數:
$WmiSpoolerService.GetMethodParameters("Change")
如果方法需要多個參數,而你不想更改其中的部分參數,則可以為不想更改的參數傳遞一個 $null 值。 此外,無需指定位於要更改的參數之後的參數。 在以下示例中,Change 方法具有 11 個參數,但只配置了第二個參數(顯示名稱)。
$WimSpoolerService.Change($null,"Printer Service")
使用Invoke-WmiMethod
可以單獨使用 Invoke-WmiMethod cmdlet,也可以使用管道向其發送 WMI 對象。 下面是工作原理相同的兩個示例:
Get-WmiObject -Class Win32_OperatingSystem | Invoke-WmiMethod -Name Win32Shutdown -Argument 0
或者
Invoke-WmiMethod -Class Win32_OperatingSystem -Name Win32Shutdown -Argument 0
使用Invoke-CimMethod
Invoke-CimMethod cmdlet 提供與 Invoke-WmiMethod cmdlet 類似的功能,但 Invoke-CimMethod 的參數列表是一個字典對象
此類對象由一個或多個鍵值對組成
每個對的鍵是參數名稱,每個對的值是相應的參數值
在以下示例中,Path 是參數的名稱,Notepad.exe 是值:
Invoke-CimMethod -ComputerName LON-DC1 -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine='Notepad.exe'}
若要在字典中包含多個參數,請使用分號來分隔每個鍵值對
若要針對特定的對象實例調用方法,請先使用 Get-CimInstance cmdlet 檢索對象
可以將對象直接通過管道傳遞給 Invoke-CimMethod cmdlet,或者先將其存儲在變量中
如果對象提供了所有必要的信息,則無需指定任何參數
以下示例檢索 Notepad.exe 的所有正在運行的實例,然後將其終止:
Get-CimInstance -ClassName Win32_Process -Filter "Name='notepad.exe'" | Invoke-CimMethod -MethodName Terminate
如果將 -ComputerName 或 -CIMSession 參數與 Get-CimInstance 一起使用,並將生成的對象通過管道傳遞給 Invoke-CimMethod,則在對象來自的所有計算機或會話上調用該方法
例如,若要終止遠程計算機上的進程,可以運行以下命令:
Get-CimInstance -ClassName Win32_Process -Filter "Name='notepad.exe'" -Computername LON-DC1 | Invoke-CimMethod -MethodName Terminate