WMI远程启动进程查询父进程报E_ACCESSDENIED访问拒绝如何解决
错误根因
0x80070005 (E_ACCESSDENIED)报错的核心是WMI远程启动进程的令牌限制:
通过WMI远程创建的进程,所持有的用户令牌为网络登录类型,默认的Impersonate模拟级别仅支持在当前机器本地使用用户身份,无法将凭据二次跳转回源机器完成WMI查询的身份校验。你手动在远程机器交互式登录运行进程时,拿到的是交互式登录令牌,具备跨网络访问权限,所以查询可以正常执行。
解决方案
方案1:调整WMI配置修复查询权限
如果你的两台服务器处于同一个Active Directory域中,可直接修改父进程的WMI连接参数,将模拟级别升级为Delegate即可支持凭据跨网络跳转:
module Wmi = let connect host privileged = let options = ConnectionOptions( Impersonation = ImpersonationLevel.Delegate, // 替换原有的Impersonate级别 EnablePrivileges = privileged, Authentication = AuthenticationLevel.PacketPrivacy // 可选,开启WMI通信加密 ) let scope = new ManagementScope(sprintf @"\\%s\ROOT\CIMV2" host, options) do scope.Connect() scope
注意:工作组环境不支持
Delegate模拟级别,该方案仅适用域环境。
方案2:复用现有TCP通道实现心跳(兼容性最高)
无需调整任何系统权限,同时还能覆盖父进程所在机器断网、系统卡死等WMI查询无法覆盖的异常场景:
- 在现有TCP任务通道中新增心跳指令,父进程收到心跳后返回ACK响应
- 远程工作进程每隔35秒发送一次心跳请求,连续23次未收到ACK响应,直接自行终止
方案3:同步句柄监控(性能最优)
如果两台机器SMB协议互通,可通过跨机器继承进程同步句柄实现无网络请求的监控:
- 父进程创建一个可跨网络访问的自动重置事件句柄,将句柄标识随启动参数传给远程工作进程
- 工作进程启动后打开该句柄,等待句柄触发信号,父进程异常退出时系统会自动释放该句柄并触发信号,工作进程捕获到信号后直接退出
内容的提问来源于stack exchange,提问作者Aaron M. Eshbach
相关产品推荐
相关产品推荐

