2

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: $_"
        }
    }
}
Community
  • 1
  • 1
ca9163d9
  • 27,283
  • 64
  • 210
  • 413
  • Are you using a loop to upload files? Does it always fail on the same file? – Andy Arismendi Jan 13 '12 at 01:14
  • @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 Jan 13 '12 at 01:20
  • @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 Jan 13 '12 at 01:37
  • Is the file its failing on bigger or smaller than the ones that are succeeding, if so, how big? – Andy Arismendi Jan 13 '12 at 02:08
  • The failed file is bigger than the succeeded one. The first two files which can be uploaded is 15KB, 11KB respectively. The failed one has the size of 36KB. – ca9163d9 Jan 13 '12 at 04:17
  • What does the path and the filename look like? You have to watch out that you don't use characters that can be interpreted as html. For example #. – Tom Jan 13 '12 at 07:48
  • @Tom The file name look like `########-########-AA-AAAAAAAA.csv.zip`. – ca9163d9 Jan 13 '12 at 15:25
  • I don't get it. Does the # stand for numbers? If it is actually a #-symbol the filename would be treated as empty string because # is an anchor. Link and example in one -> http://en.wikipedia.org/wiki/HTML_element#Anchor – Tom Jan 13 '12 at 15:36
  • @Tom Yes # stands for number. And A stands for letters. For example 500004807-500005398-DM-AAAAAAAA.csv.zip – ca9163d9 Jan 13 '12 at 16:00
  • If `KeepAlive = $false` works then it maybe that you are exceeding the maximum number of concurrent connections for that server. – Andy Arismendi Jan 14 '12 at 05:16
  • @AndyArismendi, i didn't try `KeepAlive = $false` yet. I did tried call Windows ftp program and it works. However, it seems it always fails on the third file (the name I gave above). – ca9163d9 Jan 14 '12 at 05:24
  • If you rename the file to something simple like a.zip does it work? – Andy Arismendi Jan 14 '12 at 05:28
  • @AndyArismendi, it seems not file name issue. It works if I just run `ftpFile 500004807-500005398-DM-AAAAAAAA.csv.zip`. It failed in the loop when it was uploading after the first two files. – ca9163d9 Jan 14 '12 at 06:06
  • 2
    @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 Jan 16 '12 at 08:01

2 Answers2

0

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.

VertigoRay
  • 5,935
  • 6
  • 39
  • 48
  • Yes, it fails on the same files. However, call the `ftpFile name` works without error. Very strange. – ca9163d9 Jan 13 '12 at 01:52
0

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

ca9163d9
  • 27,283
  • 64
  • 210
  • 413