ManagementEventWatcher(WMI)从远程计算机通知事件时发生exception

我正在尝试使用WMI和C#从远程计算机的事件查看器获取通知。 我可以使用ManagementObjectSearcher连接系统并获取事件日志。 但是当我尝试使用ManagementEventWatcher.Start方法时,我得到一个exception:

访问被拒绝。 (来自HRESULT的exception:0x80070005(E_ACCESSDENIED))

我已将WMI Control中的root\cimv2赋予root\cimv2并在DCOM Config中授予用户帐户的管理员权限。

我有正常的Windows应用程序,因此我不使用ASP.net(ASPNET用户)在我的情况下。

我的代码是:

 ConnectionOptions connectionOptions = new ConnectionOptions(); connectionOptions.Username = @"Domain\UName";//txtUserName.Text; connectionOptions.Password = "pass";//txtPassword.Text; connectionOptions.Impersonation = ImpersonationLevel.Impersonate; ManagementScope managementScope = new ManagementScope(@"\\server\root\cimv2",connectionOptions); managementScope.Options.EnablePrivileges = true; managementScope.Connect(); // this line is executing fine. eventWatcher = new ManagementEventWatcher(managementScope, new EventQuery("Select * From __InstanceCreationEvent WHERE TargetInstance ISA 'Win32_NTLogEvent' and TargetInstance.LogFile = 'Application'")); eventWatcher.EventArrived += new EventArrivedEventHandler(Arrived); eventWatcher.Scope.Options.EnablePrivileges = true; eventWatcher.Start(); // Error occurs here 

尝试与WaitForNextEvent()半同步监听:

  var managementScope = new ManagementScope(@"\\mysever\root\onguard"); managementScope.Connect(); var query = new EventQuery("select * from lnl_AccessEvent"); var eventWatcher = new ManagementEventWatcher(managementScope, query); var wmiEvent = eventWatcher.WaitForNextEvent(); Console.Out.WriteLine(wmiEvent.GetPropertyValue("Description")); 

我们还发现wbemtest.exe很有用。 单击通知查询…按钮以侦听事件。 您可以尝试各种连接方法(同步,异步或半同步)。 连接到本地计算机时,所有连接方法都有效,但我们只能半远程同步工作。 异步(您正在使用)更复杂(并且安全性更低),因为服务器必须建立与客户端的连接。

这里有一些关于安全性和配置设置的好信息: http : //www.packettrap.com/network/Knowledge-Base/PacketTrap-MSP/WMI-Troubleshooting.aspx#_Toc239699682

首先,请记住, Microsoft建议使用半同步操作 (如Brian建议的那样):

如果可以,我们建议您使用半同步操作。 性能影响很小,半同步操作允许相同的function,但不需要反向连接。

另请参阅在VBScript中设置异步调用的安全性 。

如果您仍想使用异步操作,请参阅以下文章:

  • 如何解决Windows XP SP2中与WMI相关的问题
  • 远程连接到WMI从Windows Vista开始
  • 保护远程WMI连接
  • 连接不同的操作系统

YMMV,但对我来说(客户端:Win7 x64 SP1服务器:没有防火墙的Windows Server 2008 Enterprise SP2),在第三篇文章中找到了E_ACCESSDENIEDexception的解决方案:

  1. 单击“开始”,单击“运行”,键入DCOMCNFG ,然后单击“确定”。
  2. 在“ 组件服务”对话框中,展开“ 组件服务” ,展开“ 计算机” ,然后右键单击“ 我的电脑” ,再单击“ 属性”
  3. 在“ 我的电脑属性”对话框中,单击“ COM安全”选项卡。
  4. 在“ 访问权限”下 ,单击“ 编辑限制”
  5. 在“ 访问权限”对话框中,在“ 组或用户名”框中选择“ ANONYMOUS LOGON”名称。 在“ 用户权限”下的“ 允许”列中,选择“ 远程访问” ,然后单击“ 确定”

请注意,我在客户端中执行了上述操作。 虽然这为我修复了DCOM权限问题,然后我遇到了WMI访问被拒绝错误( 0x80041003 )。 原来这是由于第二篇文章中提到的注册表项:

如果远程连接是在没有信任关系的计算机之间,则需要更新CIMOM设置; 否则,异步连接将失败。 不应为同一域或受信任域中的计算机修改此设置。

需要修改以下注册表项以允许匿名回调:HKLM \ SOFTWARE \ Microsoft \ WBEM \ CIMOM \ AllowAnonymousCallback

如果AllowAnonymousCallback键设置为0,则WMI服务会阻止对客户端的匿名回调。 如果该值设置为1,则WMI服务允许匿名回调客户端。

请注意,您需要在服务器中设置上述内容。 一旦我这样做,异步回调就起作用了。 您可以尝试的其他事项是以管理员身份运行客户端并将ConnectionOptions.EnablePrivileges设置为true。

有关疑难解答请参

  • WMI故障排除
  • 记录WMI活动(Pre vista)
  • 跟踪WMI活动(从Vista开始)

最后,我建议你利用微软的WMI测试器( %windir%\system32\wbem\wbemtest.exe

我花了好几个小时搞清楚这个。 以上都不适合我。

在我的IIS服务器上分析事件日志后,我发现每次在ManagementEventWatcher对象上调用Start方法时,我都在系统日志中收到以下错误事件:

机器默认权限设置不会将具有CLSID {49BD2028-1523-11D1-AD79-00C04FD8FDFF}和APPID {49BD2028-1523-11D1-AD79-00C04FD8FDFF}的COM服务器应用程序的本地激活权限授予用户IIS APPPOOL \ DefaultAppPool SID(S-1-5-82-3006700770-424185619-1745488364-794895919-4004696415)来自地址LocalHost(使用LRPC)。 可以使用组件服务管理工具修改此安全权限。

注册表搜索显示具有错误中指定的APPID的应用程序是

Microsoft WBEM无担保公寓

要使异步回调工作,您需要将此COM对象的本地激活权限授予IIS APPPOOL \ DefaultAppPool用户,这听起来很容易,除非用户未在安全数据库中显示为有效帐户。 这是因为它是在创建IIS应用程序池时自动构建的系统生成的用户帐户。

完成这项工作的过程如下:

  1. 运行mmc,添加“组件服务”管理单元
  2. 打开计算机 – >我的电脑 – > DCOM配置
  3. 向下滚动到“Microsoft WBEM Unsecured Apartment Object”
  4. 右键单击并选择“属性”
  5. 单击“安全”选项卡,然后在“启动和激活权限”部分下,选择“自定义”选项并单击“编辑”
  6. 如果您的IIS服务器是域的一部分,请确保您在位置字段中指定了本地计算机而不是域。
  7. 点击添加按钮,在用户框中输入“IIS APPPool \ DefaultAppPool”,然后点击Check Names按钮。 如果您没有使用DefaultAppPool,则替换您正在使用的应用程序池的名称。
  8. 您将看到框中显示有效用户,单击“确定”。
  9. 在列表中选择用户,然后选中“允许”“本地启动和本地激活”框。
  10. 享受这样一个事实,即您将不再在对WMI事件侦听器的异步回调中看到E_ACCESSDENIED。