.netpowershellurlftpftpwebrequest

Escape the @ character in my PowerShell FTP script


I want to upload some data to three different FTP servers. It's working for two of the three servers. The reason why it's not working for the third server is, that there is an @-sign in the password and I am not capable of escaping it. It just doesn't work. Sorry I cant show you the password, but just imagine ftp://username:p@ssword@ftp-server.com. The PowerShell now thinks, that the password already stops at the first @-sign, but it does not. So the password the PowerShell is using is wrong and the address to the FTP server is wrong too.

I tried escaping it with '@' or in ASCII code [char]64 or as parameters. I really don't know what to try else...

$request = [Net.WebRequest]::Create("ftp://username:p@ssword@example.com/")
$request.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile 

$fileStream = [System.IO.File]::OpenRead("C:\Users\Desktop\file.zip")
$ftpStream = $request.GetRequestStream()

$buffer = New-Object Byte[] 10240
while (($read = $fileStream.Read($buffer, 0, $buffer.Length)) -gt 0)
{
    $ftpStream.Write($buffer, 0, $read)
    $pct = ($fileStream.Position / $fileStream.Length)
    Write-Progress `
        -Activity "Uploading" -Status ("{0:P0} complete:" -f $pct) `
        -PercentComplete ($pct * 100)
}

$fileStream.CopyTo($ftpStream)

$ftpStream.Dispose()
$fileStream.Dispose()

Solution

  • Easiest is to use WebRequest.Credentials instead of specifying the credentials in the URL:

    $request = [Net.WebRequest]::Create("ftp://example.com/")
    $request.Credentials = New-Object System.Net.NetworkCredential("username", "p@ssword") 
    

    Alternatively, you can use Uri.EscapeDataString:

    $encodedPassword = [Uri]::EscapeDataString("p@ssword") 
    $request = [Net.WebRequest]::Create("ftp://username:$encodedPassword@example.com/")
    

    It will give you: p%40ssword – Learn about URL encoding.


    Similarly for WebClient: Using special characters (slash) in FTP credentials with WebClient