Reputation: 140
All I'm trying to do here is determine whether or not this specific version of java is installed. The Program should only either return "Java is installed" or return a non-zero exit error with "Java is not installed".
function Check_Java_Installed {
$app = java -version | Out-String
if ($app -contains "1.8.0_141"){
Write-Output "Java installed"
}
else{
Write-Error -Message "Java not installed"
}
}
Check_Java_Installed
Output (Powershell ISE):
java : java version "1.8.0_141"
At C:\temporary\Installers\java-checker.ps1:3 char:12
+ $app = (java -version) | Out-String
+ ~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (java version "1.8.0_141":String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Java(TM) SE Runtime Environment (build 1.8.0_141-b15
)
Java HotSpot(TM) 64-Bit Server VM (build 25.141-b15, mixed mode)
Check_Java_Installed : Java not installed
At C:\temporary\Installers\java-checker.ps1:13 char:2
+ Check_Java_Installed
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Check_Java_Installed
Output (Powershell):
Upvotes: 2
Views: 3455
Reputation: 438153
java -version
prints to stderr, which the obsolescent PowerShell ISE treats as an error, unlike regular PowerShell console windows. To capture stderr output, you must use redirection 2>&1
System.Management.Automation.ErrorRecord
objects. In PowerShell [Core] v6+, these objects sensibly stringify to their original string content if you pipe to Out-String
, for instance. Unfortunately, this is not true in Windows PowerShell (v5.1-), so you'll have to call .ToString()
on them; the alternative is to shell out to cmd.exe
and apply the redirection there (cmd /c 'java -version 2>&1'
), but that is inefficient and can have side effects.The -contains
operator tests an array for the presence of an element, it doesn't perform a substring search; you can use the [string]
type's .Contains()
method for the latter, or - more PowerShell-idiomatically - the -match
operator, though note that -match
operates on regular expressions rather than literal strings, and is case-insensitive by default. Note that with -match
the .
chars. in search string 1.8.0_141
must then be \
-escaped in order for them to be treated literally.
Write-Error
writes to PowerShell's error stream, it doesn't set an exit code. While it is possible to assign to $global:LASTEXITCODE
to set an exit code from a function, PowerShell doesn't use exit codes internally.
Instead, name your function Test-*
(Test
is an approved verb) and make it return $true
or $false
.
Alternatively, name it Assert-JavaInstalled
and make it throw an error that aborts processing of the script.
To put it all together:
# Functions named Test-* should return $true or $false
function Test-JavaInstalled {
# In Windows PowerShell, use:
# (java -version 2>&1 | % ToString | Out-String)
(java -version 2>&1 | Out-String) -match '1\.8\.0_141'
}
# Call the function.
if (Test-JavaInstalled) {
"Java installed"
} else {
Write-Error"Java not installed"
}
Alternatively, name your function Assert-JavaInstalled
and make it generate a script-terminating error via throw
, if Java is found not to be installed:
function Assert-JavaInstalled {
# In Windows PowerShell, use:
# (java -version 2>&1 | % ToString | Out-String)
if ((java -version 2>&1 | Out-String) -match '1\.8\.0_141')) {
"Java installed"
}
else {
# Throw a script-terminating error.
throw "Java not installed"
}
}
# Call the function.
Assert-JavaInstalled
Upvotes: 1