如何测试Powershell中的系统上是否存在程序/可执行文件?

时间:2018-12-18 22:19:43

标签: powershell

我有一个脚本,要求在系统上安装openssl。我想检查一下是否已安装。我曾考虑过使用test-path,但是由于此脚本将在许多计算机上使用,所以无法知道用户将openssl安装在哪里或它是否在系统路径中。

有没有办法做类似test-command openssl(我知道那不存在)并得到错误级别之类的东西以在Powershell中返回?

非常感谢!

2 个答案:

答案 0 :(得分:4)

使用Get-Command cmdlet 进行显式测试,是否只能使用可执行文件的名称来调用可执行文件(这意味着它们位于目录中列出的目录之一中) $env:PATH)和一般命令发现

$found = [bool] (Get-Command -ErrorAction Ignore -Type Application openssl)

Write-Verbose -vb "openssl.exe found? $found"

仅当[bool]返回输出时,对$true的强制转换才算为Get-Command,只有找到可执行文件时,该操作才会得出。

-Type Application确保仅考虑外部程序;默认情况下,Get-Command查找所有类型的命令,包括*.ps1脚本,cmdlet,函数和别名。

Get-Command本身还可以使您通过输出对象的.Source属性来找到可执行文件的完整路径


或者,如果最重要的是可执行文件是否可用,则您可以简单地尝试执行实际命令并处理错误。指示可执行文件无法通过try / catch使用:

try {
  openssl ... # your *actual* command, not a test
} catch [System.Management.Automation.CommandNotFoundException] {
  # Handle the error, reflected in $_
  Write-Warning $_
  # ... 
}

请注意,如果您确信唯一可能发生的错误是由于缺少可执行文件而引起的,则不必严格地[System.Management.Automation.CommandNotFoundException],但是请注意,然后您可能会从中获得潜在的误报在评估基于表达式的参数时发生的错误,例如尝试将(1 / 0)作为参数传递。

还请注意,尝试通过在try / catch语句内调用不带参数测试可执行文件的可用性不是一种可行的方法,因为可执行文件可能会进入交互式shell(例如openssl)或产生不良副作用。

答案 1 :(得分:2)

您可以使用try / catch块执行以下操作:

$OpenSSLMissing = $false
try {openssl} catch {$OpenSSLMissing = $true}
if ($OpenSSLMissing)
{
    # Do something
}
else
{
    # Do something else
}