Удаленное подключение к WMI с помощью C #

Как и в случае с другими языками, такими как PowerShell, VBScript или C++, C# можно использовать для удаленного мониторинга оборудования и программного обеспечения на удаленных компьютерах. Удаленные подключения для управляемого кода выполняются через пространство имен Microsoft.Management.Infrastructure . (В предыдущих версиях инструментария WMI использовалось пространство имен System.Management , которое включено здесь для полноты.)

Примечание

System.Management — это исходное пространство имен .NET, используемое для доступа к WMI; Однако API-интерфейсы в этом пространстве имен обычно работают медленнее и не масштабируются по сравнению с более современными аналогами Microsoft.Management.Infrastructure .

 

Удаленное подключение с помощью классов в пространстве имен Microsoft.Management.Infrastructure использует DCOM в качестве базового удаленного механизма. Удаленные подключения WMI должны соответствовать требованиям безопасности DCOM в отношении проверки подлинности и олицетворения. По умолчанию область привязан к локальному компьютеру и пространству имен "Root\CIMv2". Однако вы можете изменить как компьютер, домен, так и пространство имен WMI, к которому вы обращаетесь. Вы также можете задать центр, олицетворение, учетные данные и другие параметры подключения.

Удаленное подключение к WMI с помощью C# (Microsoft.Management.Infrastructure)

  1. Создайте сеанс на удаленном компьютере с вызовом CimSession.Create.

    Если вы подключаетесь к удаленному компьютеру, используя те же учетные данные (домен и имя пользователя), с помощью которых вы выполнили вход, вы можете указать имя компьютера в вызове Create . Получив возвращенный объект CimSession , можно выполнить запрос WMI.

    using Microsoft.Management.Infrastructure;
    ...
    string Namespace = @"root\cimv2";
    string OSQuery = "SELECT * FROM Win32_OperatingSystem";
    CimSession mySession = CimSession.Create("Computer_B");
    IEnumerable<CimInstance> queryInstance = mySession.QueryInstances(Namespace, "WQL", OSQuery);
    

    Дополнительные сведения о создании запросов WMI с помощью API Microsoft.Management.Infrastructure в C# см. в статье Получение данных класса или экземпляра WMI.

  2. Если вы хотите задать разные параметры подключения, например разные учетные данные, языковой стандарт или уровни олицетворения, необходимо использовать объект CimSessionOptions в вызове CimSession.Create.

    CimSessionOptions — это базовый класс для WSManSessionOptions и DComSessionOptions. Вы можете использовать любой из этих вариантов, чтобы задать параметры для сеансов WS-Man и DCOM соответственно. В следующем примере кода описывается использование объекта DComSessionOptions для задания уровня олицетворения значения Impersonate.

    string computer = "Computer_B"
    DComSessionOptions DComOptions = new DComSessionOptions();
    DComOptions.Impersonation = ImpersonationType.Impersonate;
    
    CimSession Session = CimSession.Create(computer, DComOptions);
    
  3. Если вы хотите задать учетные данные для подключения, необходимо создать и добавить объект CimCredentials в CimSessionOptions.

    В следующем примере кода описывается создание класса WSManSessionOptions , заполнение его соответствующим CimSessionOptions и его использование в вызове CimSession.Create .

    string computer = “Computer_B”;
    string domain = “Domain1″;
    string username = “User1″;
    
    string plaintextpassword; 
    
    //Retrieve password from the user. 
    //For the complete code, see the sample at the bottom of this topic.
    
    CimCredential Credentials = new CimCredential(PasswordAuthenticationMechanism.Default, domain, username, securepassword); 
    
    WSManSessionOptions SessionOptions = new WSManSessionOptions();
    SessionOptions.AddDestinationCredentials(Credentials); 
    
    CimSession Session = CimSession.Create(computer, SessionOptions);
    

    Как правило, не рекомендуется жестко указывать пароль в приложениях. Как показано в приведенном выше примере кода, по возможности попробуйте запросить у пользователя пароль и сохранить его в безопасном виде.

Инструментарий WMI предназначен для наблюдения за аппаратным и программным обеспечением на удаленных компьютерах. Удаленные подключения для WMI версии 1 выполняются с помощью объекта ManagementScope .

Удаленное подключение к WMI с помощью C# (System.Management)

  1. Создайте объект ManagementScope , используя имя компьютера и путь WMI, и подключитесь к целевому объекту с помощью вызова ManagementScope.Connect().

    Если вы подключаетесь к удаленному компьютеру, используя те же учетные данные (домен и имя пользователя), с помощью которых вы выполнили вход, достаточно указать путь WMI. После подключения можно выполнить запрос WMI.

    using System.Management;
    ...
    ManagementScope scope = new ManagementScope("\\\\Computer_B\\root\\cimv2");
    scope.Connect();
    ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
    

    Дополнительные сведения о выполнении запросов WMI с помощью API System.Management в C# см. в статье Получение данных класса или экземпляра WMI.

  2. Если вы подключаетесь к удаленному компьютеру в другом домене или используете другое имя пользователя и пароль, необходимо использовать объект ConnectionOptions в вызове ManagementScope.

    ConnectionOptions содержит свойства для описания проверки подлинности, олицетворения, имени пользователя, пароля и других параметров подключения. В следующем примере кода описывается использование ConnectionOptions для задания уровня олицетворения значения Impersonate.

    ConnectionOptions options = new ConnectionOptions();
    options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
    
    ManagementScope scope = new ManagementScope("\\\\FullComputerName\\root\\cimv2", options);
    scope.Connect();
    
    ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope,query);
    

    Как правило, рекомендуется задать для уровня олицетворения значение Олицетворение, если в противном случае не требуется явно. Кроме того, старайтесь не записывать имя и пароль в код C#. (Если возможно, вы можете запросить у пользователя динамическое предоставление их во время выполнения.)

    Дополнительные примеры настройки различных свойств для удаленного WMI-подключения см. в разделе Примеры на странице справочника ConnectionOptions .

Пример Microsoft.Management.Infrastructure

В следующем примере кода C# на основе следующей записи блога на сайте TechNetописывается использование CimCredentials и WSManSessionOptions для установки учетных данных для удаленного подключения.

using System;
using System.Text;
using System.Threading;
using Microsoft.Management.Infrastructure;
using Microsoft.Management.Infrastructure.Options;
using System.Security; 

namespace SMAPIQuery
{
    class Program
    {
        static void Main(string[] args)
        { 

            string computer = "Computer_B";
            string domain = "DOMAIN";
            string username = "AdminUserName";


            string plaintextpassword; 

            Console.WriteLine("Enter password:");
            plaintextpassword = Console.ReadLine(); 

            SecureString securepassword = new SecureString();
            foreach (char c in plaintextpassword)
            {
                securepassword.AppendChar(c);
            } 

            // create Credentials
            CimCredential Credentials = new CimCredential(PasswordAuthenticationMechanism.Default, 
                                                          domain, 
                                                          username, 
                                                          securepassword); 

            // create SessionOptions using Credentials
            WSManSessionOptions SessionOptions = new WSManSessionOptions();
            SessionOptions.AddDestinationCredentials(Credentials); 

            // create Session using computer, SessionOptions
            CimSession Session = CimSession.Create(computer, SessionOptions); 

            var allVolumes = Session.QueryInstances(@"root\cimv2", "WQL", "SELECT * FROM Win32_Volume");
            var allPDisks = Session.QueryInstances(@"root\cimv2", "WQL", "SELECT * FROM Win32_DiskDrive"); 

            // Loop through all volumes
            foreach (CimInstance oneVolume in allVolumes)
            {
                // Show volume information

                if (oneVolume.CimInstanceProperties["DriveLetter"].ToString()[0] > ' '  )
                {
                    Console.WriteLine("Volume ‘{0}’ has {1} bytes total, {2} bytes available", 
                                      oneVolume.CimInstanceProperties["DriveLetter"], 
                                      oneVolume.CimInstanceProperties["Size"], 
                                      oneVolume.CimInstanceProperties["SizeRemaining"]);
                }

            } 

            // Loop through all physical disks
            foreach (CimInstance onePDisk in allPDisks)
            {
                // Show physical disk information
                Console.WriteLine("Disk {0} is model {1}, serial number {2}", 
                                  onePDisk.CimInstanceProperties["DeviceId"], 
                                  onePDisk.CimInstanceProperties["Model"].ToString().TrimEnd(), 
                                  onePDisk.CimInstanceProperties["SerialNumber"]);
            } 

            Console.ReadLine();
         }
     }
 }

Пример System.Management

В следующем примере кода C# описывается общее удаленное подключение с использованием объектов System.Management.

using System;
using System.Management;
public class RemoteConnect 
{
    public static void Main() 
    {
        ConnectionOptions options = new ConnectionOptions();
        options.Impersonation = System.Management.ImpersonationLevel.Impersonate;

        
        ManagementScope scope = new ManagementScope("\\\\FullComputerName\\root\\cimv2", options);
        scope.Connect();

        //Query system for Operating System information
        ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope,query);

        ManagementObjectCollection queryCollection = searcher.Get();
        foreach ( ManagementObject m in queryCollection)
        {
            // Display the remote computer information
            Console.WriteLine("Computer Name     : {0}", m["csname"]);
            Console.WriteLine("Windows Directory : {0}", m["WindowsDirectory"]);
            Console.WriteLine("Operating System  : {0}", m["Caption"]);
            Console.WriteLine("Version           : {0}", m["Version"]);
            Console.WriteLine("Manufacturer      : {0}", m["Manufacturer"]);
        }
    }
}

Подключение к WMI на удаленном компьютере