WMI介紹
Windows Management Instrumentation (WMI) 是基於 Windows 的操作系統上管理數據和操作的基礎結構。 用戶可以使用 WMI 管理本地和遠程計算機。
WMI是Windows操作系統的功能,默認情況下,無須安裝就可以使用。某些Provider(提供程序)的安裝會由系統配置而定。
快速查看WMI對象內容
打開Powershell,輸入
1 Get-WmiObject [WMI Provider]
WMI Provider : WMI的提供程序
如 WIn32_KeyBoard:
WMI的體系結構
WMI提供了一個統一的接口用於從本地或遠程計算機系統中獲取管理數據。WMI基於COM。(詳細的介紹可訪問:https://docs.microsoft.com/en-us/windows/win32/wmisdk/wmi-architecture)
它的體系結構圖如下:
WMI的提供程序(Provider)
WMI支持用戶自己創建提供程序(Provider),以下列舉了操作系統支持的WMI Provider
提供程序 | 描述 |
---|---|
Active Directory 提供程序 | 將 Active Directory 對象映射到 WMI。 通過訪問 WMI 中 (LDAP) 命名空間中的輕型目錄訪問協議,你可以在 Active Directory 中引用或使對象成為別名。 |
BitLocker 驅動器加密 (MANAGE-BDE) 提供程序 | 為硬盤驅動器上的存儲區域(由 Win32 _ EncryptableVolume的實例表示,可使用加密來保護)提供配置和管理。 |
BizTalk 提供程序 | 提供對 WMI 類所表示的 BizTalk 管理對象的訪問權限。 |
引導配置數據 (BCD) 提供程序 | 通過根 WMI 命名空間中的 BCD 提供程序類提供對啟動配置數據的訪問 \ 。 有關詳細信息,請參閱 BCD 參考。 |
CIMWin32 WMI 提供程序 | 支持在 CimWin32.dll 中實現的類。 其中包括核心 CIM WMI 類、這些類的 Win32 實現和電源管理事件。 |
分布式文件系統 (DFS) 提供程序 | 提供 分布式文件系統 (DFS) 函數,這些函數對多個服務器上的共享進行邏輯分組,並以透明方式將它們鏈接到單個命名空間中類似於樹的結構。 |
分布式文件系統復制 (DFSR) 提供程序 | 創建用於配置和監視 分布式文件系統 (DFS) 服務的工具。 有關詳細信息,請參閱 DFSR WMI 類。 |
DNS 提供程序 | 通過使用 Windows Management Instrumentation (WMI) ,管理員和程序員可以配置域名系統 (DNS) 資源記錄 (Rr) 和 DNS 服務器。 |
磁盤配額提供程序 | 允許管理員控制每個用戶在 NTFS 卷上存儲的數據量。 |
事件日志提供程序 | 提供對事件日志服務中數據的訪問,以通知事件。 |
Hyper-v WMI 提供程序 (V2) | 使開發人員和腳本編寫人員能夠快速為虛擬化平台構建自定義工具、實用程序和增強功能。 |
Hyper-v WMI 提供程序 | 使開發人員和腳本編寫人員能夠快速為虛擬化平台構建自定義工具、實用程序和增強功能。 |
Internet Information Services (IIS) | 公開可用於查詢和配置 IIS 元數據庫的編程接口。 |
IP 路由提供程序 | 提供網絡路由信息。 |
作業對象提供程序 | 提供對命名的內核作業對象上的數據的訪問。 |
智能平台管理接口 (IPMI) | 與 WMI IPMI 提供程序一起使用,以便從基板管理控制器 (BMC) 操作向操作系統提供數據。 |
實時通信服務器2003提供程序 | 提供用於創建、注冊、配置、管理自定義會話初始協議 (SIP) 應用程序與 實時通信服務器 2003的 WMI 類。 |
網絡負載平衡 (NLB) | 允許應用程序通過 WMI 與網絡負載平衡群集進行交互。 |
Ping 提供程序 | 提供 WMI 訪問標准 ping 命令提供的狀態信息。 |
策略提供程序 | 提供對組策略的擴展,並允許在策略應用中進行優化。 |
電源管理事件提供程序 | 向 Win32 _ PowerManagementEvent 類提供信息,以描述通過建模 Windows 電源管理協議而導致電源狀態變化的電源管理事件。 |
遠程桌面服務 WMI 提供程序 | 在遠程桌面服務環境中啟用一致的服務器管理。 |
Reporting Services 提供程序 | 定義使您可以編寫腳本和代碼以修改 Report Server 和報表管理器設置的 WMI 類。 |
(RSoP) 提供程序的策略的結果集 | 提供在假設情況下計划和調試策略設置的方法。 這些方法使管理員能夠輕松地確定適用於或將應用於用戶或計算機的策略設置的組合。 這稱為策略的結果集 (RSoP) 。 有關詳細信息,請參閱 關於 RSOP Wmi 方法提供程序 和 rsop wmi 類。 |
安全提供程序 | 檢索或更改控制文件、目錄和共享的所有權、審核和訪問權限的安全設置。 |
服務器群集提供程序 | 定義一組 WMI 類,這些類用於訪問群集對象、屬性和事件。 |
會話提供程序 | 管理網絡會話和連接。 |
卷影復制提供程序 | 為共享文件夾功能的卷影副本提供管理功能。 |
SNMP 提供程序 | 將簡單的網絡管理協議 (SNMP) 對象(在管理信息基本 (MIB) 架構對象)映射到 WMI CIM 類中。 未預安裝此提供程序。 有關詳細信息,請參閱 設置 WMI SNMP 環境。 |
System Center Endpoint Protection (SCEP) | 定義用於實現 System Center Endpoint Protection (SCEP) 管理的 WMI 類。 |
系統注冊表提供程序 | 允許管理應用程序檢索和修改系統注冊表中的數據;並在發生更改時接收通知。 64位平台上提供了兩個版本的系統注冊表提供程序。 |
系統還原提供程序 | 提供配置和使用系統還原功能的類。 有關詳細信息,請參閱 配置系統還原 和 系統還原 WMI 類。 |
受信任的平台模塊提供程序 | 提供有關安全設備的數據的訪問權限(由 Win32 _ TPM的實例表示),這是 Microsoft Windows 可信平台計算機系統的信任的根。 |
Trustmon 提供程序 | 提供有關域信任的訪問信息。 |
查看提供程序 | 基於其他類的實例創建新的實例和方法。 64位平台提供了視圖提供程序的兩個版本。 |
WDM 提供程序 | 提供對符合 Windows 驅動模型 (WDM) 的硬件驅動程序的類、實例、方法和事件的訪問。 |
Win32 提供程序 | 提供來自 Windows 系統的訪問和更新數據,如環境變量的當前設置和邏輯磁盤的屬性。 |
Windows Defender | 定義啟用 Windows Defender 管理的 WMI 類。 |
Windows Installer 提供程序 | 提供從 Windows Installer 兼容的應用程序收集的訪問信息並使 Windows Installer 過程可遠程使用。 |
Windows 產品激活提供程序 | 支持 Windows 產品激活 (WPA) 使用 WMI 接口進行管理,並提供一致的服務器管理。Windows 產品激活在基於 Itanium 的 Windows 操作系統版本上不可用。 |
WMIPerfClass 提供程序 | 創建 WMI 性能計數器類。 WMIPerfInst 提供程序會動態向這些 WMI 性能類提供數據。WMIPerfClass 和 WMIPerfInst 提供程序將替換 ADAP 函數。 |
WmiPerfInst 提供程序 | 從 WMI 性能計數器類 定義動態提供原始和格式化的性能計數器數據。 |
獲取WMI數據的步驟
-
通過調用 CoInitializeEx初始化 COM 參數。
-
通過調用 CoInitializeSecurity初始化 COM 進程安全性。
-
通過調用 CoCreateInstance獲取 WMI 的初始定位符。
-
通過調用 IWbemLocator:: ConnectServer獲取指向本地計算機上根 cimv2 命名空間的 IWbemServices 的指針。
-
設置 IWbemServices proxy security,以便 WMI 服務可以通過調用 CoSetProxyBlanket來模擬客戶端。
-
使用 IWbemServices 指針發出 WMI 請求。 再調用 IWbemServices:: ExecQuery來執行查詢。
如:
SELECT * FROM Win32_OperatingSystem
-
獲取並顯示 WQL 查詢中的數據。 IEnumWbemClassObject指針鏈接到查詢返回的數據對象,可以通過 IEnumWbemClassObject:: Next方法檢索數據對象。 此方法將數據對象鏈接到傳遞到方法的 IWbemClassObject 指針。使用 IWbemClassObject:: get 方法從數據對象獲取所需的信息。
調用WMI函數的步驟
-
通過調用 CoInitializeEx初始化 COM 參數。
-
通過調用 CoInitializeSecurity初始化 COM 進程安全性。
-
通過調用 CoCreateInstance獲取 WMI 的初始定位符。
-
通過調用 IWbemLocator:: ConnectServer獲取指向本地計算機上根 cimv2 命名空間的 IWbemServices 的指針。
-
設置 IWbemServices proxy security
-
使用 IWbemServices 指針向 WMI 發出請求。 使用 IWbemServices:: ExecMethod 來調用WMI函數
示例:獲取WMI數據
1 #include <iostream> 2 #include <WbemIdl.h> 3 #include<Windows.h> 4 #include <comdef.h> 5 6 #pragma comment(lib,"wbemuuid.lib") 7 8 using namespace std; 9
1 //初始化COM [MTAThread] 2 HRESULT hr; 3 hr = CoInitializeEx(0, COINIT_MULTITHREADED); 4 5 if (FAILED(hr)) 6 { 7 return; 8 } 9 10 //設置COM安全級別 11 hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); 12 13 if (FAILED(hr)) 14 { 15 CoUninitialize(); 16 return; 17 } 18 19 //創建WMI命名空間的連接 20 IWbemLocator* pLoc = NULL; 21 22 hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc); 23 24 IWbemServices* pSvc = NULL; 25 26 //連接WMI 27 hr = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc); 28 29 if (FAILED(hr)) 30 { 31 pLoc->Release(); 32 CoUninitialize(); 33 return; 34 } 35 36 //在代理上設置安全級別 37 hr = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); 38 39 if (FAILED(hr)) 40 { 41 pSvc->Release(); 42 pLoc->Release(); 43 44 CoUninitialize(); 45 } 46 47 //查詢WMI對象 48 //使用IWbemServices指針創建WMI請求 49 IEnumWbemClassObject* pEnumerator = NULL; 50 pSvc->ExecQuery(bstr_t("WQL"), 51 bstr_t("Select * from win32_OperatingSystem"), 52 WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 53 NULL, 54 &pEnumerator); 55 56 if (FAILED(hr)) 57 { 58 pSvc->Release(); 59 pLoc->Release(); 60 CoUninitialize(); 61 return; 62 } 63 64 //獲取數據 65 IWbemClassObject* pclsObj = NULL; 66 ULONG uReturn = 0; 67 68 while (pEnumerator) 69 { 70 hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); 71 72 if (0 == uReturn) 73 { 74 break; 75 } 76 77 VARIANT vtProp{}; 78 hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0); 79 80 std::wcout << "OS Name : " << vtProp.bstrVal << std::endl; 81 82 VariantClear(&vtProp); 83 pclsObj->Release(); 84 } 85 86 pSvc->Release(); 87 pLoc->Release(); 88 pEnumerator->Release(); 89 CoUninitialize();
示例:調用WMI函數來禁用/啟用網卡
1 /*include 2 *#include <iostream> 3 *#include <WbemIdl.h> 4 *#include<Windows.h> 5 *#include <comdef.h> 6 *#pragma comment(lib,"wbemuuid.lib") 7 *using namespace std; 8 */ 9 10 HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); 11 if (FAILED(hr)) 12 { 13 return; 14 } 15 16 if ((FAILED(hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0)))) 17 { 18 return; 19 } 20 21 IWbemLocator* pLocator = NULL; 22 if (FAILED(hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator)))) 23 { 24 return; 25 } 26 27 IWbemServices* pService = NULL; 28 hr = pLocator->ConnectServer(_bstr_t("root\\CIMV2"), NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService); 29 if (FAILED(hr)) 30 { 31 pLocator->Release(); 32 return; 33 } 34 35 IEnumWbemClassObject* pEnumerator = NULL; 36 hr = pService->ExecQuery(_bstr_t("WQL"), _bstr_t("SELECT * FROM Win32_NetworkAdapter WHERE Name Like 'Intel(R) Ethernet Connection (2) I219-V'"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator); 37 if (FAILED(hr)) 38 { 39 pLocator->Release(); 40 pService->Release(); 41 return; 42 } 43 44 IWbemClassObject* clsObj = NULL; 45 int numElems; 46 while ((hr = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE) 47 { 48 if (FAILED(hr)) 49 break; 50 51 VARIANT vtPath; 52 VariantInit(&vtPath); 53 if (FAILED(clsObj->Get(L"__Path", 0, &vtPath, NULL, NULL))) 54 { 55 cout << "Object has no __Path!" << endl; 56 clsObj->Release(); 57 continue; 58 } 59 60 IWbemClassObject* pResult = NULL; 61 //禁用 62 hr = pService->ExecMethod(vtPath.bstrVal, _bstr_t("Disable"), 0, NULL, NULL, &pResult, NULL); 63 if (FAILED(hr)) 64 cout << "Unable to set the default printer: " << std::hex << hr << endl; 65 else 66 { 67 VARIANT vtRet; 68 VariantInit(&vtRet); 69 if (FAILED(hr = pResult->Get(L"ReturnValue", 0, &vtRet, NULL, 0))) 70 cout << "Unable to get return value of call: " << std::hex << hr << endl; 71 else 72 cout << "Method returned: " << vtRet.intVal << endl; 73 74 VariantClear(&vtRet); 75 pResult->Release(); 76 } 77 78 VariantClear(&vtPath); 79 clsObj->Release(); 80 } 81 82 pEnumerator->Release(); 83 pService->Release(); 84 pLocator->Release();
示例:調用WMI函數來創建進程
1 HRESULT hr; 2 hr = CoInitializeEx(0, COINIT_MULTITHREADED); 3 if (FAILED(hr)) 4 { 5 return; 6 } 7 8 hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); 9 if (FAILED(hr)) 10 { 11 CoUninitialize(); 12 return; 13 } 14 15 IWbemLocator* pLoc = NULL; 16 hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc); 17 if (FAILED(hr)) 18 { 19 CoUninitialize(); 20 return; 21 } 22 23 IWbemServices* pSvc = NULL; 24 hr = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0,0, &pSvc); 25 if (FAILED(hr)) 26 { 27 pLoc->Release(); 28 CoUninitialize(); 29 return; 30 } 31 32 hr = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); 33 if (FAILED(hr)) 34 { 35 pSvc->Release(); 36 pLoc->Release(); 37 CoUninitialize(); 38 return; 39 } 40 41 BSTR methodName = SysAllocString(L"Create"); 42 BSTR className = SysAllocString(L"Win32_Process"); 43 44 IWbemClassObject* pClass = NULL; 45 hr = pSvc->GetObjectW(className, 0, NULL, &pClass, NULL); 46 47 IWbemClassObject* pInParamDefinition = NULL; 48 hr = pClass->GetMethod(methodName, 0, &pInParamDefinition, NULL); 49 50 IWbemClassObject* pClassInstance = NULL; 51 hr = pInParamDefinition->SpawnInstance(0, &pClassInstance); 52 53 VARIANT varCommand; 54 VariantInit(&varCommand); 55 varCommand.vt = VT_BSTR; 56 varCommand.bstrVal = _bstr_t(L"notepad.exe"); 57 58 hr = pClassInstance->Put(L"CommandLine", 0, &varCommand, 0); 59 60 IWbemClassObject* pOutParams = NULL; 61 hr = pSvc->ExecMethod(className, methodName, 0, NULL, pClassInstance, &pOutParams, NULL); 62 63 if (FAILED(hr)) 64 { 65 VariantClear(&varCommand); 66 SysFreeString(className); 67 SysFreeString(methodName); 68 pClass->Release(); 69 pClassInstance->Release(); 70 pInParamDefinition->Release(); 71 pOutParams->Release(); 72 pSvc->Release(); 73 pLoc->Release(); 74 CoUninitialize(); 75 return; 76 } 77 78 VARIANT varReturnValue; 79 VariantInit(&varReturnValue); 80 hr = pOutParams->Get(BSTR(L"ReturnValue"), 0, &varReturnValue, NULL, 0); 81 82 if (SUCCEEDED(hr)) 83 { 84 VariantClear(&varReturnValue); 85 } 86 VariantClear(&varCommand); 87 SysFreeString(className); 88 SysFreeString(methodName); 89 pClass->Release(); 90 pClassInstance->Release(); 91 pInParamDefinition->Release(); 92 pOutParams->Release(); 93 pLoc->Release(); 94 pSvc->Release(); 95 CoUninitialize();
示例代碼
https://github.com/zhaotianff/WindowsProgramming/tree/master/WMI