Powershell FTP 脚本错误:远程服务器返回错误:227 进入被动模式

Powershell FTP 脚本错误:远程服务器返回错误:227 进入被动模式

我遇到了 Powershell FTP 脚本问题。我为此绞尽了脑汁。

我最近为我的软件项目设置了一个“自动构建服务器”。所有软件项目都构建并打包成一个 zip 文件。理论上,这个 zip 文件将通过 FTP 下载到几个不同的服务器。我正在尝试构建一个 powershell 脚本,它将下载我的包并将其解压到所需的目录中。

我遇到的问题是通过 FTP 下载文件。我可以通过 DOS 命令窗口手动登录 FTP 来访问源文件。我可以正常下载文件,所以我知道这不是防火墙问题。至少我不这么认为。

每当 powershell 开始下载源 .zip 文件时,它都会挂起。我可以看到文件出现在硬盘上,但当脚本失败时它就会消失。它永远不会从 FTP 服务器获取任何字节。然后我收到此错误:

Powershell FTP 脚本错误:远程服务器返回错误:227 进入被动模式 (10,255,130,77,231,5) Blockquote

这是我的脚本:

#create destination directory (this is where the build files will be dropped)
[IO.Directory]::CreateDirectory("C:\tempftp")

"Creating staging folder..."
#create staging folder for deployment package bundle unzip
[IO.Directory]::CreateDirectory("C:\FINALDEPLOYMENTFOLDER")

#create destination and source paths for FTP copy command
$File = "C:\tempftp\MyPackageT.zip"
$ftp = "ftp://AdminiUser:[email protected]/MyPackage.zip"

"ftp url: $ftp"

$webclient = New-Object System.Net.WebClient
$uri = New-Object System.Uri($ftp)

"Downloading $File..."

#perform the actual data transfer via FTP
$webclient.DownloadFile($ftp, $File)

"Unzip build package..."
#unzip the file that was transferred via FTP
$shell_app=new-object -com shell.application 
$zip_file = $shell_app.namespace("C:\tempftp\MyPackage.zip")         #source
$destination = $shell_app.namespace("C:\FINALDEPLOYMENTFOLDER")       #final destination

#unzip to destination folder
foreach ($item in $zip_file.Items())
{
$destination.CopyHere($item, 16)
}

我可以在构建服务器上本地运行此脚本,并且运行良好。我知道此脚本可以正常工作。我的问题是,为什么此脚本在我的非构建服务器上会出错?为什么被动模式对于这种情况来说是个问题,我该如何修复它?我尝试过 FTP IPv4 地址规则、FTP 防火墙支持更改等。但没有成功。

值得注意的是,我在 IIS7 的 FTP 防火墙支持部分看到了一条警告消息。它指出:

当您使用 FTP over SSL (FTPS) 或防火墙不过滤数据包时,要接受被动连接,请配置防火墙的外部 IPv4 地址。

^ 我不确定这到底是什么意思,但我会试一试。有人知道为什么被动模式对我来说如此麻烦吗?我不应该使用 WebClient 吗?我真的想避免必须下载另一个程序/补丁才能使其工作。我宁愿在本机 Powershell 中工作...所以不,我不能使用 FTP 客户端库!!

**** 编辑:我可以通过打开防火墙上的“所有端口”来解决这个问题,但这似乎有点吓人。有没有建议可以追踪需要哪些端口,以便消除此被动模式错误?我已经有一条规则允许我认为 FTP 正在使用的几个特定端口......但我如何才能看到我需要启用哪些端口?**

答案1

当您从命令提示符连接到 FTP 站点时,您使用的是主动 FTP(只有一个可用),这对防火墙而言更容易预测。当您使用 连接时System.Net.WebClient,您使用的是 PASV 连接,它会从预定义的可用范围中随机获取一个端口。这些请求会被防火墙阻止。如果您必须坚持使用 PASV,您还可以尝试打开防火墙上的端口范围。否则,您需要弄清楚如何指定使用主动 FTP 连接。这不能使用 来完成System.Net.WebClient

看一下System.Net.FtpWebRequest,它可能会做你想做的事。我看到有一个UsePassive属性。

相关内容