Question

Use case: I am checking certain credentials on a remote system by running commands via PsExec (i.e. for this example, I am trying to retrieve the KB articles currently installed on the remote system).

I have the following to retrieve command output:

public string GetCmDOutput(string cmd)
    ProcessStartInfo startInfo = new ProcessStartInfo("control", cmd)
    {
        WindowStyle = ProcessWindowStyle.Hidden,
        UseShellExecute = false,
        RedirectStandardOutput = true,
        CreateNoWindow = true
    };

    string output = string.Empty;

    Process process = Process.Start(startInfo);
    process.OutputDataReceived += (sender, e) => output = string.Concat(output, e.Data);
    process.BeginOutputReadLine();
    process.Start();
    process.WaitForExit();
    Delay.Milliseconds(1500) //API-specific delay

    return output;
}

Whenever I use GetCmdOutput() to run a command locally it works like a charm, but if I try to run a command with PsExec, my output is empty.

For instance, I ran the following:

string cmd = @"\psexec.exe \\remoteComputerName -u username -p password -c cmd /c wmic qfe";
GetCmdOutput(cmd);
Report.Info(cmd); //API-specific reporting

And an empty string was returned.

After playing around with this for a couple of hours, I feel I may need a second set of eyes. What might be causing this issue?

Was it helpful?

Solution

I have run into this same problem. My solution was to run cmd and have it call psexec. I have psexec's output saved to a temp file for further manipulation. My code is returning a List.

public List<string> ExecutePSExec(string hostname)
{
    List<string> recordNames = new List<string>();
    string command = @"\\path\to\psexec.exe /accepteula \\" + hostname + ". exe-to-run-remotely";
    try
    {
        string location = AppDomain.CurrentDirectory.BaseDirectory;
        string cmdWithFileOutput = string.Format("{0} >{1}temp.log", command, location);

        procStartInfo.UseShellExecute = true;
        procStartInfo.CreateNoWindow = true;
        procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;

        Process proc = new Process();
        proc.StartInfo = procStartInfo;
        proc.Start();
        proc.WaitForExit();

        // Read file contents, manipulate data and then delete temp file here
    }
    catch (Exception e)
    {
        Console.WriteLine("Failure to run psexec: {0}", e.Message);
    }

    return recordNames;
}

NOTE: I ran into another problem and found out that running psexec this way requires the remote hostname (not IP Address) in the command to end in a period \\" + hostname + ".

This code assumes you can run psexec on the remote machine as your current user.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top