我是PowerShell和FTP脚本的新手,所以要善待。我搜索了很多,无法找到一种方法,只需使用脚本从FTP服务器下载文件。我从cmd.exe
开始尝试ftp
子命令,但没有成功。所以我切换到PowerShell(v4.0)。我已经看过各种下载FTP文件的例子,但没有一个对我有用。这是我最近的尝试:
$Username = "username"
$Password = "password"
$LocalFile = "C:\Users\myuser\MyFile.xlsx"
$RemoteFile = "ftp://ftp.example.com/MyFile.xlsx"
$req = [System.Net.FtpWebRequest]::Create($RemoteFile)
$req.Credentials = New-Object System.Net.NetworkCredential($Username, $Password)
$req.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
$req.UseBinary = $true
$req.UsePassive = $true
$req.KeepAlive = $false
# Everything works to this point.
try {
# This throws exception.
$resp = [System.Net.FtpWebResponse]$req.GetResponse()
}
catch {
$msg = $_.Exception
Write-Host "Exception: $msg" -ForegroundColor Red
}
# More code will go here later to write the data to the local file.
# Clean up.
if ($resp -ne $null) {
$resp.Close()
$resp = $null
}
我得到的错误是:
System.Management.Automation.MethodInvocationException: Exception calling "GetResponse" with "0" argument(s): "The remote server returned an error: 227 Entering Passive Mode (172,16,13,205,5,250).
." ---> System.Net.WebException: The remote server returned an error: 227 Entering Passive Mode (172,16,13,205,5,250).
. ---> System.Net.Sockets.SocketException: A socket operation was attempted to an unreachable network 172.16.13.205:1530
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
at System.Net.FtpControlStream.QueueOrCreateDataConection(PipelineEntry entry, ResponseDescription response, Boolean timeout, Stream& stream, Boolean& isSocketReady)
at System.Net.FtpControlStream.PipelineCallback(PipelineEntry entry, ResponseDescription response, Boolean timeout, Stream& stream)
at System.Net.CommandStream.PostReadCommandProcessing(Stream& stream)
at System.Net.CommandStream.ContinueCommandPipeline()
at System.Net.FtpWebRequest.TimedSubmitRequestHelper(Boolean async)
at System.Net.FtpWebRequest.SubmitRequest(Boolean async)
--- End of inner exception stack trace ---
at System.Net.FtpWebRequest.SyncRequestCallback(Object obj)
at System.Net.CommandStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.Net.ConnectionPool.Destroy(PooledStream pooledStream)
at System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse)
at System.Net.FtpWebRequest.FinishRequestStage(RequestStage stage)
at System.Net.FtpWebRequest.GetResponse()
at CallSite.Target(Closure , CallSite , Object )
--- End of inner exception stack trace ---
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
我知道该文件存在且可用,因为当我将ftp://username:password@ftp.example.com/MyFile.xlsx
粘贴到浏览器中时,系统会提示我下载该文件,一切正常。
FTP服务器在我们的网络中,但我想要一个适用于我们网络外的FTP服务器的解决方案。
我做错了什么?
答案 0 :(得分:1)
问题是配置错误的服务器。
尝试对无法访问的网络172.16.13.205:1530进行套接字操作
服务器在对227
命令的PASV
响应中返回其本地网络IP地址。
您的客户端(FtpWebRequest
)自然无法连接到该地址并失败。
必须正确配置服务器,以便在227
响应中了解并显示其外部IP地址。
有些FTP客户端可以通过以下方式克服这种错误配置:
227
响应中不可路由的IP地址,并使用控制连接地址进行数据传输或EPSV
命令而不是PASV
(服务器仅使用端口号响应,让客户端隐式使用控制连接地址) FtpWebRequest
也无法做到。
Windows命令行FTP客户端ftp.exe
甚至不支持被动模式。它仅支持主动模式,由于无处不在的NAT和防火墙,它现在几乎无法工作。
有关此类问题的详细信息,请参阅FTP connection modes (active and passive)上的我的文章。
如果您无法修复服务器,则需要使用其他FTP客户端。
例如WinSCP FTP/SFTP client使用scripting interface,您可以使用以下批处理文件(.bat):
winscp.com /log=winscp.log /command ^
"open ftp://username:password@ftp.example.com" ^
"get MyFile.xlsx C:\Users\myuser\MyFile.xlsx" ^
"exit"
WinSCP忽略227
响应中不可路由的IP地址,并使用控制连接地址进行数据传输。
(我是WinSCP的作者)