在 Windows 系統開發中,經常需要以程式方式讀取或修改本地安全策略。本文將詳細介紹如何使用 C++ 遍歷本地安全策略中的各項本地策略設定,提供兩種主流方案的完整代碼示例與最佳實踐建議。
WMI 提供了標準化的系統管理介面,透過 RSOP_SecurityPolicySetting 等類別可查詢策略結果集。以下是核心步驟:
SELECT * FROM RSOP_SecurityPolicySettingIEnumWbemClassObject 取得每個策略物件KeyName、Setting 等屬性// 關鍵代碼片段
IWbemServices* pSvc = NULL;
IWbemLocator* pLoc = NULL;
CoInitializeEx(0, COINIT_MULTITHREADED);
CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);
pLoc->ConnectServer(_bstr_t(L"ROOT\\RSOP\\Computer"), NULL, NULL, 0, NULL, 0, 0, &pSvc);
CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
IEnumWbemClassObject* pEnumerator = NULL;
pSvc->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM RSOP_SecurityPolicySetting"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
// 遍歷 pEnumerator...
對於需要更底層控制或效能考量的場景,直接呼叫 advapi32.dll 中的 LSA 函數更為高效:
LsaOpenPolicy 取得政策控制代碼LsaEnumerateAccountRights / LsaEnumeratePrivileges 列舉權限LsaQueryInformationPolicy 讀取具體策略資訊LSA_OBJECT_ATTRIBUTES objAttr = {0};
LSA_HANDLE policyHandle;
NTSTATUS status = LsaOpenPolicy(NULL, &objAttr, POLICY_VIEW_LOCAL_INFORMATION, &policyHandle);
if (NT_SUCCESS(status)) {
PLSA_ENUMERATION_HANDLE enumHandle = 0;
PPOLICY_PRIVILEGE_DEFINITION privileges;
ULONG count;
status = LsaEnumeratePrivileges(policyHandle, &enumHandle, (PVOID*)&privileges, 0xFFFFFFFF, &count);
// 處理 privileges 陣列...
LsaFreeMemory(privileges);
LsaClose(policyHandle);
}
requireAdministratorROOT\\RSOP\\Computer 或 ROOT\\CIMV2WMI 方案開發效率高、跨語言支援好,適合快速原型;LSA API 則提供更精細的控制與更佳效能,適合生產級安全工具開發。根據專案需求選擇合適方案,並務必在目標作業系統版本上充分測試。