Problem starting an exe file on remote machine using wmi - c#

I followed some articles here and managed to start notepad.exe on a remote machine.
I am trying to start a third-party software we bought and installed on the remote machine once it restarts, but it's not running the exe..
object[] theProcessToRun = { #"C:\Program Files (x86)\xyz\xyz.exe" };
var connection = new ConnectionOptions
{
Username = "username",
Password = "password",
Authority = ""ntlmdomain:.local"",
};
var scope = new ManagementScope("\\\\IP\\root\\CIMV2", connection);
scope.Connect();
using (var managementClass = new ManagementClass(scope, new ManagementPath("Win32_Process"), new ObjectGetOptions()))
{
managementClass.InvokeMethod("Create", theProcessToRun);
}

Related

setup other computer network and configure the ip address programatically C#

I have some sample codes where I can change my own ip address.
Now i have a problem regarding changing the ip address of my networks.
When i mean networks (Computers that are connected to the lan)
I want to connect and configure their ip address as well.
Example
I have 2 computers and the ip addresses are 192.168.1.6 - Computer 1 and 192.168.1.7 - Computer 2. So now I am at computer 1 and I want to connect to 192.168.1.7 and change the ip address to 192.168.1.8
CODE
private void button1_Click_1(object sender, EventArgs e)
{
//example of ip 10.11.3.120
try
{
setIP();
setGateway();
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
setIP();
setGateway();
MessageBox.Show("Update Success");
}
}
private void setIP()
{
ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if ((bool)objMO["IPEnabled"])
{
try
{
ManagementBaseObject setIP;
ManagementBaseObject newIP =
objMO.GetMethodParameters("EnableStatic");
//string ip_address = "10.11.3.120";
//string subnet_mask = "255.255.255.0";
newIP["IPAddress"] = new string[] { textBox1.Text };
newIP["SubnetMask"] = new string[] { textBox2.Text };
setIP = objMO.InvokeMethod("EnableStatic", newIP, null);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
public void setGateway()
{
ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if ((bool)objMO["IPEnabled"])
{
try
{
ManagementBaseObject setGateway;
ManagementBaseObject newGateway =
objMO.GetMethodParameters("SetGateways");
newGateway["DefaultIPGateway"] = new string[] { textBox3.Text };
newGateway["GatewayCostMetric"] = new int[] { 1 };
setGateway = objMO.InvokeMethod("SetGateways", newGateway, null);
}
catch (Exception)
{
throw;
}
}
}
}
This is not a direct answer. However, you should have all the information you need here
Connecting to WMI Remotely with C#
In short you will need create a system ManagementScope
Note System.Management was the original .NET namespace used to access
WMI; however, the APIs in this namespace generally are slower and do
not scale as well relative to their more modern
Microsoft.Management.Infrastructure counterparts.
However
Create a ManagementScope object, using the name of the computer and the WMI path, and connect to your target with a call to ManagementScope.Connect().
If you connect to a remote computer in a different domain or using a different user name and password, then you must use a ConnectionOptions object in the call to the ManagementScope.
The ConnectionOptions contains properties for describing the
Authentication, Impersonation, username, password, and other
connection options.
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
// options takes more arguments, you need to read up on what you want
ManagementScope scope = new ManagementScope("\\\\FullComputerName\\root\\cimv2", options);
scope.Connect();
ManagementPath path = new ManagementPath("Win32_NetworkAdapterConfiguration");
ObjectGetOptions o = new ObjectGetOptions(null, System.TimeSpan.MaxValue, true);
ManagementClass objMC = new ManagementClass(scope, path, o);
...
Generally speaking, it is recommended that you set your Impersonation
level to Impersonate unless explicitly needed otherwise
Additional reading
Connecting to WMI Remotely with C#
ManagementScope Class
ConnectionOptions Class
ObjectGetOptions Class
ManagementPath Class
ManagementClass Class
Disclaimer : You will have to read about these topics and work out what you need in your situation.

How to start a process on a remote server?

I'm trying to start command prompt process, remotely to a server and write a write a command to it and execute. The problem I have is that the process starts as background process.
Even tho, as a background process is possible to write a command into .cmd and execute it?
Hope I been explicit enough.
Here is my code.
var connection = new ConnectionOptions();
connection.Username = #"xxxx";
connection.Password = "xxxxx";
ManagementScope WMIscope = new ManagementScope(string.Format("\\\\{0}\\root\\cimv2", REMOTE_SERVER_NAME), connection);
WMIscope.Connect();
ManagementClass WMIprocess = new ManagementClass(WMIscope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
object[] process = { "cmd.exe" };
object result = WMIprocess.InvokeMethod("Create", process);

How to restart service remotely?

I can start or stop service remotely from .net project.
ConnectionOptions options = new ConnectionOptions();
options.Username = #"192.168.36.22\test";
options.Password = "test";
ManagementScope scope = new ManagementScope(#"\\192.168.36.22\root\cimv2", options);
scope.Connect();
ManagementOperationObserver Stop = new ManagementOperationObserver();
Stop.Completed += new CompletedEventHandler(Stop_CallBack);
try
{
string NameServices = "ArcGIS Server";
WqlObjectQuery query = new WqlObjectQuery("SELECT * FROM Win32_Service WHERE Name=\"" + NameServices + "\"");
ManagementObjectSearcher find = new ManagementObjectSearcher(scope, query);
foreach (ManagementObject spooler in find.Get())
{
spooler.InvokeMethod("StopService", new object[] { });
spooler.InvokeMethod(Start, "StopService", new object[] { });
}
}
....
How can I restart this service?
You could use the ServiceController class like so:
ServiceController sc = new ServiceController("ArcGIS Server", "192.168.36.22");
sc.Start();
sc.Stop();
This saves you having to write all that code to interact with WMI. Note to use the ServiceController class, you'll have to add a reference to the System.ServiceProcess assembly.
Service controller didn't work for me, so I used Cmd to do it.
Process.Start("CMD.exe", "/C sc \\\\remoteMachine stop \"serviceName\"&sc \\\\remoteMachine start \"serviceName\"");
To overcome credentials issue, I used class from this https://stackoverflow.com/a/5433640/2179222 answer.
So in the end It looked like this:
private static void RestartService(string remoteMachine, string serviceName, string userName, string password)
{
using (new NetworkConnection($"\\\\{remoteMachine}", new NetworkCredential(userName, password)))
{
Process.Start("CMD.exe", $"/C sc \\\\{remoteMachine} stop \"{serviceName}\"&sc \\\\{remoteMachine} start \"{serviceName}\"");
}
}
I have come across a similar problem when I tried to connect, just add your machine name as admin in the 'users' group of the target machine and you will be able to fetch the data.

C# WMI Win32_ScheduledJob properties

ConnectionOptions connOptions = new ConnectionOptions();
connOptions.Username = _username;
connOptions.Password = _password;
connOptions.Impersonation = ImpersonationLevel.Impersonate;
connOptions.Authentication = AuthenticationLevel.PacketPrivacy;
connOptions.EnablePrivileges = true;
ManagementScope manScope = new ManagementScope(_server, connOptions);
manScope.Connect();
ObjectGetOptions objectGetOptions = new ObjectGetOptions();
ManagementPath managementPath = new ManagementPath("Win32_ScheduledJob");
ManagementClass processClass = new ManagementClass(manScope, managementPath, objectGetOptions);
ManagementBaseObject inParams = processClass.GetMethodParameters("Create");
inParams["Name"] = "TESTER";
inParams["Owner"] = "Tester";
inParams["Command"] = command;
inParams["StartTime"] = "********171000.000000-300";
I'm tyring to connect to a remote system to create a scheduled task. I can create the scheduled tasks, but its being created with user - SYSTEM. I want it to be created under my user. I tried using the properties like 'Owner' and 'Name' eg:
inParams["Owner"] = ;
inParams["Name"] = ;
But they throw a ManagementException, "Not Found". Does anyone know how I can do this, or what might be wrong that I'm doing here...
Thanks
Creating a scheduled job with the Win32_ScheduledJob WMI class is equivalent to create job using the AT command. The AT service normally run under the Local\System account or the NetworkService Account. so when you uses this class your jobs are created using one of these accounts for more info about this topic you can check the remarks part of the MSDN documentation.

C# WMI privileges

I have searched through numerous questions about how to convert VBS to C# and all that good stuff.
The issue that I'm having is that with the VBS code (see below) when the process is executed on the remote machine it's run with the SYSTEM account.
When I execute with C# it's run with my credentials (or whomever runs the C# program).
The VBS seems to be more reliable in getting remote installs to go through which is what i need it for.
I wanted to switch to C# so I could make a more user friendly GUI for the program.
Anyone know how to get C# to run WMI with the SYSTEM account?
VBS Code:
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objScheduledJob = objWMIService.Get("Win32_ScheduledJob")
Set objSWbemDateTime = CreateObject("WbemScripting.SWbemDateTime")
'add the scheduled job to be run
objSWbemDateTime.SetVarDate(DateAdd(INTERVAL, MINUTES, Now()))
errReturn = objScheduledJob.Create(strCommand, objSWbemDateTime.Value, False, 0, 0, True, intJobID)
C# code:
static public int RemoteAdmin(string remoteMachine, string runFile)
{
try
{
ManagementPath run = new ManagementPath(#"\\" + remoteMachine + #"\root\cimv2:Win32_process");
ManagementClass man = new ManagementClass(run);
man.InvokeMethod("Create", new Object[] { runFile });
return 0;
}
catch
{
MessageBox.Show("Error in remote execution");
return 1;
}
}
You need to setup the ConnectionOptions
ConnectionOptions wmiConnOpts = new ConnectionOptions();
wmiConnOpts.Impersonation = ImpersonationLevel.Impersonate;
wmiConnOpts.Authentication = System.Management.AuthenticationLevel.Default;
wmiConnOpts.EnablePrivileges = true;
ManagementScope wmiLoc =
new ManagementScope(String.Format(#"\\{0}\root\cimv2", remoteMachine ),
wmiConnOpts);
ManagementPath wmiProcPath = new ManagementPath("Win32_ScheduledJob");
ManagementClass wmiProc = new ManagementClass(wmiLoc, wmiProcPath, null);
wmiProc.InvokeMethod("Create", new Object[] { runFile });
This is probably idiot error on my part but the error I was getting was because I didn't specify a time (UTC format) for it to start the scheduled job
ConnectionOptions connOptions = new ConnectionOptions();
connOptions.Impersonation = ImpersonationLevel.Impersonate;
connOptions.Authentication = AuthenticationLevel.PacketPrivacy;
connOptions.EnablePrivileges = true;
ManagementScope manScope = new ManagementScope(String.Format(#"\\" + remoteMachine + #"\ROOT\CIMV2"), connOptions);
manScope.Connect();
ObjectGetOptions objectGetOptions = new ObjectGetOptions();
ManagementPath managementPath = new ManagementPath("Win32_ScheduledJob");
ManagementClass processClass = new ManagementClass(manScope, managementPath, objectGetOptions);
ManagementBaseObject inParams = processClass.GetMethodParameters("Create");
inParams["Command"] = runFile;
string StartTime = DateTimetoUTC(DateTime.Now.AddMinutes(1));
inParams["StartTime"] = StartTime;
ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null);

Categories