共用方式為


使用 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

    如果您要使用您登入的相同認證(網域和使用者名稱)連線到遠端計算機,則可以在 [建立 呼叫] 中指定計算機的名稱。 傳回 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,將模擬層級設定為 [模擬]。

    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