MANOJ GOPI
MANOJ GOPI

Reputation: 1279

Monitor Remote Service using WMI COM objects

I am trying to access the service status of the remote machine using WMI component (if there any alternative kindly suggest).

Below is my code:

public void MonitorService()
{
                ConnectionOptions con = new ConnectionOptions();
                con.Username = "username";
                con.Password = "password";
                con.Authority = "ntlmdomain:somedomain";
                con.Authentication = AuthenticationLevel.Connect;
                con.EnablePrivileges = true;
                con.Impersonation = ImpersonationLevel.Identify;
                ManagementScope scope = new ManagementScope(@"\\machinename\root\cimv2", con);
                scope.Connect();
                ManagementPath path = new ManagementPath("Win32_Service");
                ManagementClass services;
                services = new ManagementClass(scope, path, null);

                foreach (ManagementObject service in services.GetInstances())
                {

                    // some manipulations

                }
}


At scope.Connect(), i am getting Error "Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)"

The user which I am using in the ConnectionOption is having admin privilages on the remote system. I have allowed the user to access the WMI COM objects in the remote machine. I already gone through the link but not helped me. Please let me what I am missing.

Upvotes: 2

Views: 1170

Answers (3)

Mike Ness
Mike Ness

Reputation: 286

First, I would recommend against changing the Authentication property from its default value unless you're absolutely sure you need to do so. Documentation for this property says that Packet-level authentication is used for Windows XP and above while Connect-level authentication is used for Windows 2000 and below. The default setting will use whatever authentication the server specifies, which is more likely to work than dictating a specific authentication level that the server might not accept. It's also unusual that you would need to set the Authority property since by default it will use NTLM authentication against the domain of the current user, but doing so probably won't hurt anything. For the Impersonation property, I agree with Sameh that the value of ImpersonationLevel.Impersonate should be used (also the default). In general, you shouldn't have to change any ConnectionOptions property values unless you need to connect with a user account other than the one that the program is running as, and then you should only need to change Username and Password.

Second, I'm not exactly sure what you mean by "allowing the administrator access to WMI COM on the remote machine." In my experience, when remote WMI fails to connect it's usually because Windows firewall is getting in the way. If you haven't already, I'd also recommend running the command below on the machine you're trying to connect to (see link Connecting Through Windows Firewall from the page you originally linked to).

netsh firewall set service RemoteAdmin enable

With regards to APIs for services, the .NET framework includes the System.ServiceProcess.ServiceController class, which provides information about and control over a named service on a local or remote machine. However, it doesn't look like this API allows a user name and password to be specified when connecting, so if you aren't running the program as the connecting user this probably isn't a viable solution. If you are running the program as the account that needs to be used for the remote connection and want to try this class out, please note that you will have to add a reference to System.ServiceProcess since that isn't included in the default framework references for most new VS projects.

Upvotes: 0

Vikas Gupta
Vikas Gupta

Reputation: 4465

An alternative (as you requested) would be to use PowerShell remoting. Powershell remoting works in a fundamentally different way compared to WMI remoting.

Here is an example, which incidentally uses Get-Service cmdlet from C# to get service information from remote computer (defaults to localhost)

Upvotes: 0

Sameh
Sameh

Reputation: 1020

First, try to run visual studio as Administrator OR, run the output exe as Administrator.

Also you need to use Impersonation = ImpersonationLevel.Impersonate instead of Identity, so try the following code:

VB.NET:

Dim opt As ObjectGetOptions
 opt = New ObjectGetOptions(Nothing, TimeSpan.MaxValue, True)
 Using manClass As New ManagementClass("\\YOUR_MACHINE\root\cimv2", "Win32_Service", opt)
    manClass.Scope.Options.EnablePrivileges = True
    manClass.Scope.Options.Impersonation = ImpersonationLevel.Impersonate
    manClass.Scope.Options.Username = "username"
    manClass.Scope.Options.Password = "pass"
    manClass.Scope.Options.Authority = "ntlmdomain:Domain"
 End Using  

C#: (online conversion)

ObjectGetOptions opt = default(ObjectGetOptions);
opt = new ObjectGetOptions(null, TimeSpan.MaxValue, true);
using (ManagementClass manClass = new ManagementClass("\\\\YOUR_MACHINE\\root\\cimv2", "Win32_Service", opt)) {
    manClass.Scope.Options.EnablePrivileges = true;
    manClass.Scope.Options.Impersonation = ImpersonationLevel.Impersonate;
    manClass.Scope.Options.Username = "username";
    manClass.Scope.Options.Password = "pass";
    manClass.Scope.Options.Authority = "ntlmdomain:Domain";
}

For more information see the open source Windows Services Manager (Services+) on codeplex.

Upvotes: 1

Related Questions