17

I'm trying to get the Java version in PowerShell. The version string is printed to stderr, so I'm trying to redirect it to stdout and assign it to a string variable.

I get the following strange error:

PS P:\> & java -version 2>&1
java.exe : java version "1.7.0_25"
At line:1 char:2
+ & <<<<  java -version 2>&1
    + CategoryInfo          : NotSpecified: (java version "1.7.0_25":String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

Java(TM) SE Runtime Environment (build 1.7.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

Call without redirection (2>&1) gives this:

PS P:\> & java -version
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

I think that Java here is irrelevant, and the same would happen for any other program printing strings to stderr.

The PowerShell version I use is 2.0.

Questions:

  • How can I redirect stderr to a variable?
  • Or, alternatively, how can I check the installed Java version?

Workaround

I can run it like this:

$output = & cmd /c "java -version 2>&1"

But I hate running a cmd.exe where it shouldn't be necessary.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ivan
  • 9,089
  • 4
  • 61
  • 74

2 Answers2

17

I have been using Get-Command to get Java version on PowerShell 5.1.

Get-Command java | Select-Object Version

This returns an object. If you want a string instead, use:

(Get-Command java | Select-Object -ExpandProperty Version).toString()

The outputs look like this:

PS > Get-Command java | Select-Object Version

Version
-------
8.0.1710.11



PS > Get-Command java | Select-Object -ExpandProperty Version

Major  Minor  Build  Revision
-----  -----  -----  --------
8      0      1710   11



PS > (Get-Command java | Select-Object -ExpandProperty Version).tostring()
8.0.1710.11

It worked quite well under PowerShell 5.1. I don't have a chance to test this on PowerShell 2.0.

Allen
  • 2,195
  • 1
  • 14
  • 9
16

One way is using WMI:

$javaver =  Get-WmiObject -Class Win32_Product -Filter "Name like 'Java(TM)%'" | Select -Expand Version

Another one is redirect to a file with start-process:

start-process  java  -ArgumentList "-version" -NoNewWindow -RedirectStandardError .\javaver.txt

$javaver = gc .\javaver.txt

del .\javaver.txt

And my last is:

dir "HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment"  | select -expa pschildname -Last 1

Regarding how redirect stderr in this case you can do:

$out = &"java.exe" -version 2>&1
$out[0].tostring()
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
CB.
  • 58,865
  • 9
  • 159
  • 159
  • Good approach! Didn't work for me just like this (something to do with the -Filter), but has worked as: Get-WmiObject -Class Win32_Product | Where-Object {$_.Name.StartsWith('Java')} | Select -Expand Version – Ivan Sep 19 '13 at 09:44
  • Thanks. Yes, I knew about -RedirectStandardError option of Start-Process, but hate creating a file just for this simple reason... – Ivan Sep 19 '13 at 09:50
  • @Ivan Added my last ;) – CB. Sep 19 '13 at 10:06
  • Amazing! Couldn't think there are so many ways of getting Java version. Will probably use the one with Get-WmiObject. Though it's still not clear how to redirect stderr in PS... but many thanks C.B.! – Ivan Sep 19 '13 at 10:40
  • @Ivan Glad to help! I've added a method for redirect stderr, hope you like it – CB. Sep 19 '13 at 12:00
  • 1
    The `Get-WmiObject` approach just causes my script to hang, how annoying – Bassie Jun 14 '18 at 06:40
  • Querying the Win32_Product for anything is not recommended. Will cause a system to basically touch every single app installed via msi on a computer. – Paul Wetter Dec 23 '20 at 20:15