Share via


C#을 사용하여 원격으로 WMI에 연결

PowerShell, VBScript, C++를 비롯한 다른 언어와 마찬가지로 C#을 사용하여 원격 컴퓨터의 하드웨어 및 소프트웨어를 원격으로 모니터링할 수 있습니다. 관리형 코드에 대한 원격 연결은 Microsoft.Management.Infrastructure 네임스페이스를 통해 수행됩니다. (이전 버전의 WMI에서는 System.Management 네임스페이스를 사용했습니다. 이 네임스페이스는 정보의 완전성을 위해 이 문서에 포함되어 있습니다.)

참고

System.Management는 WMI에 액세스하는 데 사용되는 원래 .NET 네임스페이스였습니다. 그러나 이 네임스페이스의 API는 일반적으로 최신 네임스페이스인 Microsoft.Management.Infrastructure에 비해 더 느리고 스케일링 성능이 떨어집니다.

 

Microsoft.Management.Infrastructure 네임스페이스의 클래스를 사용한 원격 연결에서는 기본 원격 메커니즘으로 DCOM을 사용합니다. WMI 원격 연결은 가장 및 인증에 대한 DCOM 보안 요구 사항을 준수해야 합니다. 범위는 기본적으로 로컬 컴퓨터 및 “Root\CIMv2” 시스템 네임스페이스에 바인딩됩니다. 개발자는 액세스하려는 컴퓨터, 도메인 및 WMI 네임스페이스를 변경할 수 있습니다. 권한, 가장, 자격 증명 및 기타 연결 옵션도 설정할 수 있습니다.

C#을 사용하여 원격으로 WMI에 연결하려면 다음을 수행합니다(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);
    

    C#에서 Microsoft.Management.Infrastructure API를 사용하여 WMI 쿼리를 수행하는 방법에 대한 자세한 내용은 WMI 클래스 또는 인스턴스 데이터 검색을 참조하세요.

  2. 연결에 다른 자격 증명, 로캘 또는 가장 수준과 같은 다른 옵션을 설정하려면 CimSession.Create 호출에서 CimSessionOptions 개체를 사용해야 합니다.

    CimSessionOptionsWSManSessionOptionsDComSessionOptions의 기본 클래스입니다. 둘 중 하나를 사용하여 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 v1에 대한 원격 연결은 ManagementScope 개체를 통해 이루어집니다.

C#을 사용하여 원격으로 WMI에 연결하려면 다음을 수행합니다(System.Management).

  1. 컴퓨터 이름과 WMI 경로를 사용하여 ManagementScope 개체를 만들고, 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);
    

    C#에서 System.Management API를 사용하여 WMI 쿼리를 수행하는 방법에 대한 자세한 내용은 WMI 클래스 또는 인스턴스 데이터 검색을 참조하세요.

  2. 다른 도메인에 있는 원격 컴퓨터에 연결하거나 다른 사용자 이름 및 암호를 사용하는 경우에는 ManagementScope 호출에서 ConnectionOptions 개체를 사용해야 합니다.

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

    달리 명시적으로 필요하지 않은 한 일반적으로 가장 수준은 Impersonate로 설정하는 것이 좋습니다. 또한 C# 코드 안에 이름과 암호를 기재하지 않는 것이 좋습니다. (가능한 경우 사용자에게 쿼리하여 런타임 시 동적으로 제공하는 것이 좋습니다.)

    원격 WMI 연결에 여러 속성을 설정하는 더 많은 예제는 ConnectionOptions 참조 페이지의 예제 섹션을 참조하세요.

Microsoft.Management.Infrastructure 예제

TechNet 블로그 게시물을 기반으로 하는 다음 C# 코드 예제에서는 CimCredentialsWSManSessionOptions를 사용하여 원격 연결에서 자격 증명을 설정하는 방법을 설명합니다.

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에 연결