我目前在不同的服务器上有批处理脚本,用于将 csv 文件传输到不同位置的 FTP 服务器。我的脚本看起来与此类似:
echo user ftp_user> ftpcmd.dat
echo password>> ftpcmd.dat
echo put c:\directory\%1-export-%date%.csv>> ftpcmd.dat
echo quit>> ftpcmd.dat
ftp -n -s:ftpcmd.dat ftp.MyFTPSite.com
del ftpcmd.dat
如果我想要求安全传输,我的脚本将如何更新?
谢谢。
首先,请确保您了解,是否需要使用 Secure FTP(=FTPS,根据您的文本)或 SFTP(根据您使用的标签)。
Windows 命令行
ftp.exe
均不支持。正如您所建议的,您可以使用WinSCP。它同时支持 FTPS 和 SFTP。
使用 WinSCP,您的批处理文件将如下所示(对于 SFTP):
echo open sftp://ftp_user:[email protected] -hostkey="..." >> ftpcmd.dat
echo put c:\directory\%1-export-%date%.csv >> ftpcmd.dat
echo exit >> ftpcmd.dat
winscp.com /script=ftpcmd.dat
del ftpcmd.dat
批处理文件:
winscp.com /log=ftpcmd.log /script=ftpcmd.dat /parameter %1 %date%
虽然使用了 WinSCP 的所有功能(特别是直接在命令行上提供命令和
%TIMESTAMP%
语法),批处理文件简化为:
winscp.com /log=ftpcmd.log /command ^
"open sftp://ftp_user:[email protected] -hostkey=""...""" ^
"put c:\directory\%1-export-%%TIMESTAMP#yyyymmdd%%.csv" ^
"exit"
关于
-hostkey
切换的目的,请参阅在脚本中验证主机密钥。
比手动组装脚本/批处理文件更简单的是在 WinSCP GUI 中设置和测试连接设置,然后让它为您生成脚本或批处理文件:
您需要调整的只是源文件名(使用如前所示的
%TIMESTAMP%
语法)和日志文件的路径。
对于 FTPS,请将
sftp://
命令中的
open
替换为 ftpes://
(显式 TLS/SSL)或 ftps://
(隐式 TLS/SSL)。并取下 -hostkey
开关。
winscp.com /log=ftpcmd.log /command ^
"open ftps://ftp_user:[email protected] -explicit" ^
"put c:\directory\%1-export-%%TIMESTAMP#yyyymmdd%%.csv" ^
"exit"
如果您的服务器证书
不是由受信任的机构颁发,您可能需要添加
-certificate
开关。
同样,与 SFTP 一样,更简单的是在 WinSCP GUI 中设置和测试连接设置,然后让它为您生成脚本或批处理文件。
查看完整的 从
ftp.exe
到 WinSCP 的转换指南。
您还应该阅读自动将文件传输到 FTP 服务器或 SFTP 服务器的指南。
注意使用
%TIMESTAMP#yyyymmdd%
而不是 %date%
: %date%
变量值的格式是特定于区域设置的。因此,请确保在实际要使用脚本的同一区域设置上测试脚本。例如,在我的捷克语言环境中,%date%
解析为 čt 06. 11. 2014
,用作文件名的一部分时可能会出现问题。
因此,WinSCP 原生支持 (区域设置中性)时间戳格式。例如,在任何语言环境中
%TIMESTAMP#yyyymmdd%
都会解析为 20170515
。
(我是WinSCP的作者)
内置的 FTP 命令没有安全设施。请改用 cUrl。它是可编写脚本的,更加强大并且具有 FTP 安全性。
只需在 PowerShell 中添加一小段代码,即可在 WinSCP 未在路径中注册但 WinSCP.exe 可用时简化调用(默认值指向
Install-Module WinSCP
目录):
function Send-WinScpCommand ([string]$command, [string]$connection = "sftp://username:[email protected]/", [string]$hostkey = "*", [string]$WinSCPDirectory = "$((Get-Module winscp).Path)\..\bin\") {
Write-Host $command
pushd; cd "$WinSCPDirectory"
.\winscp.exe -loglevel=1 /log="C:\Temp\WinSCP.log" <#-console#> -command "open $connection -hostkey=$hostkey" "$command" "close" "exit" | Out-Null # Sync wait
popd
}
用途:
Send-WinScpCommand "get `"`"/ftpdir/distantfile.txt`"`" `"`"c:\temp\localfile.txt`"`""
Send-WinScpCommand "put `"`"c:\temp\localfile.txt`"`" `"`"/ftpdir/distantfile.txt`"`""
使用此功能和 sftp 的原始帖子答案(我的用例):
Send-WinScpCommand "put c:\directory\%1-export-%%TIMESTAMP#yyyymmdd%%.csv"
按照@Stephan的要求,批量等效:
echo "%programfiles%\WindowsPowerShell\Modules\WinSCP\6.1.2.0\bin\WinSCP.exe" -loglevel=1 /log="C:\Temp\WinSCP.log" -command "open sftp://username:[email protected] -hostkey=*" %1 "close" "exit">Send-WinScpCommand.bat
用途:
Send-WinScpCommand "get ""/ftpdir/distantfile.txt"" ""c:\temp\localfile.txt"""
Send-WinScpCommand "put ""c:\temp\localfile.txt"" ""/ftpdir/distantfile.txt"""
ftps -a -z -e:on -pfxfile:"S-PID.p12" -pfxpwfile:"S-PID.p12.pwd" -user:<S-PID number> -s:script <RemoteServerName> 2121
S-PID.p12 => certificate file name ;
S-PID.p12.pwd => certificate password file name ;
RemoteServerName => abcd123 ;
2121 => port number ;
ftps => command is part of ftps client software ;