我正在使用IIS在服务器上运行的C# ASP.NET Application中try 使用WMI查询本地域上计算机的硬件数据.
在使用New-CimSession
cmdlet成功打开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的不同方法,但对于我的用例来说,使用CimSession
和QueryInstances
方法似乎是最直接的.尽管如此,我找到的所有其他代码示例都导致了相同的错误.
任何帮助都将不胜感激--谢谢!
更新
正如@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#中工作