How to download file with powershell?

Viewed 780

In the past I did use :

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$url = "https://nodejs.org/dist/v14.17.6/node-v14.17.6-x64.msi"
$folder = "C:\Users\test\Downloads"

$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile($url, $folder)

When I try today it shows this error

  Exception calling "DownloadFile" with "2" argument(s): "An exception occurred during a WebClient request."
  At line:1 char:5
  +     $WebClient.DownloadFile($url, $folder)
  +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
      + FullyQualifiedErrorId : WebException

I tried to fix with suggestions found but none worked.

2 Answers

You'll need to extract the file name so you have a full path for the outfile, but this will work:

$url = "https://nodejs.org/dist/v14.17.6/node-v14.17.6-x64.msi"
$fullPath = "C:\Users\test\Downloads\node-v14.17.6-x64.msi"
Invoke-WebRequest $url -outfile $fullPath

To complement James World's effective solution:

To clarify:

In the past I did use:

System.Net.WebClient.DownloadFile() always required a file path as the second argument - passing just a directory path - as desirable as that is - did not work.

Obviously, it would be convenient to be able to specify just a local directory path, so as to have the file name part be implied, either by:

  • the filename attribute of the Content-Disposition response-header field

  • or, in its absence, by the last URL component - assuming it is a legal file name.

Regrettably, the -OutFile parameters of PowerShell's Invoke-WebRequest and Invoke-RestMethod cmdlets also do not support passing a directory path, as of PowerShell 7.2.

  • GitHub issue #11671 is the latest of several feature requests that asks for addressing this limitation. While such an enhancement has been green-lit in principle, initially as an experimental feature, no one has stepped up to implement it so far.

In the case at hand, you can programmatically derive the target file name from the URL as follows:

$url = "https://nodejs.org/dist/v14.17.6/node-v14.17.6-x64.msi"
$folder = "C:\Users\test\Downloads"

Invoke-WebRequest $url -OutFile "$folder\$(Split-Path -Leaf $url)"
Related