Search code examples
powershell

PowerShell Invoke-WebRequest, how to automatically use original file name?


How can I use Invoke-WebRequest to download a file but automatically make the file name the same as if I downloaded via browser? I haven't found a way to make -OutFile work without manually specifying the file name. I'm fine with this involving a few other lines of code.

A good solution will:

  • Work even if the file name isn't in the request URL. For example, the URL to download the Visual Studio x64 Remote Debugging Tools is http://go.microsoft.com/fwlink/?LinkId=393217 but it downloads the file rtools_setup_x64.exe.
  • Not save the whole file to memory before writing to disk, unless that's what Invoke-WebRequest already does even with the -OutFile parameter (?)

Thanks!


Solution

  • For the example given you're going to need to get the redirected URL, which includes the file name to be downloaded. You can use the following function to do so:

    Function Get-RedirectedUrl {
    
        Param (
            [Parameter(Mandatory=$true)]
            [String]$URL
        )
    
        $request = [System.Net.WebRequest]::Create($url)
        $request.AllowAutoRedirect=$false
        $response=$request.GetResponse()
    
        If ($response.StatusCode -eq "Found")
        {
            $response.GetResponseHeader("Location")
        }
    }
    

    Then it's a matter of parsing the file name from the end of the responding URL (GetFileName from System.IO.Path will do that):

    $FileName = [System.IO.Path]::GetFileName((Get-RedirectedUrl "http://go.microsoft.com/fwlink/?LinkId=393217"))
    

    That will leave $FileName = rtools_setup_x64.exe and you should be able to download your file from there.