Как получить экземпляры CIM с хоста Linux с помощью WinRM?

Я использую WinRM API в попытке собрать несколько экземпляров CIM с нескольких хостов под управлением Windows или Linux. Мой код работает нормально при подключении к хосту Windows, но возникает исключение, если я пытаюсь подключиться к машине Linux, на которой работает сервер SFCB CIM. Я могу нормально получать экземпляры CIM с хоста Linux через WBEM, но не через WS-MAN/WinRM.

Вот пример кода, который получает CIM_OperatingSystem с хоста Windows - это работает нормально:

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.FileNotFound Exception: сетевой путь не найден. в WSManAutomation.IWSManSession.Enumerate(Object resourceUri, строковый фильтр, строковый диалект, флаги Int32)

Я могу успешно пинговать машину, поэтому она должна быть видна. Тем не менее, имя хоста отображается только на его IP в моей Windows hosts файл. Если я пытаюсь создать сеанс на этом компьютере с помощью PowerShell, также возникает ошибка:

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

new-cimsession: WinRM не может обработать запрос. При использовании проверки подлинности Kerberos произошла следующая ошибка: Не удается найти компьютер myLinuxHost. Убедитесь, что компьютер существует в сети и что указанное имя написано правильно.

  • если я укажу полный URL хоста (тот, который я могу получить с помощью WBEM экземпляров CIM), т.е. remoteHost = "https://<ip>:5989" или же remoteHost = "https://myLinuxHost:5989" перечисление не выполняется с:

Необработанное исключение: System.Runtime.InteropServices.COMException: ошибка безопасности произошла в WSManAutomation.IWSManSession.Enumerate(Object resourceUri, строковый фильтр, строковый диалект, флаги Int32)

Подробности:

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

Что я делаю неправильно?

1 ответ

Прочитав некоторые руководства о том, как установить сеанс Powershell на компьютере без WSMAN с помощью HTTPS CIMSessions, я обнаружил, что есть параметр типа CIMSessionOption который может быть сконструирован для использования SSL, так что фактическое соединение осуществляется через интерфейс WBEM через HTTPS. Документ здесь, коды следующие:

$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, вы должны преобразовать код Powershell, который создает CIMSessionOption и CIMSession, используя метод не-WSMAN. В Powershell это должно позволить вам подключаться к машине Linux, если предоставлены правильные учетные данные. ResourceUri Параметр указывает, какой объект вы хотите получить, и соответствующий URI должен быть взят из руководств в целевой системе.

Другие вопросы по тегам