Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Execute command line on remote computer with WMI

Status
Not open for further replies.

MakeItSo

Programmer
Oct 21, 2003
3,316
DE
Hi friends,

I am trying to execute a command on a remote computer, a netstat call with specified port to be precise, in order to have an overview of who is connected to this computer via VNC.
I do have a (somewhat) functioning code using VB6 and PsExec,the performance of which is however rather poor and the code clunky.
Now that I am warming up to C#, I'd like to achieve a more elegant - and faster! - solution.

Here's my approach so far:
Code:
/[COLOR=#73D216]* some stuff here
*/[/color]
using System.Management;
using WbemScripting;
[COLOR=#73D216]// form stuff[/color]
private void button1_Click(object sender, EventArgs e)
        {
            if(CanPing("servername"))
            {
                string remoteMachine = "servername";

                ConnectionOptions connOptions = new ConnectionOptions();
                connOptions.Impersonation = ImpersonationLevel.Impersonate;
                connOptions.EnablePrivileges = true;

                ManagementScope manScope = new ManagementScope(String.Format(@"\\{0}\ROOT\CIMV2", remoteMachine), connOptions);
                manScope.Connect();

                ObjectGetOptions objectGetOptions = new ObjectGetOptions();
                ManagementPath managementPath = new ManagementPath("Win32_Process");
                ManagementClass processClass = new ManagementClass(manScope, managementPath, objectGetOptions);

                ManagementBaseObject inParams = processClass.GetMethodParameters("Create");

                [COLOR=#EF2929]inParams["CommandLine"] = "netstat -an | find \":5900\" >M:\temp\flog.txt";[/color]
                ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null);

                String outMess= "Creation of the process returned: " + outParams["returnValue"] + "\n";
                outMess=outMess + "Process ID: " + outParams["processId"];
                MessageBox.Show(outMess);
            }
        }

"CanPing" is a simple little function that returns true if a ping returns "Success":
Code:
Boolean CanPing(String compi)
        {
            System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
            System.Net.NetworkInformation.PingReply reply = ping.Send(compi);

            return (reply.Status.ToString() == "Success");
        }

5900 is the VNC port, M drive is mapped on the computer that shall run the command, temp folder exists.

My problem now is: The computer can be pinged, the code is being executed and I have a returnValue of 0 (which seems to be good according to Google) and a processID which gives me the idea that something is being done.
The output file however is not being created, so clearly something is wrong!

I have no idea what.
[3eyes]

By the way: I made sure that the firewall options are properly set on my computer as well as on the destination.

Can anyone tell me whether my general approach will work at all or if I am missing something hopefully simple?
Thanks a bunch!

MakeItSo

“Knowledge is power. Information is liberating. Education is the premise of progress, in every society, in every family.” (Kofi Annan)
Oppose SOPA, PIPA, ACTA; measures to curb freedom of information under whatever name whatsoever.
 
Does the user the code will execute under have write permissions to that share? Can you log on to the machine as the same user and run the same command manually to see if you get an output file?
 
Hi Ralph,

I'm domain admin. If the impersonation works as I think it does, that should not be a problem.
Does it?
I'm logged on with my normal domain account.

“Knowledge is power. Information is liberating. Education is the premise of progress, in every society, in every family.” (Kofi Annan)
Oppose SOPA, PIPA, ACTA; measures to curb freedom of information under whatever name whatsoever.
 
P.s: running the command locally from a DOS prompt works fine, just as running it via psexec with explicitly provided user name and password.
User logged on to destination computer has domain user rights including write rights to said share.

“Knowledge is power. Information is liberating. Education is the premise of progress, in every society, in every family.” (Kofi Annan)
Oppose SOPA, PIPA, ACTA; measures to curb freedom of information under whatever name whatsoever.
 
Little update on this:
I have hoped to solve this by altering the command line a little, like this:
Code:
inParams["CommandLine"] = "[b][COLOR=#3465A4]cmd.exe /c[/color][/b] netstat -an | find :5900 >M:\temp\flog.txt";

Again, the returnValue is 0 and I get a processID.
Alas, I was simultaneously connected to the other computer via VNC and even have the physical screen itself in sight, with Task Manager open.
No additional process appears in the list.
Whatever happens, it leaves no sign of its existence.


“Knowledge is power. Information is liberating. Education is the premise of progress, in every society, in every family.” (Kofi Annan)
Oppose SOPA, PIPA, ACTA; measures to curb freedom of information under whatever name whatsoever.
 
Another update:
I've replaced the server name with that of my own computer, so I execute the "remote" command locally.
I saw a command window quickly flashing so I replaced the "/c" switch with "/k" to keep the command prompt open. Obviously no parameters have been passed!
=>cmd.exe is being executed but the netstat command is not being passed!

So I enclosed the command in quotes - and received that the path was wrong. After some ruminating it struck me:
This is C#, damnit, you gotta escape backslashes!! [banghead]

So this code here functions in as far as it actually produces the output file:
Code:
inParams["CommandLine"] = "cmd.exe /c [COLOR=#CC0000]\"[/color]netstat -an | find \":5900\" >M:[COLOR=#CC0000]\\[/color]temp[COLOR=#CC0000]\\[/color]flog.txt[COLOR=#CC0000]\"[/color]";

So far so good. What's bad still: the output file is 0 bytes; no content. [poke]

Any ideas?

“Knowledge is power. Information is liberating. Education is the premise of progress, in every society, in every family.” (Kofi Annan)
Oppose SOPA, PIPA, ACTA; measures to curb freedom of information under whatever name whatsoever.
 
Next update:
the output works fine; 0 bytes only when there is no connection whatsoever, i.e. not even listening at that port.
Only works locally though.
As soon as I try to send the command to the remote computer, no output is generated.
I have tried with 4 remote computers running Windows 7 Pro, XP Pro SP3, Server 2003, and Server 2008.
Running out of ideas.
[sadeyes]

“Knowledge is power. Information is liberating. Education is the premise of progress, in every society, in every family.” (Kofi Annan)
Oppose SOPA, PIPA, ACTA; measures to curb freedom of information under whatever name whatsoever.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top