How To: Connect to a Remote Computer
The document is archived and information here might be outdated

How To: Connect to a Remote Computer

.NET Framework 2.0

WMI is intended to monitor the hardware and software on remote computers. Remote connections for WMI in .NET Framework are accomplished through the ManagementScope object.

Connecting remotely using classes in the System.Management namespace uses DCOM as the underlying remote mechanism. WMI remote connections must comply with DCOM security requirements for impersonation and authentication. Connections between different operating systems, for example, a connection initiated from a Windows 2000 computer to a Windows Server 2003 computer, may require a different impersonation and authentication level than a connection between two Windows 2000 computers. For more information, see "Connecting to WMI on a Remote Computer" in the Windows Management Instrumentation documentation in the MSDN Library at

By default, a scope is bound to the local computer and the root\cimv2 system namespace. However, you can either change the namespace in the string that specifies the constructor path or use a ManagementPath object. The string used for the path follows the same rules as other WMI paths and backslashes (\) must be escaped. For more information, see "Describing the Location of a WMI Object" in the Windows Management Instrumentation documentation in the MSDN Library at

In addition, when connecting remotely, you can specify credentials for a user other than the currently logged-on user, and the operations on that remote machine will be performed in the context of the specified user. This can be done using a ConnectionOptions object.


The following code example connects to a remote computer in the same domain as the user and displays information about the operating system on the remote computer. The user must be an administrator on the remote computer for the connection to be made.

using System;
using System.Management;
public class RemoteConnect 
    public static void Main() 
        /*// Build an options object for the remote connection
        //   if you plan to connect to the remote
        //   computer with a different user name
        //   and password than the one you are currently using
             ConnectionOptions options = 
                 new ConnectionOptions();
             // and then set the options.Username and 
             // options.Password properties to the correct values
             // and also set 
             // options.Authority = "ntdlmdomain:DOMAIN";
             // and replace DOMAIN with the remote computer's
             // domain.  You can also use kerberose instead
             // of ntdlmdomain.

        // Make a connection to a remote computer.
        // Replace the "FullComputerName" section of the
        // string "\\\\FullComputerName\\root\\cimv2" with
        // the full computer name or IP address of the
        // remote computer.
        ManagementScope scope = 
            new ManagementScope(

        // Use this code if you are connecting with a 
        // different user name and password:
        // 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}", 
            Console.WriteLine("Windows Directory : {0}", 
            Console.WriteLine("Operating System: {0}",  
            Console.WriteLine("Version: {0}", m["Version"]);
            Console.WriteLine("Manufacturer : {0}", 

The ConnectionOptions object also controls the impersonation and authentication levels used by WMI in the remote DCOM operations. The default settings for these parameters are Impersonate and Unchanged respectively.

The Unchanged value means that the client defaults to the server's requirements for authentication, using the standard DCOM negotiation process. On Windows 2000, Windows NT 4.0, and Windows 98, the WMI service will request Connect level authentication, while on Windows XP Home Edition, Windows XP Professional, Windows Server 2003 and Windows Server 2003 it will request Packet level authentication. If the client requires a specific authentication setting, the Authentication property on the ConnectionOptions object can be used to control the authentication level on this particular connection.

The Impersonate value means that the client allows the WMI data provider to impersonate its identity when gathering the requested information. This default setting is advantageous when the provider is a trusted application or service because it eliminates the need for the provider to perform explicit identity and access checks when retrieving information for this client. However, if the addressed provider or instrumented application cannot be trusted for some reason, allowing it to impersonate the client may constitute a security threat. In such cases, we recommend that the impersonation level be changed by the client application to a lower value, such as Identify. Note that this may lead to the inability to access information from certain providers, in cases where the provider does not perform access checks or does not have sufficient permissions in its own running context to retrieve the requested information.

The following code example connects to a remote computer and displays information about the operating system on the remote computer. The code also creates a form to gather the user name and password information for the connection.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Management;

namespace WMISample
    public class MyQuerySample : System.Windows.Forms.Form
        private System.Windows.Forms.Label userNameLabel;
        private System.Windows.Forms.TextBox userNameBox;
        private System.Windows.Forms.TextBox passwordBox;
        private System.Windows.Forms.Label passwordLabel;
        private System.Windows.Forms.Button OKButton;
        private System.Windows.Forms.Button cancelButton;
        private System.ComponentModel.Container components = null;

        public MyQuerySample()

        protected override void Dispose( bool disposing )
            if( disposing )
                if (components != null)
            base.Dispose( disposing );

        private void InitializeComponent()
            this.userNameLabel = new System.Windows.Forms.Label();
            this.userNameBox = new System.Windows.Forms.TextBox();
            this.passwordBox = new System.Windows.Forms.TextBox();
            this.passwordLabel = new System.Windows.Forms.Label();
            this.OKButton = new System.Windows.Forms.Button();
            this.cancelButton = new System.Windows.Forms.Button();
            // userNameLabel
            this.userNameLabel.Location = new System.Drawing.Point(16, 8);
            this.userNameLabel.Name = "userNameLabel";
            this.userNameLabel.Size = new System.Drawing.Size(160, 32);
            this.userNameLabel.TabIndex = 0;
            this.userNameLabel.Text = 
                "Enter the user name for the remote computer:";
            // userNameBox
            this.userNameBox.Location = new System.Drawing.Point(160, 16);
            this.userNameBox.Name = "userNameBox";
            this.userNameBox.Size = new System.Drawing.Size(192, 20);
            this.userNameBox.TabIndex = 1;
            this.userNameBox.Text = "";
            // passwordBox
            this.passwordBox.Location = new System.Drawing.Point(160, 48);
            this.passwordBox.Name = "passwordBox";
            this.passwordBox.PasswordChar = '*';
            this.passwordBox.Size = new System.Drawing.Size(192, 20);
            this.passwordBox.TabIndex = 3;
            this.passwordBox.Text = "";
            // passwordLabel
            this.passwordLabel.Location = new System.Drawing.Point(16, 48);
            this.passwordLabel.Name = "passwordLabel";
            this.passwordLabel.Size = new System.Drawing.Size(160, 32);
            this.passwordLabel.TabIndex = 2;
            this.passwordLabel.Text = 
                "Enter the password for the remote computer:";
            // OKButton
            this.OKButton.Location = new System.Drawing.Point(40, 88);
            this.OKButton.Name = "OKButton";
            this.OKButton.Size = new System.Drawing.Size(128, 23);
            this.OKButton.TabIndex = 4;
            this.OKButton.Text = "OK";
            this.OKButton.Click += 
                new System.EventHandler(this.OKButton_Click);
            // cancelButton
            this.cancelButton.DialogResult = 
            this.cancelButton.Location = new System.Drawing.Point(200, 88);
            this.cancelButton.Name = "cancelButton";
            this.cancelButton.Size = new System.Drawing.Size(128, 23);
            this.cancelButton.TabIndex = 5;
            this.cancelButton.Text = "Cancel";
            this.cancelButton.Click += 
                new System.EventHandler(this.cancelButton_Click);
            // MyQuerySample
            this.AcceptButton = this.OKButton;
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.CancelButton = this.cancelButton;
            this.ClientSize = new System.Drawing.Size(368, 130);
            this.ControlBox = false;
            this.Name = "MyQuerySample";
            this.StartPosition = 
            this.Text = "Remote Connection";


        static void Main() 
            Application.Run(new MyQuerySample());

        private void OKButton_Click(object sender, System.EventArgs e)
                ConnectionOptions connection = new ConnectionOptions();
                connection.Username = userNameBox.Text;
                connection.Password = passwordBox.Text;
                connection.Authority = "ntlmdomain:DOMAIN";

                ManagementScope scope = new ManagementScope(
                    "\\\\FullComputerName\\root\\CIMV2", connection);

                ObjectQuery query= new ObjectQuery(
                    "SELECT * FROM Win32_Service"); 

                ManagementObjectSearcher searcher = 
                    new ManagementObjectSearcher(scope, query);

                foreach (ManagementObject queryObj in searcher.Get())
                    Console.WriteLine("Win32_Service instance");
                    Console.WriteLine("Caption: {0}", queryObj["Caption"]);
                    Console.WriteLine("Description: {0}", queryObj["Description"]);
                    Console.WriteLine("Name: {0}", queryObj["Name"]);
                    Console.WriteLine("PathName: {0}", queryObj["PathName"]);
                    Console.WriteLine("State: {0}", queryObj["State"]);
                    Console.WriteLine("Status: {0}", queryObj["Status"]);
            catch(ManagementException err)
                MessageBox.Show("An error occured while querying for WMI data: "
                    + err.Message);
            catch(System.UnauthorizedAccessException unauthorizedErr)
                MessageBox.Show("Connection error " + 
                    "(user name or password might be incorrect): " +

        private void cancelButton_Click(object sender, System.EventArgs e)

For more information on the impersonation and authentication levels used by WMI in the remote connection, see the Comments section in the previous code example.

Compiling the Code

The example requires references to the System and System.Management namespaces.

See Also

© 2016 Microsoft