我正在使用IIS在服务器上运行的C# ASP.NET Application中try 使用WMI查询本地域上计算机的硬件数据.

在使用New-CimSessioncmdlet成功打开CIM会话并在PowerShell中查询WMI数据后,我try 使用C#中的CimSession.Create完成相同的操作.

然而,当try 使用C#查询相同的数据时,我收到了一个Access Denied错误,代码为0x80070005. 根据Microsoft文档(https://learn.microsoft.com/en-us/windows/win32/wmisdk/wmi-troubleshooting),这是由DCOM引起的.

到目前为止,我一直无法想出一个不同的解决方案,我觉得奇怪的是,在使用PowerShell时,基本上同样的try 可以很好地工作.

一些一般信息:

  • 我的帐户在远程计算机上具有本地管理员权限(根据使用cim会话执行WMI查询时的要求)
  • 我已经判断了防火墙和连接问题,并try 在IIS以外运行我的应用程序

PowerShell中的成功try :

$CimSession = New-CimSession -ComputerName "PC-HOSTNAME" -Credential (Get-Credential)
Get-CimInstance -CimSession $CimSession -ClassName Win32_ComputerSystem

在不传递显式身份验证参数的情况下try 使用登录到运行应用程序的服务器的Windows用户的same credentials的代码示例:

CimSession session = CimSession.Create("PC-HOSTNAME");
// The next line results in the error
var response = session.QueryInstances(@"root\cimv2", "WQL", "SELECT * FROM Win32_ComputerSystem");

这应该可以按原样工作,但为了确保我也try 传递显式身份验证参数,这也会导致相同的错误:

DComSessionOptions dComOptions = new DComSessionOptions();
dComOptions.Impersonation = ImpersonationType.Impersonate;

//Build secure string from plain text for representation
var somePasswordString = "password"
var password = new SecureString();
somePasswordString.ToList().ForEach(x => password.AppendChar(x));

dComOptions.AddDestinationCredentials(new CimCredential(PasswordAuthenticationMechanism.Default, "mydomain.local", "myusername", password));
        
CimSession session = CimSession.Create("PC-HOSTNAME");
// The next line results in the error
var response = session.QueryInstances(@"root\cimv2", "WQL", "SELECT * FROM Win32_ComputerSystem");

我在C#中看到了许多关于WMI的不同方法,但对于我的用例来说,使用CimSessionQueryInstances方法似乎是最直接的.尽管如此,我找到的所有其他代码示例都导致了相同的错误.

任何帮助都将不胜感激--谢谢!

更新

正如@IanKemp所指出的,我知道在Web应用程序中运行需要管理员权限的操作是不好的做法.然而,我只是想弄清楚如何在C#中运行基本的WMI查询,以及哪些问题可能会导致我得到所描述的Access Denied错误,而使用PowerShell则完全可以正常工作.

更新 V2

我在服务器故障上找到了一个有趣的答案:https://serverfault.com/a/1105113

如果您正在try 访问WMI,则有两种协议可用:DCOM和WinRM.您使用的协议将取决于所使用的工具或API.例如,当您使用PowerShell时,‘较旧’的Get-WmiObject cmdlet使用DCOM,而‘较新’的Get-CimInstance cmdlet使用WinRM.

这可以解释为什么PowerShell在我的例子中表现不同,但我仍然没有找到一个解决方案来让它在C#中工作

推荐答案

经过反复试验,我找到了解决问题的办法.

正如我在《更新V2》中提到的,这篇文章指向我的解决方案:https://serverfault.com/a/1105113

有两件事解决了我的问题:

  1. 我在服务器故障的帖子中提到,我在WMI控制下授予了我的用户‘Remote Enable’权限

  2. 在开发中,我必须以管理员身份运行Visual Studio(不知道为什么,但这解决了我之前遇到的任何访问被拒绝的问题,即使我在代码中以管理员身份进行了验证)

Csharp相关问答推荐

编写DataAnnotations自定义验证器的多种方法

找不到网址:https://localhost:7002/Category/Add?区域= Admin.为什么我的URL是这样生成的?area = Admin而不是/Admin/

数组被内部函数租用时,如何将数组返回给ArrayPool?

C#中使用BouncyCastle计算CMac

NumPy s fftn in C#with pythonnet'

在多对多关系上不删除实体

为什么在ANTLR4中会出现不匹配的输入错误?""

JsonSerializer.Deserialize<;TValue>;(String,JsonSerializerOptions)何时返回空?

Blazor WebApp:原始异常:AADSTS700025:客户端是公共的,因此既不应显示客户端,也不应显示客户端

内部接口和类的DI解析

如何在WPF的树视图中显示一个对象的两个或多个属性,其中只有一个是分层项?

C#中Java算法的类似功能

如何允许数组接受多个类型?

我可以强制System.Text.Json.JsonSerializer以非递归方式工作吗?

RCL在毛伊岛应用程序和Blazor服务器应用程序.Net 8.0中使用页面

为什么在使用JsonDerivedType序列化泛型时缺少$type?

Cmd中的&ping.end()";有时会失败,而";ping";总是有效

在使用.NET EF Core DbContext属性之前,是否应使用null判断

在Swagger中显示自定义属性的属性名称

Firefox中的MudBlazor DataGrid单元格溢出