Search code examples
powershellcurlftpinvoke-webrequest

How to fix curl syntax error in Windows Powershell?


I'm trying to use curl in Windows Powershell to download a file from an SFTP/FTPS site, I have tried to follow the examples in How to use curl on Windows, which seem to indicate that I can download from an SFTP/FTPS site. I do the following:

PS C:\temp> curl -User 'username:password' -Uri 'ftp://ftp.company.com/devops/path/somefile.txt' -OutFile somefile.txt

But I get the following error

curl : The remote server returned an error: (530) Not logged in.
At line:1 char:1
+ curl -User 'username:password' -Uri 'ftp://ftp.company.com/devops ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.FtpWebRequest:FtpWebRequest) [Invoke-WebRequest], W
   ebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestComma
   nd

I've also tried ideas in other Stackoverflow posts, e.g., How to use the curl command in PowerShell?, to no avail. What is my syntax error?


Solution

  • Building on the helpful comments:

    • In Windows PowerShell (but no longer in PowerShell (Core) 7+) curl is built-in alias of Invoke-WebRequest, whose syntax is very different from that of curl.exe.

      • To reliably invoke the latter on Windows, invoke it with .exe (curl.exe ...)

      • curl.exe ships with Windows since Windows 10 / Windows Server 2019.

    • Your attempt ended up calling Invoke-WebRequest, as evidenced by the error message you saw.

      • While your call technically fulfills the syntax requirements of Invoke-WebRequest, it cannot work as intended:

        • -User, thanks to PowerShell's "elastic syntax", prefix-matched the -UserAgent parameter, which is not your intent.

        • Since no credentials were actually passed (which would require the -Credential parameter), you received the error you saw.


    Therefore, you have two options:

    • Stick with Invoke-WebRequest and use its parameters properly.

      • However, given that FTP support has been removed from Invoke-WebRequest in PowerShell (Core) 7+, perhaps using curl.exe is better (see next point).
    • Switch to curl.exe and use its parameters properly; e.g.:

      curl.exe -u 'username:password' ftp://ftp.company.com/devops/path/somefile.txt -o somefile.txt