授予远程用户(非管理员)使用 WMI 和 C# 在命名空间 cimv2 中枚举 Win32_Service 服务的能力

Posted

技术标签:

【中文标题】授予远程用户(非管理员)使用 WMI 和 C# 在命名空间 cimv2 中枚举 Win32_Service 服务的能力【英文标题】:Granting remote user (non admin) the ability to enumerate services in Win32_Service in namespace cimv2 using WMI & C# 【发布时间】:2010-10-12 17:41:04 【问题描述】:

我正在创建一个监视服务,它将监视各种远程服务器上的其他服务(都在同一个域中)。我用来连接远程服务器的用户不是管理员。当我尝试枚举 Win32_Service 类中的服务时,我收到拒绝访问错误。

我已授予用户“远程启用”和“启用帐户”权限以访问 WMI 控件中的 Root\CIMV2 命名空间。

我可以使用以下代码连接到服务器。对象 ServiceListItem 只是一个包含服务器名称和服务名称的简单类:

SecureString secureString = new SecureString();

foreach ( char c in "password" )

    secureString.AppendChar( c );


ConnectionOptions connectionOptions = new ConnectionOptions();

connectionOptions.Username = "domain\\user";
connectionOptions.SecurePassword = secureString;

foreach ( ServiceListItem service in _serviceList )

     ManagementScope managementScope = new ManagementScope();
     managementScope = new ManagementScope( String.Format( @"\\0\root\cimv2", service.ServerName ), connectionOptions );
     managementScope.Connect();

     //RelatedObjectQuery relatedObjectQuery = new RelatedObjectQuery( String.Format( "Win32_Service.Name='0'", service.ServiceName ) );
     //ManagementObjectSearcher objectSearcher = new ManagementObjectSearcher( managementScope, relatedObjectQuery );

     ObjectQuery objectQuery = new ObjectQuery( "SELECT * FROM Win32_Service WHERE Name = '" + service.ServiceName + "'" );
     ManagementObjectSearcher objectSearcher = new ManagementObjectSearcher( managementScope, objectQuery );

     ManagementObjectCollection objectCollection = objectSearcher.Get();

     foreach ( ManagementObject managementObject in objectCollection )
     
          serviceStatus = managementObject.Properties["State"].Value.ToString();
          Debug.Print(service.ServiceName + " - " + serviceStatus);
          //break;
     

managementScope.Connect() 运行良好,这意味着 cimv2 上的 wmi 安全设置正确。但是,当我尝试枚举 objectCollection 时,我得到了“拒绝访问”异常。这告诉我(我认为)用户没有权限枚举 Win32_Service 类 (SC_MANAGER_ENUMERATE_SERVICE)。

我只是找不到任何关于如何为远程用户启用该权限的好例子。在使用 Windows api 进行编码时,我不是很有经验,所以请在你的答案中尽可能详细:)

【问题讨论】:

【参考方案1】:

今天我自己试图找到相同的答案,我一直在进行大量的谷歌搜索。经过半小时的咒语,我找到了this MSDN article (907460),它使用了sc sdet。尽管安全描述符适用于 Windows Server 2003,但它似乎到目前为止仍然有效。我发现您可以通过 sc sdshow SCMANAGER 获取当前值,因此明天回到办公室时,我将比较对比以确保我没有锁定我不应该锁定的东西:-)

为完整起见,KB907460 中的注释(以防它移动/消失):

症状:安装 Microsoft Windows Server 2003 Service Pack 1 (SP1) 后,非管理员无法远程访问服务控制管理器。

原因: Windows Server 2003 SP1 更改了服务控制管理器的默认安全设置。

分辨率: 要解决此问题,请使用 Sc.exe 工具的 5.2.3790.1830 版本。 此工具位于 %windir%\System32 文件夹中。去做这个, 请按照以下步骤操作:

单击“开始”,单击“运行”,键入 cmd,然后单击“确定”。

在命令提示符下键入以下命令,然后按 ENTER:

sc sdset SCMANAGER D:(A;;CCLCRPRC;;;AU)(A;;CCLCRPWPRC;;;SY)(A;;KA;;;BA)S:(AU;FA;KA;;;WD)(AU;OIIOFA;GA;;;WD)

【讨论】:

【参考方案2】:

我发现自己陷入了类似的问题。就我而言,它与权限无关,我通过以下链接进行设置:http://www.poweradmin.com/help/enableWMI.aspx

因此,经过数小时的疑惑迷路后,我发现这篇文章讲述了 UAC 如何干扰您的权限集以及如何解决该问题: http://www.solarwinds.com/documentation/apm/docs/APMWMITroubleshooting.pdf

在我的例子中,注册表项不存在,所以我创建了它。

希望这也有帮助,干杯!

【讨论】:

以上是关于授予远程用户(非管理员)使用 WMI 和 C# 在命名空间 cimv2 中枚举 Win32_Service 服务的能力的主要内容,如果未能解决你的问题,请参考以下文章

WMI 访问被拒绝问题

什么是WMI 有什么用?

在远程计算机上模拟用户时 WMI 的访问被拒绝

无法使用 WMI 和 C# 远程终止进程

远程运行 wmi 进程,没有适当的域用户权限

C#通过WMI的wind32 的API函数实现msinfo32的本地和远程计算机的系统日志查看功能