1 function Invoke-CommandLine {
3 [Parameter(Mandatory=$true)]
6 [Int[]]$AllowedExitCodes=@(0)
8 & $Command $Arguments.Split(" ")
9 if($LASTEXITCODE -notin $AllowedExitCodes) {
10 Throw "$Command $Arguments returned a non zero exit code ${LASTEXITCODE}."
14 function Start-ExecuteWithRetry {
16 [Parameter(Mandatory=$true)]
17 [ScriptBlock]$ScriptBlock,
18 [Int]$MaxRetryCount=10,
19 [Int]$RetryInterval=3,
20 [String]$RetryMessage,
21 [Array]$ArgumentList=@()
23 $currentErrorActionPreference = $ErrorActionPreference
24 $ErrorActionPreference = "Continue"
28 $res = Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList $ArgumentList
29 $ErrorActionPreference = $currentErrorActionPreference
31 } catch [System.Exception] {
33 if ($retryCount -gt $MaxRetryCount) {
34 $ErrorActionPreference = $currentErrorActionPreference
37 $prefixMsg = "Retry(${retryCount}/${MaxRetryCount})"
39 Write-Host "${prefixMsg} - $RetryMessage"
41 Write-Host "${prefixMsg} - $($_.ToString())"
43 Start-Sleep $RetryInterval
49 function Start-FileDownload {
51 [Parameter(Mandatory=$true)]
53 [Parameter(Mandatory=$true)]
57 Write-Output "Downloading $URL to $Destination"
58 Start-ExecuteWithRetry `
59 -ScriptBlock { Invoke-CommandLine -Command "curl.exe" -Arguments "-L -s -o $Destination $URL" } `
60 -MaxRetryCount $RetryCount `
61 -RetryMessage "Failed to download '${URL}'. Retrying"
62 Write-Output "Successfully downloaded."
65 function Add-ToPathEnvVar {
67 [Parameter(Mandatory=$true)]
69 [Parameter(Mandatory=$false)]
70 [ValidateSet([System.EnvironmentVariableTarget]::User, [System.EnvironmentVariableTarget]::Machine)]
71 [System.EnvironmentVariableTarget]$Target=[System.EnvironmentVariableTarget]::Machine
73 $pathEnvVar = [Environment]::GetEnvironmentVariable("PATH", $Target).Split(';')
74 $currentSessionPath = $env:PATH.Split(';')
75 foreach($p in $Path) {
76 if($p -notin $pathEnvVar) {
79 if($p -notin $currentSessionPath) {
80 $currentSessionPath += $p
83 $env:PATH = $currentSessionPath -join ';'
84 $newPathEnvVar = $pathEnvVar -join ';'
85 [Environment]::SetEnvironmentVariable("PATH", $newPathEnvVar, $Target)
88 function Install-Tool {
89 [CmdletBinding(DefaultParameterSetName = "URL")]
91 [Parameter(Mandatory=$true, ParameterSetName = "URL")]
93 [Parameter(Mandatory=$true, ParameterSetName = "LocalPath")]
95 [Parameter(ParameterSetName = "URL")]
96 [Parameter(ParameterSetName = "LocalPath")]
97 [String[]]$Params=@(),
98 [Parameter(ParameterSetName = "URL")]
99 [Parameter(ParameterSetName = "LocalPath")]
100 [Int[]]$AllowedExitCodes=@(0)
103 $installerPath = $LocalPath
104 if($PSCmdlet.ParameterSetName -eq "URL") {
105 $installerPath = Join-Path $env:TEMP $URL.Split('/')[-1]
106 Start-FileDownload -URL $URL -Destination $installerPath
108 Write-Output "Installing ${installerPath}"
110 "FilePath" = $installerPath
111 "ArgumentList" = $Params
112 "NoNewWindow" = $true
116 if((Get-ChildItem $installerPath).Extension -eq '.msi') {
117 $kwargs["FilePath"] = "msiexec.exe"
118 $kwargs["ArgumentList"] = @("/i", $installerPath) + $Params
120 $p = Start-Process @kwargs
121 if($p.ExitCode -notin $AllowedExitCodes) {
122 Throw "Installation failed. Exit code: $($p.ExitCode)"
124 if($PSCmdlet.ParameterSetName -eq "URL") {
125 Start-ExecuteWithRetry `
126 -ScriptBlock { Remove-Item -Force -Path $installerPath -ErrorAction Stop } `
127 -RetryMessage "Failed to remove ${installerPath}. Retrying"