Invoke-DownloadMsixPackage.ps1

<#
.SYNOPSIS
    This script downloads the converted MSIX installer.
 
.DESCRIPTION
    This script reads the conversion Id and download location
    and invokes the download MSIX REST API.
 
.PARAMETER ConversionId
    The Conversion Id is required.
 
.PARAMETER Env
    Optional parameter of the environment value.
 
.PARAMETER downloadLocation
    Specifies a path to a location. The value of
    downloadLocation is used exactly as it is typed. No characters are interpreted
    as wildcards. If the path includes escape characters, enclose it in single
    quotation marks. Single quotation marks tell Windows PowerShell not to
    interpret any characters as escape sequences.
 
.OUTPUTS
    The file gets downloaded to the provided location.
#>


# Uncomment for debugging
# Set-PSDebug -Trace 2

# function to the validate the checksum of the downloaded file
function Compare-SHA256() {

    param (
        [Parameter(Mandatory, HelpMessage = "Please provide location of the file.", Position=0)]
        [string] $fileName,

        [Parameter(Mandatory, HelpMessage = "Please provide the SHA256 value of the file.", Position=1)]
        [string] $hash
    )

    $calculatedHash = (Get-FileHash $fileName -Algorithm SHA256).Hash.ToUpper()
    $calculatedHash -eq $hash.ToUpper()
}

function Invoke-DownloadMsixPackage() {

    # Conversion Id as a mandatory input
    # Destination location to save the file
    param (
        [Parameter(Mandatory, HelpMessage = "Please provide a valid conversion Id.", Position=0)]
        [ValidatePattern(
        "^([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$",
        ErrorMessage = "Conversion Id {0} is not valid."
        )]
        [string] $ConversionId,

        [Parameter(HelpMessage = "Optional Parameter: Enter the location where you want to save the installer file", Position=1)]
        [string] $DownloadLocation,

        [Parameter(HelpMessage = "Optional Parameter: Please provide the environment value.")]
        [string]$Env
    )
    
    # Get Environment value
    if ( !$Env )
    {
       $Env = "msix"
    }
    $global:devRestEndPoint = $(Get-Content "$PSScriptRoot/config.json" | ConvertFrom-Json).$Env.url

    Write-Debug "The entered conversion Id is $ConversionId"

    if ([string]::IsNullOrEmpty($DownloadLocation)) {
        $DownloadLocation = (Get-Location)
    }

    if (!(Test-Path -Path "$DownloadLocation")) {
        Write-Output "Download location not valid"
        Write-Output "Download location: $DownloadLocation"
        return
    }

    # Get Full Absolute download path
    $DownloadLocation = [System.IO.Path]::GetFullPath($DownloadLocation)
    $DownloadLocation = $DownloadLocation.TrimEnd('\')

    Write-Debug "The download location is $DownloadLocation "

    Try
    {
        # REST API invocation
        Authenticate($Env)

        $restEndpoint = $global:devRestEndPoint + "download/v1/msix/" + $ConversionId

        $header = @{
            authorization=$global:bearerToken
        }
        $Response = ConvertFrom-Json $([String]::new((Invoke-WebRequest -Uri $restEndpoint -Header $header -MaximumRedirection 1).Content))

        # Destination to save the file
        $DownloadLocation = $DownloadLocation + "\" + $Response.packageName

        # Trigger download
        Start-BitsTransfer -Source $Response.uri -Destination $DownloadLocation

        # Make the file readonly for now
        Set-ItemProperty -Path $DownloadLocation -Name IsReadOnly -Value $true

        # Compare the checksum
        if (Compare-SHA256 $DownloadLocation $Response.checksum)
        {
            Write-Debug "Checksum validation succeeded for the downloaded file."
            Write-Output "Successfully downloaded file : $DownloadLocation"
            # Give executable permissions on the file
            Set-ItemProperty -Path $DownloadLocation -Name IsReadOnly -Value $false
            return
        }
        else
        {
             Write-Output "Checksum validation failed, file might be corrupted. Kindly try again!"
             Write-Debug "Removing file: $DownloadLocation"
             Set-ItemProperty -Path $DownloadLocation -Name IsReadOnly -Value $false
             Remove-Item -Path $DownloadLocation
             return
        }
    }
    Catch
    {
        if (Test-Path -Path $DownloadLocation -PathType Leaf)
        {
            Set-ItemProperty -Path $DownloadLocation -Name IsReadOnly -Value $false
            Remove-Item -Path $DownloadLocation
        }
        Register-Error($_)
    }
}