Downloader.ps1
. $PSScriptRoot\UserInterface.ps1 . $PSScriptRoot\SessionManager.ps1 Add-Type -TypeDefinition @" public enum ChecksumStatus { Skipped, Passed, Failed, } "@ Function DownloadFiles { Param( [Parameter(Mandatory=$True)] [System.Collections.ArrayList] $Uris, [Parameter(Mandatory=$True)] [String] $DestinationFolder, [Switch] $WithChecksums, [Parameter(Mandatory=$True)] [Microsoft.PowerShell.Commands.WebRequestSession] $AuthenticatedSession ) $OldPreference = $ProgressPreference $ProgressPreference = 'SilentlyContinue' $PadLeft = GetLeftNumberPadding -Count $Uris.Count $DownloadStats = [PSCustomObject]@{ FilesFound = [System.Collections.ArrayList]::new(); FilesNotFound = [System.Collections.ArrayList]::new(); FilesChecksumPassed = [System.Collections.ArrayList]::new(); FilesChecksumFailed = [System.Collections.ArrayList]::new(); FilesChecksumSkipped = [System.Collections.ArrayList]::new(); } $Count = 0 ForEach ($PSObj in $Uris) { $Count += 1 $ObjectUri = $PSObj.Uri $StringUri = [String] $ObjectUri $OutputFileName = $ObjectUri.Segments[$ObjectUri.Segments.Length - 1] $OutputFilePath = Join-Path -Path $DestinationFolder -ChildPath $OutputFileName $StringCount = ([String] $Count).PadLeft($PadLeft, ' ') Write-Host "$StringCount - $OutputFileName " -NoNewline $Response = DownloadSingleFile -Uri $ObjectUri ` -WebSession $AuthenticatedSession ` -OutFile $OutputFilePath If ($Response.Status -ne 200) { Write-Host "($($Reponse.Status) $($Response.Description))" -ForegroundColor Red $DownloadStats.FilesNotFound.Add($StringUri) | Out-Null If ($WithChecksums) { $DownloadStats.FilesChecksumSkipped.Add($StringUri) | Out-Null } Continue } $DownloadStats.FilesFound.Add($StringUri) | Out-Null $FileLength = GetHumanReadableSize -Bytes $Response.FileSize If ($WithChecksums) { $Status = VerifyChecksum -File $OutputFilePath ` -Algorithm $PSObj.Algorithm ` -Checksum $PSObj.Checksum Write-Host "($FileLength | " -NoNewline Switch($Status) { "Skipped" { Write-Host 'EMPTY CHECKSUM - SKIPPED' -ForegroundColor Yellow -NoNewline Write-Host ')' $DownloadStats.FilesChecksumSkipped.Add($StringUri) | Out-Null Break } "Passed" { Write-Host 'CHECKSUM OK' -ForegroundColor Green -NoNewline Write-Host ')' $DownloadStats.FilesChecksumPassed.Add($StringUri) | Out-Null Break } "Failed" { Write-Host 'CHECKSUM FAILED' -ForegroundColor Red -NoNewline Write-Host ')' $DownloadStats.FilesChecksumFailed.Add($StringUri) | Out-Null Break } } } Else { Write-Host "($FileLength)" } } $ProgressPreference = $OldPreference $DownloadStats } Function DownloadSingleFile { Param( [Parameter(Mandatory=$True)] [System.Uri] $Uri, [Parameter(Mandatory=$True)] [String] $OutFile, [Parameter(Mandatory=$True)] [Microsoft.PowerShell.Commands.WebRequestSession] $WebSession ) $Status = 200 $Description = 'OK' $FileSize = $Null Try { $Response = Invoke-WebRequest -Uri $Uri -WebSession $WebSession -OutFile $OutFile $FileSize = (Get-Item $OutFile).Length } Catch { If ($Response -or $_.Exception.Response) { If (-Not $Response) { $Response = $_.Exception.Response } $Result = ExtractStatusCodeAndDescription -Response $Response $Status = $Result.Code $Description = ([String] $Result.Description).ToUpper() } Else { $Status = '???' $Description = $_.Exception.Message } } [PSCustomObject] @{ Status = $Status; Description = $Description; FileSize = $FileSize; } } Function VerifyChecksum { Param( [Parameter(Mandatory=$True)] [String] $File, [AllowEmptyString()] [AllowNull()] [String] $Checksum, [AllowEmptyString()] [AllowNull()] [String] $Algorithm ) If (-Not $Checksum) { Return [ChecksumStatus]::Skipped } $ComputedHash = (Get-FileHash -Path $OutputFilePath -Algorithm $Algorithm).Hash.ToLower() If ($ComputedHash -eq $Checksum) { Return [ChecksumStatus]::Passed } Else { Return [ChecksumStatus]::Failed } } |