简体   繁体   English

如何使用WinRM从Linux主机检索CIM实例?

[英]How to retrieve CIM instances from a Linux host using WinRM?

I'm using WinRM API in an attempt to collect some CIM instances from several hosts running either Windows or Linux. 我正在使用WinRM API,试图从运行Windows或Linux的几台主机中收集一些CIM实例。 My code works fine when connecting to a Windows host, but an exception is thrown if I try to connect to a Linux machine, which is running the SFCB CIM server. 连接到Windows主机时,我的代码工作正常,但是如果尝试连接到运行SFCB CIM服务器的Linux机器,则会引发异常。 I can retrieve CIM instances from the Linux host just fine via WBEM, but not via WS-MAN/WinRM. 我可以通过WBEM,但不能通过WS-MAN / WinRM从Linux主机中检索CIM实例。

Here's sample code that gets CIM_OperatingSystem from a Windows host - this works fine: 这是从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);
}   

If remoteHost points to a Linux machine (openSUSE VM in my example), here's what happens: 如果remoteHost指向Linux计算机(在我的示例中为openSUSE VM), remoteHost发生以下情况:

  • if I specify the hostname only, ie remoteHost = "myLinuxHost" , session.Enumerate() fails: 如果我仅指定主机名,即remoteHost = "myLinuxHost" ,则session.Enumerate()失败:

Unhandled Exception: System.IO.FileNotFoundException: The network path was not found. 未处理的异常:System.IO.FileNotFoundException:找不到网络路径。 at WSManAutomation.IWSManSession.Enumerate(Object resourceUri, String filter, String dialect, Int32 flags) 在WSManAutomation.IWSManSession.Enumerate(对象resourceUri,字符串过滤器,字符串方言,Int32标志)

I can ping the machine successfully, so it should be visible. 我可以成功ping通计算机,因此它应该可见。 However, the hostname is only mapped to its IP in my Windows hosts file. 但是,主机名仅映射到我的Windows hosts文件中的IP。 If I try to create a session to this machine with PowerShell, an error occurs as well: 如果我尝试使用PowerShell创建到此计算机的会话,也会发生错误:

PS C:\Windows\system32> $session = new-cimsession myLinuxHost -credential user

new-cimsession : WinRM cannot process the request. new-cimsession:WinRM无法处理该请求。 The following error occurred while using Kerberos authentication: Cannot find the computer myLinuxHost. 使用Kerberos身份验证时发生以下错误:找不到计算机myLinuxHost。 Verify that the computer exists on the network and that the name provided is spelled correctly. 验证计算机在网络上,并且提供的名称拼写正确。

  • if I specify the complete host URL (one that I can retrieve CIM instances with using WBEM), ie remoteHost = "https://<ip>:5989" or remoteHost = "https://myLinuxHost:5989" enumeration fails with: 如果我指定了完整的主机URL(我可以使用WBEM检索CIM实例的主机URL),即remoteHost = "https://<ip>:5989"remoteHost = "https://myLinuxHost:5989"枚举将失败,并显示以下内容:

Unhandled Exception: System.Runtime.InteropServices.COMException: A security error occurred at WSManAutomation.IWSManSession.Enumerate(Object resourceUri, String filter, String dialect, Int32 flags) 未处理的异常:System.Runtime.InteropServices.COMException:WSManAutomation.IWSManSession.Enumerate(对象resourceUri,字符串过滤器,字符串方言,Int32标志)发生安全错误

Details: 细节:

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()

What am I doing wrong? 我究竟做错了什么?

After reading some manuals on how to establish a Powershell session to a non-WSMAN machine by using HTTPS CIMSessions, I have found that there is a parameter of type CIMSessionOption which can be constructed to use SSL, so that the actual connection is done via WBEM interface over HTTPS. 在阅读了一些有关如何使用HTTPS CIMSessions与非WSMAN机器建立Powershell会话的手册之后,我发现有一个CIMSessionOption类型的参数可以构造为使用SSL,因此实际的连接是通过WBEM完成的。通过HTTPS的接口。 The document is here , the codes are as follows: 文件在这里 ,代码如下:

$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"

So, in order to make your C# program to connect via WBEM, you have to translate Powershell code that creates the CIMSessionOption and CIMSession using non-WSMAN method. 因此,为了使您的C#程序通过WBEM连接,您必须转换使用非WSMAN方法创建CIMSessionOption和CIMSession的Powershell代码。 In Powershell this should let you connect to the Linux machine if provided proper credentials. 在Powershell中,如果提供了适当的凭据,则应该可以连接到Linux计算机。 The ResourceUri parameter specifies what object you want to retrieve, and the proper URI should be taken from manuals on the target system. ResourceUri参数指定要检索的对象,并且应从目标系统的手册中获取适当的URI。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM