我正在使用WinRM API尝试从运行Windows或Linux的多个主机中收集一些CIM实例。连接到Windows主机时,我的代码工作正常,但如果我尝试连接到运行SFCB CIM服务器的Linux机器,则会引发异常。我可以通过WBEM从Linux主机上检索CIM实例,但不能通过WS-MAN / WinRM检索。
以下是从Windows主机获取CIM_OperatingSystem
的示例代码 - 这很好用:
WSMan wsman = new WSMan();
IWSManConnectionOptions options = (IWSManConnectionOptions)wsman.CreateConnectionOptions();
try
{
string remoteHost = "WindowsHost1";
options.UserName = @"domain\User";
options.Password = "somePwd";
IWSManSession session = (IWSManSession)wsman.CreateSession(remoteHost, wsman.SessionFlagCredUsernamePassword(), options);
try
{
IWSManEnumerator cimInstances = session.Enumerate("http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/CIM_OperatingSystem");
// Enumerate returned CIM instances.
while (!cimInstances.AtEndOfStream)
{
string item = cimInstances.ReadItem();
XDocument doc = XDocument.Parse(item);
var resultSet = from e in doc.Elements() select e;
foreach (var element in resultSet)
{
Console.WriteLine(element);
}
}
}
finally
{
Marshal.ReleaseComObject(session);
}
}
finally
{
Marshal.ReleaseComObject(options);
}
如果remoteHost
指向Linux机器(在我的示例中为openSUSE VM),那么会发生什么:
remoteHost = "myLinuxHost"
,则session.Enumerate()
失败:未处理的异常:System.IO.FileNotFoundException:网络路径 没找到。在WSManAutomation.IWSManSession.Enumerate(对象 resourceUri,String filter,String dialect,Int32 flags)
我可以成功ping机器,因此它应该是可见的。但是,主机名仅映射到Windows hosts
文件中的IP。如果我尝试使用PowerShell创建与此计算机的会话,也会发生错误:
PS C:\Windows\system32> $session = new-cimsession myLinuxHost -credential user
new-cimsession:WinRM无法处理请求。下列 使用Kerberos身份验证时出错:找不到 电脑myLinuxHost。验证网络上是否存在计算机 并且提供的名称拼写正确。
remoteHost = "https://<ip>:5989"
或remoteHost = "https://myLinuxHost:5989"
枚举失败,则:未处理的异常:System.Runtime.InteropServices.COMException:A 安全错误发生在 WSManAutomation.IWSManSession.Enumerate(Object resourceUri,String filter,String dialect,Int32 flags)
详细说明:
System.Runtime.InteropServices.COMException was unhandled
HResult=-2147012721
Message=A security error occurred
Source=Session
ErrorCode=-2147012721
StackTrace:
at WSManAutomation.IWSManSession.Enumerate(Object resourceUri, String filter, String dialect, Int32 flags)
at WSManTest.Program.Main(String[] args)
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
我做错了什么?
答案 0 :(得分:0)
在阅读了一些关于如何使用HTTPS CIMSessions建立与非WSMAN机器的Powershell会话的手册之后,我发现有一个CIMSessionOption
类型的参数可以被构造为使用SSL,因此实际连接是通过HTTPS上的WBEM接口完成的。该文件为here,代码如下:
$UserName="root"
$Password="calvin" # default password
$DracIP="10.10.0.120" # supply your box's IP
$SecurePass = ConvertTo-SecureString $Password -AsPlainText -Force
$DracCred = new-object -typename System.Management.Automation.PSCredential -argumentlist $UserName,$SecurePass
# this just makes a PSCredential object to be used as a reference
$cimop=New-CimSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck -Encoding Utf8 -UseSsl
# this instruction creates a SSL-enabled option set with ignore certificate checks (Dells have self-signed certs on their side)
$Dracsession=New-CimSession -Authentication Basic -Credential $DracCred -ComputerName $DracIP -Port 443 -SessionOption $cimop -OperationTimeoutSec 10000000
Get-CimInstance -CimSession $Dracsession -ResourceUri "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/root/dcim/DCIM_SystemView"
因此,为了使您的C#程序通过WBEM连接,您必须使用非WSMAN方法转换创建CIMSessionOption和CIMSession的Powershell代码。在Powershell中,如果提供了适当的凭据,这应该允许您连接到Linux机器。 ResourceUri
参数指定要检索的对象,并且应从目标系统上的手册中获取正确的URI。