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
.
Best Answer
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.