Reputation: 1069
I have a script that requires openssl be installed on the system. I want to do a check to see if it is installed. I've considered using test-path
but because this script will be on many computers, there's no way of knowing where the user installed openssl or if it is in the system path.
Is there a way to do something like test-command openssl
(I know that doesn't exist) and get an error level or the like to return in powershell?
Many thanks!
Upvotes: 5
Views: 2049
Reputation: 437052
Use the Get-Command
cmdlet to explicitly test if executables can be called by their name only (implying that they're in one of the directories listed in $env:PATH
) and for command discovery in general:
$found = [bool] (Get-Command -ErrorAction Ignore -Type Application openssl)
Write-Verbose -vb "openssl.exe found? $found"
Casting to [bool]
evaluates to $true
only if Get-Command
returns output, which it only does if the executable is found.
-Type Application
ensures that only external programs are considered; by default, Get-Command
finds commands of all types, including *.ps1
scripts, cmdlets, functions, and aliases.
The Get-Command
by itself would also allow you to find out the executable's full path, via the output object's .Source
property.
Alternatively, if all that matters is whether the executable is available, you can simply try to execute your actual command and handle an error indicating that the executable is not available via try
/ catch
:
try {
openssl ... # your *actual* command, not a test
} catch [System.Management.Automation.CommandNotFoundException] {
# Handle the error, reflected in $_
Write-Warning $_
# ...
}
Note that you don't strictly need to catch [System.Management.Automation.CommandNotFoundException]
specifically, if you're confident that the only error that can occur is due to a missing executable, but note that you could then get potential false positives from errors that occur during evaluation of expression-based arguments, such as attempting to pass (1 / 0)
as an argument.
Also note that attempting to test the availability of an executable by invoking it without arguments inside a try
/ catch
statement is not a viable approach, because the executable may enter an interactive shell (as is the case with openssl
) or produce undesired side effects.
Upvotes: 10
Reputation: 700
You can use try/catch blocks to do something like the following:
$OpenSSLMissing = $false
try {openssl} catch {$OpenSSLMissing = $true}
if ($OpenSSLMissing)
{
# Do something
}
else
{
# Do something else
}
Upvotes: 2