function Save-WinUtilFile { <# .SYNOPSIS Downloads a file and reports transfer progress. #> param( [Parameter(Mandatory)] [uri]$Uri, [Parameter(Mandatory)] [string]$DestinationPath, [Parameter(Mandatory)] [scriptblock]$ProgressCallback ) $response = $null $responseStream = $null $outputStream = $null try { $request = [System.Net.WebRequest]::Create($Uri) $response = $request.GetResponse() $totalBytes = $response.ContentLength $responseStream = $response.GetResponseStream() $outputStream = [System.IO.File]::Create($DestinationPath) $buffer = New-Object byte[] 81920 $downloadedBytes = 0L $lastPercent = -1 while (($bytesRead = $responseStream.Read($buffer, 0, $buffer.Length)) -gt 0) { $outputStream.Write($buffer, 0, $bytesRead) $downloadedBytes += $bytesRead if ($totalBytes -gt 0) { $percent = [Math]::Min(100, [int](($downloadedBytes / $totalBytes) * 100)) if ($percent -ne $lastPercent) { & $ProgressCallback $percent $lastPercent = $percent } } } if ($lastPercent -ne 100) { & $ProgressCallback 100 } } finally { if ($null -ne $outputStream) { $outputStream.Dispose() } if ($null -ne $responseStream) { $responseStream.Dispose() } if ($null -ne $response) { $response.Dispose() } } }