PSExec: Nice tool, Difficult to automate if you like StandardOut


While working on a Test-case automation solution I ran across an interesting issue: PSExec can't be used to remotely execute a script and return a result when executed within a C# application with StandardOutput redirection.

Issues:

  • Hangs (Have to manually kill PSExec service on remote machine)
  • null value return (StandardOutput redirection not supported)

Notes:

 

PSExec is an awesome tool.  It comes in handy for those times you just need to kick something off remotely without physically going over to the machine in question. For one-off activities or even limited automation it works great.

However, if you want to use PSExec in a more 'advanced' way you may be disappointed. For example, I am trying to create a generic test script execution framework for our QA Group. I want to capture the StandardOutput of a command run through PSExec and run comparisons to determine pass/fail. In this scenario you may be out of luck as PSExec doesn't behave itself when you turn on StandardOutput redirection in C# (Or other languages- see points 17/18 in the PSExec FAQ)

While I was evaluating PSExec for our windows-side script execution needs I whipped up a POC Console app to see how it would work. It looked something like this:

Process process = new Process();
process.StartInfo.FileName = @"c:\Tools\PSTools\psexec.exe";
process.StartInfo.Arguments = @" \\10.103.8.25 -u Administrator -pw PASSWORDOFSOMETYPE CommandsToRun";

process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;

process.Start();
string result = process.StandardOutput.ReadToEnd();
process.WaitForExit();

 

Here is what the above Console App tries to do:

  • Setup StandardOutput / StandardInput Redirection
  • Start PSExec with arguments to have it run stuff against a remote machine
  • Start Capturing the output
  • Wait for the process to complete before continuing to the next test

 

What I found was that most of the time PSExec would simply hang when run like this. The times that it didn't hang (less than 15% of the time), it returned NULL as the string result. This behavior is consistent across Console apps, Winforms apps or NUnit DLLs. In almost all test runs (I tried over 20, fiddling with a few small changes between runs) the remote PSExec service would hang and need to be manually stopped.

This was very different from running it manually at the command line. Run from there I was able to see the whole process complete in less than 7 seconds. The StandardOutput from the remotely executed commands were clearly visible in the command window, too..

 

In a way it was a good thing that this didn't work as it drove me to find a more 'unified' solution for creating our test scripts. Our product supports windows as well as various exotic UNIX platforms (not just Linux) and we can standardize on BASH Scripts for our testing by Installing Cygwin Bash/SSHD on our Windows hosts and using SSH to automate script execution (I'll be writing an article outlining this process).