Reputation: 1279
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
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
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
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