Secure FTP using Windows batch script
Asked Answered
B

4

20

I currently have batch scripts on different servers that transfer a csv file to an FTP server at a different location. My script looks similar to this:

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

If I wanted to require a secure transmission, is how would my script be updated?

Thanks.

Blandish answered 22/4, 2013 at 14:53 Comment(0)
N
40

First, make sure you understand, if you need to use Secure FTP (=FTPS, as per your text) or SFTP (as per tag you have used).

Neither is supported by Windows command-line ftp.exe. As you have suggested, you can use WinSCP. It supports both FTPS and SFTP.

Using WinSCP, your batch file would look like (for 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

And the batch file:

winscp.com /log=ftpcmd.log /script=ftpcmd.dat /parameter %1 %date%

Though using all capabilities of WinSCP (particularly providing commands directly on command-line and the %TIMESTAMP% syntax), the batch file simplifies to:

winscp.com /log=ftpcmd.log /command ^
    "open sftp://ftp_user:[email protected] -hostkey=""...""" ^
    "put c:\directory\%1-export-%%TIMESTAMP#yyyymmdd%%.csv" ^
    "exit"

For the purpose of -hostkey switch, see verifying the host key in script.

Easier than assembling the script/batch file manually is to setup and test the connection settings in WinSCP GUI and then have it generate the script or batch file for you:

Generate batch file

All you need to tweak is the source file name (use the %TIMESTAMP% syntax as shown previously) and the path to the log file.


For FTPS, replace the sftp:// in the open command with ftpes:// (explicit TLS/SSL) or ftps:// (implicit TLS/SSL). And remove the -hostkey switch.

winscp.com /log=ftpcmd.log /command ^
    "open ftps://ftp_user:[email protected] -explicit" ^
    "put c:\directory\%1-export-%%TIMESTAMP#yyyymmdd%%.csv" ^
    "exit"

You may need to add the -certificate switch, if your server's certificate is not issued by a trusted authority.

Again, as with the SFTP, easier is to setup and test the connection settings in WinSCP GUI and then have it generate the script or batch file for you.


See a complete conversion guide from ftp.exe to WinSCP.

You should also read the Guide to automating file transfers to FTP server or SFTP server.


Note to using %TIMESTAMP#yyyymmdd% instead of %date%: A format of %date% variable value is locale-specific. So make sure you test the script on the same locale you are actually going to use the script on. For example on my Czech locale the %date% resolves to čt 06. 11. 2014, what might be problematic when used as a part of a file name.

For this reason WinSCP supports (locale-neutral) timestamp formatting natively. For example %TIMESTAMP#yyyymmdd% resolves to 20170515 on any locale.

(I'm the author of WinSCP)

Nik answered 22/4, 2013 at 16:16 Comment(0)
K
2

The built in FTP command doesn't have a facility for security. Use cUrl instead. It's scriptable, far more robust and has FTP security.

Kevin answered 22/4, 2013 at 15:9 Comment(1)
Would WinSCP be a sufficient substitute, as well?Blandish
L
0

Just a little code snippet in PowerShell to ease the call when WinSCP is not registered in the path but winscp.exe is available (default value points to the Install-Module WinSCP directory):

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
}

Usage:

Send-WinScpCommand "get `"`"/ftpdir/distantfile.txt`"`" `"`"c:\temp\localfile.txt`"`""
Send-WinScpCommand "put `"`"c:\temp\localfile.txt`"`" `"`"/ftpdir/distantfile.txt`"`""

Original post answer using this function and sftp (my use case): Send-WinScpCommand "put c:\directory\%1-export-%%TIMESTAMP#yyyymmdd%%.csv"


As requested by @Stephan, a batch equivalent:

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

Usage:

Send-WinScpCommand "get ""/ftpdir/distantfile.txt"" ""c:\temp\localfile.txt"""
Send-WinScpCommand "put ""c:\temp\localfile.txt"" ""/ftpdir/distantfile.txt"""
Letty answered 26/10, 2023 at 7:55 Comment(1)
It's not tagged cmd, it's tagged batch-file. Though you're right (I've added the PowerShell mention in my answer), I'm editing to add a pure batch version.Letty
E
-2
    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 ; 
Engineer answered 14/1, 2016 at 16:40 Comment(1)
Hi, Try to provide some context to your code, such as what it is doing and what software you are suggesting the OP uses.Apfel

© 2022 - 2024 — McMap. All rights reserved.