Download files using Start-BitsTransfer in asynchronous mode
function Get-FileBitsTransferAsynchronous{
param(
[Parameter(Mandatory=$true)]
$url,
$destinationFolder="$env:USERPROFILE\Downloads",
[switch]$includeStats
)
$start = Get-Date
$job = Start-BitsTransfer -Source $url -Destination $destinationFolder -DisplayName 'Download' -Asynchronous
$destination = Join-Path $destinationFolder ($url | Split-Path -Leaf)
while (($job.JobState -eq 'Transferring') -or ($job.JobState -eq 'Connecting')){
filter Get-FileSize {
"{0:N2} {1}" -f $(
if ($_ -lt 1kb) { $_, 'Bytes' }
elseif ($_ -lt 1mb) { ($_/1kb), 'KB' }
elseif ($_ -lt 1gb) { ($_/1mb), 'MB' }
elseif ($_ -lt 1tb) { ($_/1gb), 'GB' }
elseif ($_ -lt 1pb) { ($_/1tb), 'TB' }
else { ($_/1pb), 'PB' }
)
}
$elapsed = ((Get-Date) - $start)
#calculate average speed in Mbps
$averageSpeed = ($job.BytesTransferred * 8 / 1MB) / $elapsed.TotalSeconds
$elapsed = $elapsed.ToString('hh\:mm\:ss')
#calculate remaining time considering average speed
$remainingSeconds = ($job.BytesTotal - $job.BytesTransferred) * 8 / 1MB / $averageSpeed
$receivedSize = $job.BytesTransferred | Get-FileSize
$totalSize = $job.BytesTotal | Get-FileSize
$progressPercentage = [int]($job.BytesTransferred / $job.BytesTotal * 100)
if ($remainingSeconds -as [int]){
Write-Progress -Activity (" $url {0:N2} Mbps" -f $averageSpeed) `
-Status ("{0} of {1} ({2}% in {3})" -f $receivedSize, $totalSize, $progressPercentage, $elapsed) `
-SecondsRemaining $remainingSeconds `
-PercentComplete $progressPercentage
}
}
if ($includeStats.IsPresent){
([PSCustomObject]@{Name=$MyInvocation.MyCommand;TotalSize=$totalSize;Time=$elapsed}) | Out-Host
}
Write-Progress -Activity (" $url {0:N2} Mbps" -f $averageSpeed) `
-Status 'Done' -Completed
Switch($job.JobState){
'Transferred' {
Complete-BitsTransfer -BitsJob $job
Get-Item $destination | Unblock-File
}
'Error' {
Write-Warning "Download of $url failed"
$job | Format-List
}
}
}