Поделиться через


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

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

Заметка

System.Management — исходное пространство имен .NET, используемое для доступа к WMI; однако интерфейсы программирования приложений в этом пространстве имен обычно работают медленнее и масштабируются хуже по сравнению с их более современными аналогами в 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 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 для установки уровня имперсонализации на уровень "Олицетворение".

    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 на удаленном компьютере