Divyesh Jesadiya
Divyesh Jesadiya

Reputation: 957

"Invalid URI: The hostname could not be parsed" + "The requested URI is invalid for this FTP command" when downloading using WebClient in PowerShell

I am trying to connect one FTP server using PowerShell like below.

$line = 'MilanRamani.json'
$file = "C:\brivo\json\" + $line
$ftpuri = "ftp://theflowregister\selfregisterflow:Buter239#@waws-prod-am2-555.ftp.azurewebsites.windows.net/site/wwwroot/json/" + $line
$webclient = New-Object System.Net.WebClient
$uri = New-Object System.Uri($ftpuri)
$webclient.DownloadFile($uri,$file)
$webclient.Dispose()

Where theflowregister\selfregisterflow is a username, Buter239# is password, waws-prod-am2-555.ftp.azurewebsites.windows.net/site/wwwroot is host and json/ is subfolder.

I am trying to copy one file named MilanRamani.json from FTP and download it at a particular location in the system. but I am getting this error when I execute the above code.

New-Object : Exception calling ".ctor" with "1" argument(s): "Invalid URI: The hostname could not be parsed."
At line:5 char:8
+ $uri = New-Object System.Uri($ftpuri)
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : 
ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

Exception calling "DownloadFile" with "2" argument(s): "The requested URI is invalid for this 
FTP command."
At line:6 char:1
+ $webclient.DownloadFile($uri,$file)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException

Upvotes: 2

Views: 1688

Answers (1)

Martin Prikryl
Martin Prikryl

Reputation: 202168

The # (hash/number sign) has special meaning in URL. If you want to use it explicitly, you have to URL-encode it to %23. You might also have to URL-encode the \ (backslash) as %5C. In general, you can use Uri.EscapeDataString to encode the credentials (and also the filename):

$ftpuri =
    "ftp://" +
    [Uri]::EscapeDataString("theflowregister\selfregisterflow") + ":" + 
    [Uri]::EscapeDataString("Buter239#") +
    "@waws-prod-am2-555.ftp.azurewebsites.windows.net/site/wwwroot/json/" +
    [Uri]::EscapeDataString($line)

An alternative and safer approach is to set the credentials via WebClient.Credentials property, instead of the URL:

$ftpuri =
    "ftp://waws-prod-am2-555.ftp.azurewebsites.windows.net/site/wwwroot/json/" +
    [Uri]::EscapeDataString($line)
$uri = New-Object System.Uri($ftpuri)
$webclient = New-Object System.Net.WebClient
$webclient.Credentials =
    New-Object System.Net.NetworkCredential(
        "theflowregister\selfregisterflow", "Buter239#")

Upvotes: 1

Related Questions