Как да извлека 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.FileNotFoundException: Мрежовият път не е намерен. в WSManAutomation.IWSManSession.Enumerate(Object resourceUri, String filter, String dialect, Int32 flags)

Мога успешно да пингвам машината, така че трябва да се вижда. Въпреки това, името на хоста е съпоставено само с неговия IP адрес в моя Windows hosts файл. Ако се опитам да създам сесия на тази машина с PowerShell, също възниква грешка:

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

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

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

Необработено изключение: System.Runtime.InteropServices.COMException: Възникна грешка в сигурността при 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()

какво правя грешно


person w128    schedule 15.04.2015    source източник


Отговори (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 трябва да бъде взет от ръководствата на целевата система.

person Vesper    schedule 22.05.2015