2

From a Windows Server 2012, using PoweShell, I connect to a remote device through ftp and run get to retrieve a file. The process goes through with no problems but the file doesn't get saved on to my local machine. The command returns Operation Complete and after a few seconds the connection gets closed.

Operation CompleteConnection closed by remote host.
ftp> 

On the destination location a temporary file of size 0 gets created at the beginning of the process and it remains unchanged. Tmp6A94.tmp

I have tried to open up the firewall following this How to Configure Windows Firewall for a Passive Mode FTP Server

netsh advfirewall firewall add rule name=”FTP Service” dir=in protocol=TCP enable=yes action=allow profile=any service=ftpsvc localport=any 
netsh advfirewall set global StatefulFTP disable

What am I missing?

EDIT 1

I have tested the ftp behavior on another WS2012 and also on a WS2012R2 and the two do not have the same issue. None of them have the firewall ftp passive mode. I wonder if there might be some other firewall rule that enables the ftp transfer.

EDIT 2

This is the PowerShell script I use to retrieve the file from the remote device through ftp:

function getFTPFile([String]$fileName)
{
    $ftpUser = "user"
    $ftpPassword = "password"
    $ftpServer = "ftpServer"

    $webclient = New-Object System.Net.WebClient 
    $webclient.Credentials = New-Object System.Net.NetworkCredential($ftpUser, $ftpPassword)

    $uri = New-Object System.Uri("$ftpServer/files")

    $webclient.DownloadFile($uri, $fileName)
} 

Running this script or doing it manually from the PowerShell console renders the same outcome. Everything will run properly until the file needs to be saved on the destination. I have successfully used this script on other Windows Servers.

This is the error thrown by the script:

Exception calling "DownloadFile" with "2" argument(s): "The remote server returned an error: 150-Starting operation:
STATUS: Getting logs ...
Please wait...
Please wait...
STATUS: Finished getting logs
STATUS: get logs operation is complete
Size: 8262246 bytes
Please wait for 8 seconds ...
Operation Complete150-Accepted data connection
150 (8262246 bytes) to download
."
At C:\Users\administrator\getFTPFile.ps1:73 char:2
+     $webclient.DownloadFile($uri, $fileName)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : WebException

And this is the failed operation from a PowerShell prompt:

ftp> get logs logsFile
200 PORT command successful
150-Starting operation:
STATUS: Getting logs ...
Please wait...
Please wait...
STATUS: Finished getting logs
STATUS: get logs operation is complete
Size: 8283146 bytes
Please wait for 8 seconds ...

Operation CompleteConnection closed by remote host.

This is the output when the transfer is successful:

ftp> get logs logsFile
200 PORT command successful
150-Starting operation:
STATUS: Getting logs ...
Please wait...
Please wait...
STATUS: Finished getting logs
STATUS: get logs operation is complete
Size: 8283146 bytes
Please wait for 8 seconds ...

Operation Complete150-Connecting to port 63596
150 (8275012 bytes) to download
226-File successfully transferred
226 0.778 seconds (measured here), 10.15 Mbytes per second
ftp: 8275012 bytes received in 0.76Seconds 10916.90Kbytes/sec.

Also, I have not tried any other FTP clients.

EDIT 3

Now it's working when using ftp from PowerShell terminal and not working through the script, ran from the PowerShell.

slybloty
  • 443
  • 2
  • 9
  • 30
  • sounds like it could be a permission problem on the local server; is your ftp process allowed to create files there? – user16081-JoeT Jan 29 '14 at 00:06
  • Sounds like the server is setup for PASV mode and the firewall is only opening ports for ACTIVE mode which allows the commands but not the data. Temporarily disable your firewall and test to confirm, and if it works then you'll need to check your ftp server and firewall configuration. – Brock Hensley Jan 29 '14 at 02:18
  • @BrockHensley-FKAdirt If I disable the firewall it works fine. I don't have access to the ftp server. The only changes I can make are on my servers. – slybloty Jan 29 '14 at 15:10
  • The Firewall needs to allow PASV communication (which is a wide range of ports) otherwise changing your server to use ACTIVE mode restricts it to just 20/21 ports. – Brock Hensley Jan 29 '14 at 15:15
  • @BrockHensley-FKAdirt According to [Microsoft](http://technet.microsoft.com/en-us/library/dd421710(WS.10).aspx) I've already configured the port for passive communication. – slybloty Jan 29 '14 at 17:45
  • Rules that attach to services and try to auto-figure out dynamic ports never work well in windows. If you're sure you've set the passive port option in the firewall and restarted the ftp service or entire server and it's still not working, the only suggestion I have is to set up active mode or statically open the passive port range you need using a custom firewall exception. If you have access to the firewall you have access to modify the FTP service configuration on that server... – Brock Hensley Jan 29 '14 at 21:44
  • @BrockHensley-FKAdirt I don't think I've explained myself properly. I have control on my WS2012 which is the client that connects to the remote device through ftp and tries to retrieve a file from there. I don't have access to the ftp server. But only this WS2012 has issues downloading the file. – slybloty Jan 29 '14 at 21:48
  • Let's start at the beginning. Please post the PowerShell script. Are you able to re-use the very same script on the other boxes? Can you telnet in from the problem box on the FTP port and run simple commands? Have you tried packet sniffing the transaction to see what's happening when the connection terminates? Please post log output from the script, and also confirm whether or not other FTP clients ie FileZilla are able to retrieve the file successfully. Cheers! Rex – Rex Hardin Jan 31 '14 at 05:22
  • @RexHardin Edited my question. – slybloty Jan 31 '14 at 20:12

1 Answers1

0

I'm not sure what exactly is the process behind the WebClient::DownloadFile method, but it seems to me that it interrupts the ftp connection right before the download transfer completes causing the operation to fail.

By using the asynchronous method I managed to successfully download the file.
Here's my updated function using the WebClient::DownloadFileTaskAsync method. I also implemented a status check.

function getFTPfile([String]$fileName)
{
    $ftpUser = "user"
    $ftpPassword = "password"
    $ftpServer = "ftpServer"

    $webclient = New-Object System.Net.WebClient 
    $webclient.Credentials = New-Object System.Net.NetworkCredential($ftpUser, $ftpPassword)

    $uri = New-Object System.Uri("$ftpServer/files")

    $job = $webclient.DownloadFileTaskAsync($uri, $fileName) 

    while(!$job.IsCompleted)
    { 
        Write-Host "Downloading file..."
        sleep 10
    }
    if($job.Status -ne "RanToCompletion")
        { Write-Host "Failed to download file." }
    else
        { Write-Host "Download successful." }
}
slybloty
  • 443
  • 2
  • 9
  • 30