2
votes

I got the the following error message when uploading. The Powershell create a zip file using 7za.exe and call my FTP function to upload the file. What may cause the problem? Will Windows ftp.exe client be more stable?

Exception calling "GetRequestStream" with "0" argument(s): "The remote server returned an error: (550) File unavailable (e.g., file not found, no access)."

Update:
It seems the same files always failed in the loop. However, It works if I just run ftpFile file_name_with_full_path. (The file_name_with_full_path is copied from the output of the loop script.

Update 2:
I tried to use webclient ($webclient.UploadFile($uri, $File)) to ftp the files. Same error.

Update 3:
Found this Question. May need to add $ftp.KeepAlive = false. Why?

function ftpFile
{
    Param (
        [Parameter(Mandatory=$true, ValueFromPipeline=$true)]
        [ValidateScript({Test-Path $_})]
        [String] 
        $filePath
        ,
        [Parameter(Mandatory=$false)]
        [String]
        $ftpUrl = "ftp://10.0.1.1/Data/"
        ,
        [Parameter(Mandatory=$false)]
        [String]
        $Login = "username"
        ,    
        [Parameter(Mandatory=$false)]
        [String]
        $password = "password"
    )
    Process {
        try {
            $ftp = [System.Net.FtpWebRequest]::Create("$ftpUrl/$(Split-Path $filePath -Leaf)")
            $ftp = [System.Net.FtpWebRequest]$ftp
            $ftp.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile
            $ftp.Credentials = new-object System.Net.NetworkCredential("$Login","$password")
            $ftp.UseBinary = $true
            $ftp.UsePassive = $true

            # read in the file to upload as a byte array
            $content = gc -en byte $filePath
            $ftp.ContentLength = $content.Length

            # get the request stream, and write the bytes into it
            $rs = $ftp.GetRequestStream()
            $rs.Write($content, 0, $content.Length)
            $rs.Close()
            $rs.Dispose()

            echo "ftpFile: $filePath size: $($content.Length)"
        }
        catch {
            throw "FTP: $_"
        }
    }
}
2
Are you using a loop to upload files? Does it always fail on the same file? - Andy Arismendi
@AndyArismendi Yes, I am using a loop to upload the files. The uploaded files were zipped right before uploading. I added start-sleep -s 1 before call the ftpFile. - ca9163d9
@AndyArismendi Yes, it seems it always fails on the same file. Even thought the file is newly generated. And it only has the problem in the loop. - ca9163d9
Is the file its failing on bigger or smaller than the ones that are succeeding, if so, how big? - Andy Arismendi
@NickW yeah, now I remember. Uploading files to the same server in short intervals lead me to the same problem. Set the keepalive to false. If keepalive is true the server expects more input from the same webrequest but the responsestream is kind of done already. I figured when I waited some seconds between the uploads it would work. But the keepalive option is surely better. The connection really ends after uploading a file. - Tom

2 Answers

0
votes

FTP Error 550 is Access Denied and tends to be a username/password conflict.

If you're using a loop and passing the same username and password each time this function is called AND it's working on some iterations of the loops and not others THEN you need to check the ftp auth/error logs on the server to get a grasp of why you're being denied.

As @AndyArismendi asked, does it always fail on the same file? Without more complete code and understanding of your use, this is hard to lock down to a simple solution.

0
votes

Found this Question. Need to add $ftp.KeepAlive = false.