"Invalid URI: The hostname could not be parsed" + "The requested URI is invalid for this FTP command" 在 PowerShell 中使用 WebClient 下载时

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

我正在尝试使用 PowerShell 连接一台 FTP 服务器,如下所示。

$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()

其中theflowregister\selfregisterflow用户名Buter239#密码waws-prod-am2-555.ftp.azurewebsites.windows.net/site/wwwroot是主机json/ 是子文件夹。

我正在尝试从 FTP 复制一个名为 MilanRamani.json 的文件并将其下载到系统中的特定位置。但是当我执行上面的代码时出现这个错误。

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

#(hash/number 符号)在 URL 中具有特殊含义。如果您想明确使用它,则必须 URL-encode it to %23. You might also have to URL-encode the \ (backslash) as %5C. In general, you can use Uri.EscapeDataString 对凭据(以及文件名)进行编码:

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

另一种更安全的方法是通过 WebClient.Credentials property 设置凭据,而不是 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#")