如何将示例FTP备份批处理代码转换为PowerShell脚本?
PowerShell实现FTP批量备份文件方案
你原批处理的核心逻辑是:
- 先ping目标FTP服务器确认网络连通
- 生成临时FTP命令脚本,以匿名方式登录、开启二进制传输、关闭交互确认、下载根目录所有文件
- 调用系统ftp.exe执行脚本后删除临时文件
以下两种实现方式都可以完全等价替代原批处理功能:
方案1:调用系统自带ftp.exe,无需临时文件
这个方案和原批处理依赖的组件完全一致,迁移成本最低,不需要额外改逻辑,直接用管道把FTP命令传给ftp.exe即可,省去生成、删除临时文件的步骤:
# 按需修改配置参数 $ftpIP = "填写你的FTP服务器IP地址" $localSaveDir = "填写文件下载后保存的本地路径,例如D:\ftp_backup" # 等价原批处理的ping连通性检测 Test-Connection $ftpIP -Count 2 # 切换到本地保存目录 Set-Location $localSaveDir # 直接传入FTP命令执行,匿名登录场景保留两个空行即可 # 如果是账号密码登录,把两个空行替换成 你的用户名、你的密码 两行内容 @" open $ftpIP bin prompt mget *.* bye "@ | ftp -n -s:-
方案2:.NET原生方法实现,不依赖ftp.exe
这个方案不需要调用外部的ftp.exe程序,用PowerShell内置的.NET类实现,可控性更高,方便后续加错误处理、日志记录、重名文件判断等逻辑:
# 按需修改配置参数 $ftpIP = "填写你的FTP服务器IP地址" $localSaveDir = "填写文件下载后保存的本地路径,例如D:\ftp_backup" $ftpUser = "anonymous" # 匿名登录默认用户名,账号密码登录替换为实际用户名 $ftpPwd = "anonymous@" # 匿名登录默认密码,账号密码登录替换为实际密码 # 连通性检测 Test-Connection $ftpIP -Count 2 -ErrorAction Stop # 本地保存目录不存在则自动创建 if (-not (Test-Path $localSaveDir)) { New-Item -ItemType Directory -Path $localSaveDir | Out-Null } Set-Location $localSaveDir # 获取FTP根目录文件列表 $listRequest = [System.Net.FtpWebRequest]::Create("ftp://$ftpIP/") $listRequest.Credentials = New-Object System.Net.NetworkCredential($ftpUser, $ftpPwd) $listRequest.Method = [System.Net.WebRequestMethods+Ftp]::ListDirectory $listRequest.UseBinary = $true $listResponse = $listRequest.GetResponse() $listReader = New-Object System.IO.StreamReader($listResponse.GetResponseStream()) $allFiles = $listReader.ReadToEnd() -split "`r`n" | Where-Object { $_ -ne '' } $listReader.Close() $listResponse.Close() # 逐个下载文件,等价原批处理mget *.*逻辑 foreach ($file in $allFiles) { $dlRequest = [System.Net.FtpWebRequest]::Create("ftp://$ftpIP/$file") $dlRequest.Credentials = New-Object System.Net.NetworkCredential($ftpUser, $ftpPwd) $dlRequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile $dlRequest.UseBinary = $true $dlResponse = $dlRequest.GetResponse() $sourceStream = $dlResponse.GetResponseStream() $targetStream = [System.IO.File]::Create((Join-Path $localSaveDir $file)) $sourceStream.CopyTo($targetStream) # 释放资源 $targetStream.Close() $sourceStream.Close() $dlResponse.Close() Write-Host "文件下载完成: $file" }
注意事项
- 原批处理的
prompt命令作用是关闭批量下载时的逐文件确认提示,以上两种方案都默认实现了该效果,不会弹出交互确认卡住脚本 - 两种方案都默认开启二进制传输模式,和原批处理
bin命令效果一致,不会出现文件损坏问题 - 如果FTP服务用的是主动/被动模式特殊配置,方案2可以通过设置
$ftpRequest.UsePassive = $true/$false快速调整
内容的提问来源于stack exchange,提问作者YellowRobot
相关产品推荐
相关产品推荐

