使用 C 從遠端連線到 WMI#

如同 PowerShell、VBScript 或 C++ 等其他語言,您可以使用 C# 從遠端監視遠端電腦上的硬體和軟體。 Managed 程式碼的遠端連線是透過 Microsoft.Management.Infrastructure 命名空間來完成。 (舊版 WMI 使用 System.Management 命名空間,這裡提供完整性。)

注意

System.Management 是用來存取 WMI 的原始 .NET 命名空間;不過,此命名空間中的 API 通常較慢,而且不會相對於其較新式 的 Microsoft.Management.Infrastructure 對應專案進行調整。

 

使用 Microsoft.Management.Infrastructure 命名空間中的類別從遠端連線,會使用 DCOM 作為基礎遠端機制。 WMI 遠端連線必須符合模擬和驗證的 DCOM 安全性需求。 根據預設,範圍會系結至本機電腦和 「Root\CIMv2」 系統命名空間。 不過,您可以變更您存取的電腦、網域和 WMI 命名空間。 您也可以設定授權單位、模擬、認證和其他連線選項。

使用 C# (Microsoft.Management.Infrastructure) 從遠端連線到 WMI

  1. 使用 CimSession.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 物件將 Impersonation 層級設定為 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 v1 的遠端連線是透過 ManagementScope 物件來完成。

使用 C# (System.Management) 從遠端連線到 WMI

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

    一般而言,除非您明確需要,否則建議您將模擬層級設定為 [模擬]。 此外,請嘗試避免將您的名稱和密碼寫入 C# 程式碼。 (可能的話,請參閱您是否可以在執行時間查詢使用者以動態方式提供它們。)

    如需在遠端 WMI 連線上設定不同屬性的更多範例,請參閱 ConnectionOptions 參考頁面的一節。

Microsoft.Management.Infrastructure 範例

下列 C# 程式碼範例是根據 TechNet 上的下列部落格文章,說明如何使用 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