Blog Pro de Jean-Baptiste HEREN - Tag - windows Notes d'un consultant Freelance en Informatique 2015-11-03T21:34:19+01:00 JB HEREN urn:md5:e39389b5ec134d99645112fce3d957df Dotclear automatic ftp tranfers on windows OS client using the command line urn:md5:095889337a165f98a9556881fb9ade07 2011-06-27T20:55:00+02:00 2011-12-02T11:07:36+01:00 Jean-Baptiste Heren Veille techno batchChilkat FTPcommand lineftpvbswindowswinSCP <p>Here is a little trick we used on a recent project.</p> <p>We needed to automatize :</p> <ol> <li>(local &lt;-- remote) download files from an ftp server specified folder</li> <li>(remote --&gt; remote/subfolder) move the downloaded files on the source server so that we do not download them again on next run.</li> </ol> <h2>Needed Tools</h2> <h3>ftp Client</h3> <p>I decided to use the WINSCP Command wich is part of the WinSCP client package. This tool works as a command line client and is scriptable. It is possible also to use the ftp command directly but it does not work properly whan you want to send ftp commands on the fly.</p> <h3>Scripting language</h3> <p>The following example uses Visual basic scripting.</p> <h2>The Script</h2> <p>After creating a new conenction in WINSCP client, we can use it on command line by running the following script :</p> <pre>[script] cscript move.vbs D:\FTPROOT\IN\LOCAL IN/FOO OUT/FOO DONE MYACCOUNT </pre> <pre>[VB] 'contact@jbheren.com 'this code builds a move command from the file list in specified directory &amp; runs it in WSCP 'usage: cscript move.vbs source_local_full_path remote_initial_directory remote_final_subdirectory Dim fso, folder, files, localPath, localFolder, remoteFolder, moveSubFolder, connexionName, oShell, oExec, winscp ' Check parameters If( WScript.Arguments.Count &lt; 4 ) Then WScript.Echo( vbCrLf &amp;&quot; usage: cscript move.vbs source_local_full_path local_ftp_path remote_ftp_path move_to_path connection_name&quot;) WScript.Echo( vbCrLf &amp;&quot; example: &quot; &amp;vbCrLf &amp;&quot; cscript move.vbs D:\FTPROOT\IN\LOCAL IN/FOO OUT/FOO DONE MYACCOUNT&quot;) WScript.Echo( vbCrLf &amp;&quot; &quot; &amp;vbCrLf &amp;&quot; 1 - Gets files from OUT/FOO -&gt; IN/FOO using the recorded MYACCOUNT WINSCP connection&quot;) WScript.Echo( vbCrLf &amp;&quot; &quot; &amp;vbCrLf &amp;&quot; 2 - moves files names found in D:\FTPROOT\IN\LOCAL, on remote from OUT/FOO -&gt; OUT/FOO/DONE&quot;) WScript.Quit End If ' ------------------------------------------- '| MAIN | ' ------------------------------------------- ' Set Winscp com path winscp = &quot;C:\Program Files\WinSCP\winscp.com&quot; commandTxt = &quot;&quot; ' Empty current command Set fso = CreateObject(&quot;Scripting.FileSystemObject&quot;) ' retreive parameters localPath = Wscript.Arguments.Item(0) localFolder = Wscript.Arguments.Item(1) remoteFolder = Wscript.Arguments.Item(2) moveSubFolder = Wscript.Arguments.Item(3) connexionName = Wscript.Arguments.Item(4) If localPath = &quot;&quot; Then Wscript.Echo &quot;No Folder parameter was passed&quot; Wscript.Quit Else Wscript.Echo &quot;Runing For &quot; &amp; localPath &amp; &quot; , &quot; &amp; localFolder &amp; &quot; , &quot; &amp; remoteFolder &amp; &quot; , &quot; &amp; moveSubFolder &amp; &quot; on connection &quot; &amp; connexionName End If ' Open ftp command Set oShell = CreateObject(&quot;wscript.shell&quot;) 'Set oExec = oShell.Exec(&quot;ftpgenerix.bat&quot;) Set oExec = oShell.Exec(winscp) ' Build the list of Commands to be ran by FTP command. ' login oExec.StdIn.Writeline &quot;option batch abort&quot; WScript.Sleep 100 oExec.StdIn.Writeline &quot;open &quot; &amp; connexionName WScript.Sleep 100 ' 00 - Set Current Folders oExec.StdIn.Writeline(&quot;cd &quot; &amp; remoteFolder) WScript.Sleep 100 oExec.StdIn.Writeline(&quot;lcd &quot; &amp; localFolder) WScript.Sleep 100 ' 01 - DOWNLOAD oExec.StdIn.Writeline(&quot;get *.*&quot;) Wscript.Echo &quot;Getting All files from &quot; &amp; remoteFolder &amp; &quot; to &quot; &amp; localFolder WScript.Sleep 1000 ' 02 - RENAME (Move files) ' list current local files Set folder = fso.GetFolder(localPath) Set files = folder.Files ' move each one on distant server from current folder to dFolder For each file In files commandTxt = &quot;rename &quot; &amp; file.Name &amp; &quot; &quot; &amp; moveSubFolder &amp; &quot;/&quot; &amp; file.Name oExec.StdIn.Writeline(commandTxt) Wscript.Echo commandTxt WScript.Sleep 100 Next ' Finish session oExec.StdIn.Writeline &quot;exit&quot; Wscript.Echo &quot;exit&quot; WScript.Sleep 100 WScript.Echo oExec.Status </pre> <p>Hope it will help !</p> <h2>Alternatives to WinSCP</h2> <p>I just reworked on this task (same actions) and wrote a vbs script doing the same task, but replaced winscp with an ActiveX control object : <a href="http://www.chilkatsoft.com/ftp-activex.asp" hreflang="en" title="http://www.chilkatsoft.com/ftp-activex.asp">Chilkat FTP ActiveX</a></p> <p>Here is the code</p> <pre>[VB] 'moveocx.vbs 'contact@jbheren.com 'this code builds a move command from the file list in specified directory &amp; runs it FTP Session 'uses ActiveX component from http://www.chilkatsoft.com/ftp-activex.asp 'usage: cscript move.vbs source_local_full_path remote_initial_directory remote_final_subdirectory Dim fso, ftpo, folder, files, localPath, localFolder, remoteFolder, moveSubFolder, host, user, pass, ok ' Check parameters If( WScript.Arguments.Count &lt; 4 ) Then WScript.Echo( vbCrLf &amp;&quot; usage: cscript moveocx.vbs source_local_full_path local_ftp_path remote_ftp_path move_to_path user pass host&quot;) WScript.Echo( vbCrLf &amp;&quot; example: &quot; &amp;vbCrLf &amp;&quot; cscript moveocx.vbs D:\FTPROOT\IN\LOCAL IN/FOO OUT/FOO DONE MYLOGIN MYPASS MYHOST&quot;) WScript.Echo( vbCrLf &amp;&quot; &quot; &amp;vbCrLf &amp;&quot; 1 - Gets files from OUT/FOO -&gt; IN/FOO using the recorded MYLOGIN connection&quot;) WScript.Echo( vbCrLf &amp;&quot; &quot; &amp;vbCrLf &amp;&quot; 2 - moves files names found in D:\FTPROOT\IN\LOCAL, on remote from OUT/FOO -&gt; OUT/FOO/DONE&quot;) WScript.Quit End If ' ------------------------------------------- '| MAIN | ' ------------------------------------------- ' Set Basic path commandTxt = &quot;&quot; ' Empty current command ' instanciate chilkat FTP Component Set fso = CreateObject(&quot;Scripting.FileSystemObject&quot;) ' retreive parameters localPath = Wscript.Arguments.Item(0) localFolder = Wscript.Arguments.Item(1) remoteFolder = Wscript.Arguments.Item(2) moveSubFolder = Wscript.Arguments.Item(3) user = Wscript.Arguments.Item(4) pass = Wscript.Arguments.Item(5) host = Wscript.Arguments.Item(6) If localPath = &quot;&quot; Then Wscript.Echo &quot;No Folder parameter was passed&quot; Wscript.Quit Else Wscript.Echo &quot;Runing For &quot; &amp; localPath &amp; &quot; , &quot; &amp; localFolder &amp; &quot; , &quot; &amp; remoteFolder &amp; &quot; , &quot; &amp; moveSubFolder &amp; &quot; on connection &quot; &amp; host End If ' JBH - Open ftp command 'Set ftpo = CreateObject(&quot;InetCtls.Inet.1&quot;) 'Msinet.ocx Set ftpo = CreateObject(&quot;ChilkatFTP.ChilkatFTP.1&quot;) ftpo.Username = user ftpo.Password = password ftpo.Hostname = host ftpo.Password = pass ftpo.Passive = true Wscript.Echo &quot;Connecting...&quot; if (ftpo.Connect()) &lt;&gt; 1 Then Wscript.Echo &quot;Failed Connection : &quot; &amp; ftpo.LastErrorText ftpo.Disconnect() Wscript.Quit else ' 00 - Set Remote Folder Wscript.Echo &quot;00 - Set remote folder to &quot; &amp; remoteFolder If (ftpo.ChangeRemoteDir( remoteFolder )) &lt;&gt; 1 Then Wscript.Echo &quot;Failed setting remote dir : &quot; &amp; ftpo.LastErrorText ftpo.Disconnect() Wscript.Quit End If ' 01 - DOWNLOAD Wscript.Echo &quot;01 - Getting All files from &quot; &amp; remoteFolder &amp; &quot; to &quot; &amp; localFolder ok = ftpo.MGetFiles(&quot;*.*&quot;, localPath) If (ok) &lt;&gt; 1 Then Wscript.Echo &quot; Download returned &quot;&amp; ok &amp;&quot; : &quot; &amp; ftpo.LastErrorText 'ftpo.Disconnect() 'Wscript.Quit End If ' 02 - RENAME (Move files) ' list current local files Set folder = fso.GetFolder(localPath) Set Files = folder.Files ' move each one on distant server from current folder to dFolder Wscript.Echo &quot; Move files present in &quot; &amp; localPath &amp; &quot; to remote folder &quot; &amp; remoteFolder &amp; &quot;/&quot; &amp; moveSubFolder For each file In Files Wscript.Echo &quot; Rename &quot; &amp; file.Name &amp; &quot; to &quot; &amp; moveSubFolder &amp; &quot;/&quot; &amp; file.Name ok = ftpo.RenameRemoteFile(file.Name, moveSubFolder &amp; &quot;/&quot; &amp; file.Name) If (ok) &lt;&gt; 1 Then Wscript.Echo &quot; Rename Returned unexpected value (&quot; &amp; ok &amp; &quot;) &quot; &amp; ftpo.LastErrorText 'ftpo.Disconnect() 'Wscript.Quit End If Next ' Finish session WScript.Echo &quot;Closing&quot; ftpo.Disconnect() WScript.Echo &quot;Done!&quot; End if </pre>