Not as easy as we thought - PowerShell from Java Runtime

This week, one of my office colleagues,Vijay asked me " Can we run command of PowerShell from Java Application ?" Microsoft is coming up with a new shell called PowerShell, commands are very similar to that of our Unix Shell. Yes, this problem looks quite simple, I guess Java Runtime class will do that as it do for cmd commands. And for that we wrote one simple code like this :

import java.io.\*;
class OneMore {
public static void main(String[] args)throws IOException
{
          Runtime runtime = Runtime.getRuntime();
           String cmds[] = {"ls"};
           Process proc = runtime.exec(cmds);
           InputStream inputstream = proc.getInputStream();
           InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
           BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
           String line;
           while ((line = bufferedreader.readLine()) != null) {
               System.out.println(line);
           }
}
}

So, this code will print the output of ls on console. But no we need to execute powershell command. So it is required to pass PowerShell in the String cmds[]. Ok, I don't have PowerShell on my machine but let me try to run the same with command.exe(cmd.exe) in place of powershell.exe. So, I have changed one line in the code:

String cmds[] = {"cmd", "ls"};

But then this is not right as there should be right option with cmd like /c or /k. So further it changed into :

String cmds[] = {"cmd", "\\c", "ls"};

Code is running fine and we are done with job. But he want a file in place of command "ls", not a problem pass a file "file.bat" in place of ls. file.bat contains ls :). So, finally code goes something like:

Runtime runtime = Runtime.getRuntime();
           String cmds[] = {"cmd", "\\c", "file.bat"};
           Process proc = runtime.exec(cmds);
           InputStream inputstream = proc.getInputStream();
           InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
           BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
           String line;
           while ((line = bufferedreader.readLine()) != null) {
               System.out.println(line);
           }


Even if we want to check the process is exiting correctly or not, we can add some more lines checking for proc.waitFor() or proc.ExitValue().

But, this piece of code is not running fine for PowerShell. WHY ? No clue(till today, trying to find out why). Unfortunately the program go for a hang. And till now the conclusion is: its either a problem that we are not able to find the right substitute of \\c in PowerShell, though the document is saying "&" will do the same Or maybe PowerShell is stopping us in writing streams(some security issue).

A bad workaround is working fine.

Process proc = runtime.exec("powershell & filename" > out.txt)

We are able to pass the output of PowerShell process into a file out.txt, now reading the file out.txt and print the output on console. But it can create problem if out.txt will go large enough. Can you give me the answer of my WHY ? Why this code is not running for PowerShell. Is there any bug in PowerShell(according to me, yes) ?

Comments:

This works with cmd.exe, because cmd.exe outputs text for you to consume with BufferedReader. Powershell emits objects, not text, so you program has to work with that instead. Furthermore, cmd.exe works on the "stdout stderr" system, where Powershell has different pipes for output,error,verbose,etc. Redirecting powershell's output to a file works, because your BufferedReader understands text files. It should be able to work with "powershell -command 'ls c:\\temp'", but it's been awhile since I programmed Java and don't remember the Runtime class too well.

Posted by James Pogran on February 22, 2008 at 12:52 PM IST #

Thanks James. This sounds little new to me. I will definitely give a try with this and let you know.

Posted by Vaibhav on February 23, 2008 at 12:07 PM IST #

I had the same problem and the problems seems to be that powershell first reads all input from it's input stream before continuing. The simple solution is to call proc.getOutputStream().close(); after you create the process.

Posted by Christoph Hohmann on March 05, 2008 at 11:58 AM IST #

Oh this is a good workaround. I thought it is some security issue with PowerShell.

Thanks for the information.

Posted by Vaibhav on March 05, 2008 at 12:29 PM IST #

Thank you! Thank you! Thank you for this solution!
I need to administer Exchange Server 2007 mailboxes using a JSP and Java servlet in Tomcat. Since Exchange 2007 administration can only be done through PowerShell cmdlets, I have no option except to execute a PowerShell script from Java. The servlet was "hanging" as described above until I added the .close() code.

Posted by Mark Wefer on August 13, 2008 at 01:01 PM IST #

O yes, even I thanks for Christoph for the comment. Vijay's work was also got done because of the comment. Thanks again from all of us :)

Posted by Vaibhav on August 13, 2008 at 01:04 PM IST #

It's good to know that I'm not the only fool got caught in this
annoying thing, Powershell is great & I love it...But I love Java more!
all the comments here helped me, so I'm contributing more info to the problem, I've solved it this way :
you can always use cmd /C and then run powershell like so -
String cmd = "cmd /f powershell myScript.ps1";
Runtime runtime = Runtime.getRuntime();
Process process1 = runtime.exec(cmd);
then you can log or system.out the powershell print out using
InputStreamReader inpStrd = new InputStreamReader(inpStr);
BufferedReader buffRd = new BufferedReader(inpStrd);
passing the process1.getInputStream() as the InputStream
( I've used a helper class that extends Thread to wrap the
Stream and the readLine() it)

Cheers.
Eldad.D
AlphaCSP Java Developer

Posted by Eldad D on December 01, 2008 at 11:07 AM IST #

My JSP page is getting hangup while running powershell; please help me!
String cmds = "cmd /C powershell c:/MyScript.ps1";
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec(cmds);
InputStream inputstream = proc.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
String line;
PrintWriter printwrite = new PrintWriter(new FileWriter(filename, true));
while ((line = bufferedreader.readLine()) != null) {
System.out.println(line);
printwrite.println(line);
}
printwrite.close();
proc.getOutputStream().close();
proc.getInputStream().close();

Posted by Kiran K. on December 02, 2008 at 07:25 AM IST #

Hope you are giving JRE complete permission to do read/write from a JSP page ?

Posted by Vaibhav Choudhary on December 02, 2008 at 08:19 AM IST #

i have tried it once again, it work fine but it's getting hangup in while loop of the above code

Posted by Kiran K. on December 02, 2008 at 09:13 AM IST #

Hi Vaibhav, my problem of powershell run over is seems to be solve but, I have a problem how can i get the buffer output to a file because now code is hangingup in file i am not able to open that file and not even see any output in it. but it works fine if i run that code from the dos prompt. i think i require something which is converting "buffereader" output to the string

Posted by Kiran K. on December 04, 2008 at 11:58 AM IST #

Nothing new to add, but must say Christoph, an impressive find regarding dumping the output stream. Worked like a charm. Very grateful for your post. And thank you Vaibhav for hosting a useful blog.

Posted by Justin Zealand on February 06, 2009 at 07:07 AM IST #

thanks ! Yes this has solved problem for many of us :)

Posted by Vaibhav Choudhary on February 06, 2009 at 07:54 AM IST #

There is a commercial solution called PSB, you can download and try at:
www.javaexchangeconnector.com

Posted by Eli Hasson on April 22, 2009 at 06:16 AM IST #

The PSB is actually does : "cmd /c powershell c:/MyScript.ps1"
and nothing more...not even concurrent or thread safe.
...pretty straight forward.

Posted by Eldad D on April 22, 2009 at 11:39 AM IST #

Please fix your post so it uses /c instead of \\c!

Posted by guest on April 28, 2009 at 06:00 PM IST #

Hi, Vaibhav.
I want to scrab this post and the comment of Christoph.
I was able to solve my problem from Christoph.
Thanks for your post and the comments.

Heo seok

LG-nortel R&D. Korea

Posted by heo seok on May 06, 2009 at 02:37 AM IST #

ah nice... go ahead :)

Posted by Vaibhav Choudhary on May 06, 2009 at 03:04 AM IST #

Thanks Vaibhav, Christopher and Eldad.....it works it works..
I am trying to build an admin interface for Exchange 2007 , and this blog saved me days of work..

Posted by Gouri on October 23, 2009 at 03:04 PM IST #

:P. Nice nice !

Posted by Vaibhav on October 23, 2009 at 04:12 PM IST #

Great post and draw. Thank you for sharing.

Posted by links london jewelry on December 01, 2009 at 12:05 AM IST #

Keep up the good work bro.Your article is really great and I truly enjoyed reading it.Waiting for some more great articles like this from you in the coming days.

Posted by Gucci Shoes discount on December 10, 2009 at 06:00 AM IST #

<a href=" http://www.linksoflondonbest.com/links-of-london-chains-c-7.html">links of london friendship bracelet</a>
<a href=" http://www.linksoflondonbest.com/links-of-london-rings-c-6.html">links of london sweetie</a>
<a href=" http://www.linksoflondonbest.com/links-of-london-rings-c-6.html">links of london ring</a>

Posted by links of london on December 22, 2009 at 01:57 AM IST #

thanks

Posted by ed hardy on January 22, 2010 at 04:45 AM IST #

Hi Vaibhav,

I have my powershell script that queries the VMM for the inventory of VMs, information such as the MAC address, and current state.

Now how should I execute the PowerShell script via JAVA.

I know you have already posted the solution. But could you exactly mention where shoudl I change in the solution you have provided above?\\

Kindly reply.

Thanks,
Vamsi

Posted by Vamsi on July 01, 2010 at 03:56 PM IST #

Thanks Guys! It Works Perfectly!!!!!!!

@Vamsi, all the details are in Eldad D's post..

Excellent work guys!!

Posted by Mewk on November 10, 2010 at 12:38 PM IST #

Post a Comment:
Comments are closed for this entry.
About

Hi, I am Vaibhav Choudhary working in Sun. This blog is all about simple concept of Java and JavaFX.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today