如何修复IWbemLocator::ConnectServer返回E_ACCESSDENIED错误?
远程WMI连接失败:错误0x80070005与事件ID 10036问题解决
问题概述
尝试建立与Windows 10 LTS远程机器的WMI连接时,原WinXP时代的代码方法失效。远程机器生成事件ID 10036,提示客户端需至少使用RPC_C_AUTHN_LEVEL_PKT_INTEGRITY认证级别,但仅修改CoInitializeSecurity的全局认证级别无法解决问题,调用ConnectServer始终返回错误0x80070005(拒绝访问)。
测试环境
- 开发机器:Windows 7 SP1,VS2022
- 远程机器:Windows 10 LTS
测试代码
// Compile with cl /std:c++17 or later #include <wbemcli.h> #include <string_view> #pragma comment (lib, "wbemuuid.lib") #pragma comment (lib, "ole32.lib") #pragma comment (lib, "OleAut32.lib") #define IP L"192.168.1.2" #define LOGIN L"Administrator" #define PWD L"P@ssw0rd" using namespace std::literals; ::BSTR SysString (std::wstring_view data) { return ::SysAllocStringLen (data.data (), (UINT) data.size ()); } int main (void) { ::wprintf (L"CoInitializeEx -> 0x%08X\n", ::CoInitializeEx (nullptr, COINIT_MULTITHREADED)); ::wprintf (L"CoInitializeSecurity -> 0x%08X\n", ::CoInitializeSecurity ( nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE, nullptr )); ::IWbemLocator *wmiLocator = nullptr; ::wprintf (L"CoCreateInstance -> 0x%08X\n", ::CoCreateInstance ( CLSID_WbemLocator, nullptr, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (void **) &wmiLocator )); if (wmiLocator) { ::IWbemServices *pNamespace = nullptr; ::wprintf (L"ConnectServer -> 0x%08X\n", wmiLocator->ConnectServer ( SysString (L"\\\\" IP L"\\root\\cimv2"sv), SysString (IP L"\\" LOGIN L""sv), SysString (PWD L""sv), nullptr, 0, nullptr, nullptr, &pNamespace )); if (pNamespace) pNamespace->Release (); wmiLocator->Release (); } return 0; }
运行输出
CoInitializeEx -> 0x00000000 CoInitializeSecurity -> 0x00000000 CoCreateInstance -> 0x00000000 ConnectServer -> 0x80070005
解决方案
1. 为WMI服务对象显式设置认证参数
全局CoInitializeSecurity的设置可能被WMI服务覆盖,需在ConnectServer成功后,通过CoSetProxyBlanket单独为IWbemServices对象指定认证级别:
修改代码中ConnectServer后的逻辑:
if (wmiLocator) { ::IWbemServices *pNamespace = nullptr; HRESULT hrConnect = wmiLocator->ConnectServer ( SysString (L"\\\\" IP L"\\root\\cimv2"sv), SysString (L".\\" LOGIN L""sv), // 本地账户改用.\前缀,避免IP解析问题 SysString (PWD L""sv), nullptr, 0, nullptr, nullptr, &pNamespace ); ::wprintf (L"ConnectServer -> 0x%08X\n", hrConnect); if (pNamespace && SUCCEEDED(hrConnect)) { HRESULT hrProxy = ::CoSetProxyBlanket( pNamespace, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE ); ::wprintf(L"CoSetProxyBlanket -> 0x%08X\n", hrProxy); } if (pNamespace) pNamespace->Release (); wmiLocator->Release (); }
2. 配置远程机器的WMI权限
- 打开远程机器的
wmimgmt.msc,右键WMI控制(本地) → 属性 - 切换到安全选项卡,展开
Root\Cimv2节点,点击安全按钮 - 添加远程访问用户(如Administrator),授予启用账户和远程启用权限
3. 检查防火墙设置
确保远程机器Windows防火墙允许WMI通信:
- 启用Windows Management Instrumentation (WMI) 入站规则
- 若使用自定义防火墙规则,需允许TCP端口135及动态RPC端口范围(默认49152-65535)
4. 更新开发机器的系统补丁
Windows 7的WMI客户端需安装最新系统补丁,以支持Windows 10的WMI安全强化要求。
内容的提问来源于stack exchange,提问作者Bogudan
相关产品推荐
相关产品推荐

