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

时间:2010-05-06 15:31:48

标签: c# wmi managementeventwatcher

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

  

访问被拒绝。 (HRESULT的例外情况:0x80070005   (E_ACCESSDENIED))

我已将WMI控制中的权限赋予root\cimv2,并且还在DCOM配置中授予用户帐户的管理员权限。

我有正常的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

3 个答案:

答案 0 :(得分:4)

尝试与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

答案 1 :(得分:4)

首先,请记住Microsoft recommends the use of semi-synchronous operations(正如Brian建议的那样):

  

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

另见Setting Security on an Asynchronous Call in VBScript

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

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

  1. 单击“开始”,单击“运行”,键入 DCOMCNFG ,然后单击“确定”。
  2. 组件服务对话框中,展开组件服务,展开计算机,然后右键单击我的电脑,然后点击属性
  3. 我的电脑属性对话框中,点击 COM安全标签。
  4. 访问权限下,点击修改限制
  5. 访问权限对话框中,在组或用户名框中选择 ANONYMOUS LOGON 名称。在用户权限下的允许列中,选择远程访问,然后点击确定
  6. 请注意,我在客户端中执行了上述操作。虽然这为我修复了DCOM权限问题,但我遇到了WMI访问被拒绝错误(0x80041003)。事实证明这是由于第二篇文章中提到的注册表项:

      

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

         

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

         

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

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

    有关问题排查,请参阅:

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

答案 2 :(得分:0)

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

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

  

计算机默认权限设置不授予本地激活   具有CLSID的COM Server应用程序的权限   {49BD2028-1523-11D1-AD79-00C04FD8FDFF}和APPID   {49BD2028-1523-11D1-AD79-00C04FD8FDFF}给用户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. 中添加“组件服务”管理单元
  3. 打开计算机 - >我的电脑 - > DCOM配置
  4. 向下滚动到" Microsoft WBEM Unsecured Apartment Object"
  5. 右键单击并选择“属性”
  6. 单击“安全”选项卡,然后单击“#34;启动和激活权限"”部分。选择“自定义”选项,然后单击“编辑”
  7. 如果您的IIS服务器是域的一部分,请确保您在位置字段中指定了本地计算机,而不是域。
  8. 点击添加按钮,然后输入" IIS APPPool \ DefaultAppPool"进入用户Box并点击Check Names按钮。如果您没有使用DefaultAppPool,请替换您正在使用的应用程序池的名称。
  9. 您会在框中看到有效用户,点击“确定”。
  10. 在列表中选择用户,然后选中“允许本地启动和本地激活”框。
  11. 尽管您不会再看到对WMI事件监听器的异步回调的E_ACCESSDENIED这一事实。