如果未安装软件,则安装 Chocolatey 软件包,但如果已安装更新版本的软件,则跳过安装?

Install Chocolatey package if software is not installed, but skip install if newer version of software is already installed?

我正在使用以下 PowerShell 脚本通过 Octopus Deploy 步骤安装 dotnetcore-windowshosting 版本 1.1.1。

ChocolateyPackageId 等于 "dotnetcore-windowshosting" 且 $ChocolateyPackageVersion 等于“1.1.1”。

但是,目标机器安装了新版本的 DotNetCore.1.0.4_1.1.1-WindowsHosting.exe,而不是 Chocolatey 包正在安装的版本。结果,出现了一个错误,提醒我目标机器已经安装了更新的版本。

如何像在脚本中一样使用 cinst 安装包,但是,如果正在安装的包(或更新版本)已经安装,请忽略并且不引发错误?

$chocolateyBin = [Environment]::GetEnvironmentVariable("ChocolateyInstall", "Machine") + "\bin"
if(-not (Test-Path $chocolateyBin)) {
    Write-Output "Environment variable 'ChocolateyInstall' was not found in the system variables. Attempting to find it in the user variables..."
    $chocolateyBin = [Environment]::GetEnvironmentVariable("ChocolateyInstall", "User") + "\bin"
}

$cinst = "$chocolateyBin\cinst.exe"
$choco = "$chocolateyBin\choco.exe"

if (-not (Test-Path $cinst) -or -not (Test-Path $choco)) {
    throw "Chocolatey was not found at $chocolateyBin."
}

if (-not $ChocolateyPackageId) {
    throw "Please specify the ID of an application package to install."
}

$chocoVersion = & $choco --version
Write-Output "Running Chocolatey version $chocoVersion"

$chocoArgs = @()
if([System.Version]::Parse($chocoVersion) -ge
   [System.Version]::Parse("0.9.8.33")) {
    Write-Output "Adding --confirm to arguments passed to Chocolatey"
    $chocoArgs += @("-y", "")
}

if (-not $ChocolateyPackageVersion) {
    Write-Output "Installing package $ChocolateyPackageId from the Chocolatey package repository..."
    & $cinst $ChocolateyPackageId $($chocoArgs)
}
else {
    Write-Output "Installing package $ChocolateyPackageId version $ChocolateyPackageVersion from the Chocolatey package repository..." & $cinst $ChocolateyPackageId -Version $ChocolateyPackageVersion $($chocoArgs)
}

免责声明:这是 hacky。而且不是很好。

function Test-ChocolateyPackageInstalled {
    Param (
        [ValidateNotNullOrEmpty()]
        [string]
        $Package
    )

    Process {
        if (Test-Path -Path $env:ChocolateyInstall) {
            $packageInstalled = Test-Path -Path $env:ChocolateyInstall\lib$Package
        }
        else {
            Write-Warning "Can't find a chocolatey install directory..."
        }

        return $packageInstalled
    }
}

$package = "dotnetcore-windowshosting"


if (Test-ChocolateyPackageInstalled -Package $package) {
    Write-Warning "Package is already installed"
}
else {
    choco install $package -confirm
}

我只通过 Chocolatey 安装过它,所以当其他人手动安装时我将很难测试你的场景,但该方法可能有问题。

因此也请注意,这可能无法完全解决您的问题;但它可以帮助未来的读者。

开源

继续您正在处理的脚本,但是请检查您正在安装的脚本的退出代码,它可能有一个有效的退出代码,表明已经安装了更新的版本。

商业

可能已经存在实现您正在寻找的目标的最佳方法。 Chocolatey for Business 具有同步命令和自动同步功能。 https://chocolatey.org/docs/features-synchronize

如果您 运行 choco sync 然后调用您的安装,您将已经拥有由 Chocolatey 管理的该软件包的更新版本。因此它会忽略你的脚本。

choco sync
choco upgrade <name> -y <options>

如果没有安装包,这里升级实现安装,如果你的源中有更新的版本,升级

感谢所有建议。以下似乎对我有用

$chocolateyBin = [Environment]::GetEnvironmentVariable("ChocolateyInstall", "Machine") + "\bin"
if(-not (Test-Path $chocolateyBin)) {
    Write-Output "Environment variable 'ChocolateyInstall' was not found in the system variables. Attempting to find it in the user variables..."
    $chocolateyBin = [Environment]::GetEnvironmentVariable("ChocolateyInstall", "User") + "\bin"
}

$cinst = "$chocolateyBin\cinst.exe"
$choco = "$chocolateyBin\choco.exe"

if (-not (Test-Path $cinst) -or -not (Test-Path $choco)) {
    throw "Chocolatey was not found at $chocolateyBin."
}

if (-not $ChocolateyPackageId) {
    throw "Please specify the ID of an application package to install."
}

$chocoVersion = & $choco --version
Write-Output "Running Chocolatey version $chocoVersion"

$chocoArgs = @()
if([System.Version]::Parse($chocoVersion) -ge [System.Version]::Parse("0.9.8.33")) {
    Write-Output "Adding --confirm to arguments passed to Chocolatey"
    $chocoArgs += @("-y", "")
}

if (-not $ChocolateyPackageVersion) {
    Write-Output "Installing package $ChocolateyPackageId from the Chocolatey package repository..."
    & $cinst $ChocolateyPackageId $($chocoArgs)
} else {
    Write-Output "Installing package $ChocolateyPackageId version $ChocolateyPackageVersion from the Chocolatey package repository..."
    & $cinst $ChocolateyPackageId -Version $ChocolateyPackageVersion $($chocoArgs) --force
}

$codes = $IgnoreExitCodes -split ','

if ($codes -Contains $lastExitCode)
{
    exit 0
}