Public/Save-EvergreenApp.ps1
function Save-EvergreenApp { <# .EXTERNALHELP Evergreen-help.xml #> [OutputType([System.Management.Automation.PSObject])] [CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = "Path")] [Alias("sea")] param ( [Parameter( Mandatory = $true, Position = 0, ValueFromPipeline, HelpMessage = "Pass an application object from Get-EvergreenApp.")] [ValidateNotNull()] [System.Management.Automation.PSObject] $InputObject, [Parameter( Mandatory = $false, Position = 1, ValueFromPipelineByPropertyName, HelpMessage = "Specify a top-level directory path where the application installers will be saved into.", ParameterSetName = "Path")] [System.IO.FileInfo] $Path, [Parameter( Mandatory = $false, Position = 1, ValueFromPipelineByPropertyName, HelpMessage = "Specify a single directory path where all application installers will be saved into.", ParameterSetName = "CustomPath")] [Alias("LiteralPath")] [System.IO.FileInfo] $CustomPath, [Parameter(Mandatory = $false, Position = 2)] [System.String] $Proxy, [Parameter(Mandatory = $false, Position = 3)] [System.Management.Automation.PSCredential] $ProxyCredential = [System.Management.Automation.PSCredential]::Empty, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $UserAgent = $script:resourceStrings.UserAgent.Base, [Parameter(Mandatory = $false)] [System.Management.Automation.SwitchParameter] $Force, [Parameter(Mandatory = $false)] [System.Management.Automation.SwitchParameter] $NoProgress ) begin { # Disable the Invoke-WebRequest progress bar for faster downloads if ($PSBoundParameters.ContainsKey("Verbose") -and !($PSBoundParameters.ContainsKey("NoProgress"))) { $ProgressPreference = [System.Management.Automation.ActionPreference]::Continue } else { $ProgressPreference = [System.Management.Automation.ActionPreference]::SilentlyContinue } # Path variable from parameters set via -Path or -CustomPath switch ($PSCmdlet.ParameterSetName) { "Path" { if ([System.String]::IsNullOrEmpty($Path)) { throw "Cannot bind argument to parameter 'Path' because it is null." } $NewPath = $Path } "CustomPath" { if ([System.String]::IsNullOrEmpty($CustomPath)) { throw "Cannot bind argument to parameter 'CustomPath' because it is null." } $NewPath = $CustomPath } } #region Test $Path and attempt to create it if it doesn't exist if (Test-Path -Path $NewPath -PathType "Container") { Write-Verbose -Message "Path exists: $NewPath." } else { Write-Verbose -Message "Path does not exist: $NewPath." Write-Verbose -Message "Create: $NewPath." $params = @{ Path = $NewPath ItemType = "Container" ErrorAction = "Stop" } New-Item @params | Out-Null } #endregion # Enable TLS 1.2 [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 } process { # Loop through each object and download to the target path foreach ($Object in $InputObject) { #region Validate the URI property and find the output filename if ([System.Boolean]($Object.URI)) { Write-Verbose -Message "URL: $($Object.URI)." if ([System.Boolean]($Object.FileName)) { $OutFile = $Object.FileName } elseif ([System.Boolean]($Object.URI)) { $OutFile = Split-Path -Path $Object.URI -Leaf } } else { throw [System.Management.Automation.PropertyNotFoundException] "InputObject does not have valid URI property." } #endregion # Handle the output path depending on whether -Path or -CustomPath are used switch ($PSCmdlet.ParameterSetName) { "Path" { # Resolve $Path to build the initial value of $OutPath $OutPath = Resolve-Path -Path $Path -ErrorAction "SilentlyContinue" if ($null -ne $OutPath) { #region Validate the Version property if ([System.Boolean]($Object.Version)) { # Build $OutPath with the "Channel", "Release", "Language", "Architecture" properties $OutPath = New-EvergreenPath -InputObject $Object -Path $OutPath } else { throw [System.Management.Automation.PropertyNotFoundException] "InputObject does not have valid Version property." } #endregion } else { throw [System.IO.DirectoryNotFoundException] "Failed validating $OutPath." } } "CustomPath" { $OutPath = Resolve-Path -Path $CustomPath -ErrorAction "Stop" } } $DownloadFile = $(Join-Path -Path $OutPath -ChildPath $OutFile) if ($PSBoundParameters.ContainsKey("Force") -or !(Test-Path -Path $DownloadFile -PathType "Leaf")) { #region Download the file # If URL in the catch list, customise the user agent if ($Object.URI -match $script:resourceStrings.UserAgent.CatchList -and -not($PSBoundParameters.ContainsKey("UserAgent"))) { Write-Verbose -Message "URL matches catch list for custom user agent: $($Object.URI)." $UserAgent = "Evergreen/$((Get-Module -Name "Evergreen").Version)" } # Invoke-WebRequest parameters $params = @{ Uri = $Object.URI OutFile = $DownloadFile UseBasicParsing = $true UserAgent = $UserAgent ErrorAction = "Continue" } if ($PSBoundParameters.ContainsKey("Proxy")) { $params.Proxy = $Proxy } if ($PSBoundParameters.ContainsKey("ProxyCredential")) { $params.ProxyCredential = $ProxyCredential } # Output the parameters when using -Verbose foreach ($item in $params.GetEnumerator()) { Write-Verbose -Message "Invoke-WebRequest parameter: $($item.name): $($item.value)." } # Download the file if ($PSCmdlet.ShouldProcess($Object.URI, "Download")) { Invoke-WebRequest @params } #endregion # Write the downloaded file path to the pipeline if (Test-Path -Path $DownloadFile) { Write-Verbose -Message "Successfully downloaded: $DownloadFile." Write-Output -InputObject $(Get-ChildItem -Path $DownloadFile) } } else { #region Write the downloaded file path to the pipeline if (Test-Path -Path $DownloadFile) { Write-Verbose -Message "File exists: $DownloadFile." Write-Output -InputObject $(Get-ChildItem -Path $DownloadFile) } #endregion } } } end { Write-Verbose -Message "Complete." if ($PSCmdlet.ShouldProcess("Remove variables")) { if (Test-Path -Path Variable:params) { Remove-Variable -Name "params" -ErrorAction "SilentlyContinue" } Remove-Variable -Name "OutPath", "OutFile" -ErrorAction "SilentlyContinue" } } } |