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_ACCESSDENIED
exception的解决方案:
- 单击“开始”,单击“运行”,键入DCOMCNFG ,然后单击“确定”。
- 在“ 组件服务”对话框中,展开“ 组件服务” ,展开“ 计算机” ,然后右键单击“ 我的电脑” ,再单击“ 属性” 。
- 在“ 我的电脑属性”对话框中,单击“ COM安全”选项卡。
- 在“ 访问权限”下 ,单击“ 编辑限制” 。
- 在“ 访问权限”对话框中,在“ 组或用户名”框中选择“ 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应用程序池时自动构建的系统生成的用户帐户。
完成这项工作的过程如下:
- 运行mmc,添加“组件服务”管理单元
- 打开计算机 – >我的电脑 – > DCOM配置
- 向下滚动到“Microsoft WBEM Unsecured Apartment Object”
- 右键单击并选择“属性”
- 单击“安全”选项卡,然后在“启动和激活权限”部分下,选择“自定义”选项并单击“编辑”
- 如果您的IIS服务器是域的一部分,请确保您在位置字段中指定了本地计算机而不是域。
- 点击添加按钮,在用户框中输入“IIS APPPool \ DefaultAppPool”,然后点击Check Names按钮。 如果您没有使用DefaultAppPool,则替换您正在使用的应用程序池的名称。
- 您将看到框中显示有效用户,单击“确定”。
- 在列表中选择用户,然后选中“允许”“本地启动和本地激活”框。
- 享受这样一个事实,即您将不再在对WMI事件侦听器的异步回调中看到E_ACCESSDENIED。