function Invoke-ChocoInstallPackagesPrivate { <# .SYNOPSIS Installs a list of Chocolatey packages. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingInvokeExpression', '', Justification = 'Alkami generates this string manually, no user injection')] [CmdletBinding()] Param( [Parameter(Mandatory = $true)] [Alias("PackagesToInstall")] [object[]]$packages, [Parameter(Mandatory = $false)] [Alias("f")] [switch]$force, [Parameter(Mandatory = $false)] [Alias("e")] [string]$environment, [Parameter(Mandatory = $false)] [Alias("migrate", "m")] [switch]$runMigrations, [Parameter(Mandatory = $false)] [Alias("start", "s")] [switch]$startService, [Parameter(Mandatory = $false)] [switch]$forceSameVersion, [Parameter(Mandatory = $false)] [switch]$ignoreDependencies, [Parameter(Mandatory = $false)] [switch]$preventDowngrade, [Parameter(Mandatory = $false)] [switch]$SkipScripts ) $loglead = Get-LogLeadName; if (!(Test-IsAdmin)) { throw "$loglead : User must be an administrator to run Chocolatey installs." } if($packages.Count -gt 1) { $localPackages = Get-ChocoState -l; } else { $localPackages = Get-ChocoState -l -packageName $packages[0].Name; } $numPackages = $packages.count; Write-Verbose "$loglead : Now installing $numPackages packages:"; $success = $true; $counter = 0; foreach ($package in $packages) { $name = $package.Name; $version = $package.Version; $counter++ try { $chocoParams = Get-ChocolateyParameterString $package -env $environment -start $startService.IsPresent -migrate $runMigrations.IsPresent; $localPackage = ($localPackages | Where-Object { $_.Name -eq $name }); $isInstalled = $null -ne ($localPackage); # Upgrade if the package is already installed. # set local package version to null if not installed if (!$isInstalled ) { $commandFlag = "install" $localPackageVersion = "0.0.0" } else { $commandFlag = "upgrade" $localPackageVersion = $localpackage.Version } # Compare two sematic verions # -1 if $Version1 < $Version2 # 0 if $Version1 = $Version2 # 1 if $Version1 > $Version2 switch ((Compare-SemVer -version1 $localPackageVersion -version2 $version)) { 1 { $isSameVersion = $false $isDowngrade = $true } 0 { # The Compare-SemVer function will say that certain pre-versions are the same version, and prevent installs. # This string version comparison hack allows these packages to be considered different versions. $isSameVersion = $localPackageVersion -eq $version } -1 { $isSameVersion = $false $isDowngrade = $false } Default { } } $forceSwitch = ""; $forceInstall = $force.IsPresent -or ($forceSameVersion.IsPresent -and $isSameVersion); if ($forceInstall) { $forceSwitch = "-f"; } # If we're not forcing a package, and it's the same version, then skip the choco install. if((!$forceInstall) -and ($isInstalled) -and ($isSameVersion)) { Write-Host "$loglead : Skipping install of $name $version because it is already installed." continue; } # Handle ignore-dependency / allow-downgrade flags $ignoreDependenciesFlag = if ($ignoreDependencies.IsPresent -or $isSameVersion -or $isDowngrade) { "--ignore-dependencies" } else { "" }; $downgradeFlag = if ($preventDowngrade.IsPresent) { "" } elseif ($isDowngrade) { "--allow-downgrade" } else { "" }; #Skips running `chocoInstall.ps1` as part of `choco install/upgrade` process #Still adds requested package to /lib #Makes choco "think" this package is "installed" without running install script $skipInstallScriptFlag = if ($SkipScripts.IsPresent) { "--skipscripts" } else { "" } if ($isSameVersion -and $forceInstall -and $skipInstallScriptFlag) { Write-Host "$loglead : Skipping download to just copy same version with componentized installer." continue } Write-Host "$loglead : Now installing ($counter/$numPackages) '$name $version':"; $command = "choco $commandFlag $name --version $version -y --no-progress $downgradeFlag $ignoreDependenciesFlag $forceSwitch $skipInstallScriptFlag --params $chocoParams;" Write-Host "Command: $command" Invoke-Expression $command Write-Host "$loglead : Installation of '$name $version $skipInstallScriptFlag' done." } catch { Write-Error $_ | Format-List -force $success = $false; } } if (!($success)) { throw "$loglead : Installation of one or more packages failed."; } }