使用PowerShell PSFTP模块下载FTP文件夹时触发550错误崩溃
问题分析与解决脚本
问题根源:Get-FTPChildItem -Recurse会同时返回远程服务器上的文件和文件夹对象,但Get-FTPItem默认会尝试下载所有传入的对象——包括文件夹。FTP服务器无法将文件夹当作文件返回,因此触发550错误,同时本地会生成一个和文件夹同名的空文件。
修正后的脚本:
$User = "xxxxx" $Password = ConvertTo-SecureString "xxxx" -AsPlainText -Force $Credentials = New-Object System.Management.Automation.PSCredential ($User, $Password) $ftp_server = "ftp://backup.xxxxx.eu" $ftp_path = "backup_old/xxx/xx_Config_Backup" $local_path = "D:\Backup\backup_old\xxx" # 建立FTP连接并保存会话 Set-FTPConnection -Credentials $Credentials -Server $ftp_server -EnableSsl -ignoreCert -UsePassive -SessionVariable ftpSession # 获取远程路径下所有递归项 $remoteItems = Get-FTPChildItem -Path $ftp_path -Recurse -Session $ftpSession # 先创建本地对应的文件夹结构 foreach ($folder in $remoteItems | Where-Object { $_.Type -eq "Directory" }) { $localFolder = $folder.FullName.Replace("$ftp_server/$ftp_path", $local_path) if (-not (Test-Path $localFolder)) { New-Item -ItemType Directory -Path $localFolder | Out-Null Write-Verbose "创建本地文件夹: $localFolder" } } # 仅下载文件类型的远程项 $remoteItems | Where-Object { $_.Type -eq "File" } | ForEach-Object { Get-FTPItem -Path $_.FullName -LocalPath $local_path -Overwrite -Verbose -Session $ftpSession }
关键改动说明:
- 显式过滤出
Directory类型项,提前在本地创建对应文件夹结构,避免下载时路径缺失 - 只对
File类型项执行下载操作,彻底规避尝试下载文件夹引发的550错误 - 使用
SessionVariable显式绑定FTP会话,减少连接异常风险
之前尝试的-RecreateFolders参数失效原因:该参数仅当Get-FTPItem的-Path直接指向远程文件夹时才会触发递归建文件夹逻辑,而管道传入单个对象时无法触发该逻辑。
内容的提问来源于stack exchange,提问作者NemoDima
相关产品推荐
相关产品推荐

