This file download function is a modified version of the one found in the top comment here. I wanted to format the file sizes a little better and make the function slightly more robust.
I found a file size conversion function that seemed to work well for me. The function is available for download from the TechNet Gallery. You can read more about the function on Boe’s blog post here.
I added an ExtraVerbose switch to suppress the verbose output from the size conversion function unless it is desired.
Function Download-File { [cmdletbinding()] Param ( [parameter(Mandatory=$True,Position=0)][Alias("Source","URL")][string]$dlURL, [parameter(Mandatory=$False,Position=1)][Alias("Target","File")][string]$dlFile = "$((Get-Item -Path ".\" -Verbose).FullName)\$(($dlURL.split('/') | Select -Last 1).Split('?') | Select -First 1)", [parameter(Mandatory=$False)][switch]$ExtraVerbose = $False ) if($ExtraVerbose) { $oldverbose = $VerbosePreference $VerbosePreference = "continue" } $dlRequired = $true Write-Verbose ("Connecting to website") $webRequest = [System.Net.HttpWebRequest]::Create($dlURL) $webRequest.set_Timeout(15000) #15 second timeout $webResponse = $webRequest.GetResponse() $webLength = [System.Math]::Floor($webResponse.get_ContentLength()) if(Test-Path $dlFile) { Write-Verbose ("File exists checking modified date and file size") $localMod = (Get-Item $dlFile).LastWriteTime $localLength = (Get-Item $dlFile).Length $webMod = ($webResponse.LastModified) -as [DateTime] if (($webMod -le $localMod) -and ($webLength -eq $localLength)) { Write-Verbose ("File is the same size and date is same or newer, no download necessary") $dlRequired = $false } } if ($dlRequired) { $responseStream = $webResponse.GetResponseStream() Write-Verbose ("Creating file stream") $targetStream = New-Object -TypeName System.IO.FileStream -ArgumentList $dlFile,Create $buffer = New-Object byte[] 10KB $count = $responseStream.Read($buffer,0,$buffer.length) $downloadedBytes = $count Write-Verbose ("Downloading file") while ($count -gt 0) { $targetStream.Write($buffer, 0, $count) $count = $responseStream.Read($buffer,0,$buffer.length) $downloadedBytes = $downloadedBytes + $count Write-Progress -Activity "Downloading file '$(($dlURL.split('/') | Select -Last 1).Split('?') | Select -First 1)'" -Status "Downloaded $(Convert-Size -Size $downloadedBytes -Verbose:$ExtraVerbose) of $(Convert-Size -Size $webLength -Verbose:$ExtraVerbose))" -PercentComplete (($downloadedBytes / $webLength) * 100) } Write-Progress -Activity "Downloading file '$(($dlURL.split('/') | Select -Last 1).Split('?') | Select -First 1)'" -Status "Download complete." -Completed Write-Verbose ("File download complete") $targetStream.Flush() $targetStream.Close() $targetStream.Dispose() $responseStream.Dispose() } $webResponse.Close() $webResponse.Dispose() $VerbosePreference = $oldverbose }
Leave a Reply