Search code examples
powershelloctopus-deploychocolatey

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


I'm using the following PowerShell script to install dotnetcore-windowshosting version 1.1.1 via an Octopus Deploy step.

ChocolateyPackageId is equal to "dotnetcore-windowshosting" and $ChocolateyPackageVersion is equal to "1.1.1".

However, the target machine has a new version of DotNetCore.1.0.4_1.1.1-WindowsHosting.exe installed than the version being installed by the Chocolatey package. As a result, an error is raised alerting me that the target machine already has a newer version installed.

How can I install the package using cinst like in the script, however, ignore and don't raise an error if the package being installed (or a newer version) is already installed?

$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)
}

Solution

  • Thanks for all the suggestions. Below seems to work for me

    $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
    }