Differences

This shows you the differences between the selected revisions of the page.

scripting 2008-04-27 scripting 2024-10-03 (current)
Line 1: Line 1:
-====== Scripting/Automation ====== +====== Scripting and Task Automation ====== 
-In addition to [[interfaces|graphical interface]], WinSCP offers scripting/console interface with many [[script_commands|commands]]. The commands can be typed in interactively, or read from script file or another source.+//This article contains detailed description of scripting/automation functionality. You may want to see [[guide_automation|simplified guide]] to the functionality instead.//
-===== Using Scripting ===== +In addition to [[interfaces|graphical interface]], WinSCP offers scripting/console interface with many [[#commands|commands]]. The commands can be typed in interactively, or read from script file or another source.
-See [[commandline|command-line parameters]] to learn how to enter the console/scripting mode.+
-For automation, commands can be read from a script file specified by ''/script'' switch, from standard input or passed from the command-line using the ''/command'' switch.+Using scripting interface directly is recommended for simple tasks not requiring any control structures. For complex tasks, using [[library|WinSCP .NET assembly]] is preferred.
-By default an interactive mode is used (the user is prompted in the same way as in GUI mode). To switch to a batch mode (all prompts are automatically answered negatively) use the command ''[[script_commands#option|option batch on]]''. For the batch mode it is recommended to turn off confirmations using ''[[script_commands#option|option confirm off]]'' to allow overwrites (otherwise the overwrite confirmation prompt would be answered negatively, making overwrites impossible). +~~AD~~
-Multiple sessions can be opened simultaneously. Use the ''[[script_commands#session|session]]'' command to switch between them.+&screenshotpict(scripting)
-Note that the first connection to an SSH server requires [[scripting#hostkey|verification of the host key]].+===== [[using_scripting]] Using Scripting ===== 
 +Enter the console/scripting mode by using ''[[executables|winscp.com]]''; or ''/console'' command-line parameter with ''[[executables|winscp.exe]]''. For details see [[commandline#scripting|console/scripting command-line parameters]].
-WinSCP returns exit code 1, when any command is interrupted due to an error or any prompt is answered //Abort// (even automatically in batch mode). Otherwise it returns the exit code 0.+For automation, commands can be read from a script file specified by ''/script'' switch, passed from the command-line using the ''/command'' switch, or read from standard input of ''winscp.com''.
-===== Commands ====+The script file must use UTF-8 or UTF-16 (with BOM) encoding.
-The following commands are implemented:+
-^ Command                           ^ Description +When running commands specified using ''/script'' or ''/command'', batch mode is used implicitly and overwrite confirmations are turned off. In an interactive scripting mode, the user is prompted in the same way as in GUI mode. To force batch mode (all prompts are automatically answered negatively) use the command ''[[scriptcommand_option#batch|option batch abort]]''. For batch mode it is recommended to turn off confirmations using ''[[scriptcommand_option#confirm|option confirm off]]'' to allow overwrites (otherwise the [[ui_overwrite|overwrite confirmation prompt]] would be answered negatively, making overwrites impossible).
-| [[script_commands#call|call]]     | Executes arbitrary remote shell command | +
-| [[script_commands#cd|cd]]         | Changes remote working directory +
-| [[script_commands#chmod|chmod]]   | Changes permissions of remote file | +
-| [[script_commands#close|close]]   | Closes session | +
-| [[script_commands#exit|exit]]     | Closes all sessions and terminates the program +
-| [[script_commands#get|get]]       | Downloads file from remote directory to local directory | +
-| [[script_commands#help|help]]     | Displays help | +
-| [[script_commands#keepuptodate|keepuptodate]] | Continuously reflects changes in local directory on remote one | +
-| [[script_commands#lcd|lcd]]      | Changes local working directory | +
-| [[script_commands#lls|lls]]      | Lists the contents of local directory | +
-| [[script_commands#ln|ln]]         | Creates remote symbolic link | +
-| [[script_commands#lpwd|lpwd]]·····| Prints local working directory | +
-| [[script_commands#ls|ls]]         | Lists the contents of remote directory +
-| [[script_commands#mkdir|mkdir]]   | Creates remote directory | +
-| [[script_commands#mv|mv]]         | Moves or renames remote file | +
-| [[script_commands#open|open]]·····| Connects to server | +
-| [[script_commands#option|option]] | Sets or shows value of script options | +
-| [[script_commands#put|put]]      | Uploads file from local directory to remote directory | +
-| [[script_commands#pwd|pwd]]      | Prints remote working directory | +
-| [[script_commands#rm|rm]]         | Removes remote file | +
-| [[script_commands#rmdir|rmdir]]   | Removes remote directory | +
-| [[script_commands#session|session]] | Lists connected sessions or selects active session | +
-| [[script_commands#synchronize|synchronize]] | Synchronizes remote directory with local one |+
-===== [[console]] The Console Interface Tool ===== +Multiple sessions can be opened simultaneously. Use the ''[[scriptcommand_session|session]]'' command to switch between them.
-As ''WinSCP.exe'' is a GUI application, it cannot inherit the console window when run from another console application (such as the Windows command-prompt). To allow this, run WinSCP using the console interface tool ''WinSCP.com'' (you can find ''WinSCP.com'' in the main [[installation|installation package]]).+
-With console interface tool you can also use input/output redirection and pipes.+Note that the first connection to an SSH server requires [[#hostkey|verification of the host key]]. 
 +Also the first connection to FTPS or WebDAVS host with [[tls#certificate|certificate]] signed by untrusted authority requires verification of the certificate.
-===== [[hostkey]] Verifying the Host Key in Script ===== +~~AD~~
-The first connection to an SSH server requires [[ssh#verifying_the_host_key|verification of the host key]]. To automate the verification in script, you can use [[commandline|command-line]] parameter ''hostkey'' (or switch of ''[[script_commands#open|open]]'' command with the same name) to accept the expected hostkey automatically.+
-You can find the fingerprint on [[ui_fsinfo|Server and Protocol Information Dialog]].+===== [[result]] Checking Results ===== 
 +WinSCP [[executables]] return exit code 1 when any command is interrupted due to an error or any prompt is answered //Abort// (even automatically in batch mode). Otherwise it returns the exit code 0.
-===== Running a Script under a Different Account ===== +To further analyze results of scripted operations, you will find [[logging_xml|XML logging]] useful.
-If you are going to run the script under a different account (for example using the Windows scheduler), note that WinSCP may [[config|store its configuration]] to the user part of Windows Registry by default. So you may need to either transfer the configuration from your account registry to the other account registry or use the [[config|INI file]] instead. +
-Note that the configuration also includes [[scripting#hostkey|verified SSH host keys]].+//For more details, refer to [[faq_script_result|*]]//
-#include <inttypes.h> 
-#include <stdio.h> 
-#include <string.h> 
-#include <sys/types.h> 
-#include <unistd.h> 
-#include <openssl/sha.h> 
-#include <openssl/aes.h> 
-struct { +===== [[syntax]] Commands Syntax ===== 
- unsigned char magic[ 4 ]; +All WinSCP commands have syntax
- unsigned char version[ 3 ]; +<code> 
- unsigned char encrypted+command -switch -switch2 parameter1 parameter2 ... parametern 
- unsigned char unknownNull[4]; +</code> 
- unsigned int sizeOfData+ 
- unsigned int footerSignatureOffset+==== [[quotes]] Command Parameters with Spaces ==== 
- unsigned int footerCertOffset+ 
- unsigned int footerCertLen+Command parameters that include space(s) have to be surrounded by double-quotes. To use double-quote literally, double it: 
- unsigned char key1[ 32 ]; +<code winscp>
- unsigned char unknownVersion[ 4 ]; +put "file with spaces and &quot;"quotes"".html" 
- unsigned char key2[ 16 ]; +</code> 
- unsigned char unknow3[ 1968 ]; + 
-} header8900;+Note that when you are specifying commands on [[commandline#scripting|command-line]] using ''/command'', you need to surround each command by double-quote and [[commandline#syntax|escape the in-command double-quotes by doubling them]]. 
 + 
 +To debug the quoting, enable session logging on level //Debug 1// (''[[commandline#logging|/loglevel=1]]''). The log will show how WinSCP understands both your command-line and individual scripting commands. 
 + 
 + 
 +==== [[variables]] Environment Variables ==== 
 + 
 +You can use environment variables in the commands, with syntax ''%NAME%'':((Generally do surround reference by double-quotes to cope properly with spaces in its value.)) 
 +<code winscp>
 +put "%FILE_TO_UPLOAD%" 
 +</code> 
 + 
 +Note that variable expansion is different than in Windows batch files: 
 + 
 +  * You cannot use any [[https://en.wikibooks.org/wiki/Windows_Batch_Scripting#String_processing|string processing syntax]]. 
 +  * You cannot use [[wp>;Environment_variable#Windows_2|dynamic/pseudo environment variables]], such as ''%DATE%'' or ''%RANDOM%''. 
 +  * References to undefined variables are kept intact (not removed). 
 +  * You can use ''%WINSCP_PATH%'' to refer to WinSCP [[executable]] path. 
 + 
 +==== [[timestamp]] Timestamp ==== 
 + 
 +WinSCP automatically resolves ''%TIMESTAMP[rel]#format%'' to a real time (optionally to a past or future time) with the given format. The ''format'' may include ''yyyy'' for year, ''mm'' for month, ''dd'' for day, ''hh'' for hour, ''nn'' for minute and ''ss'' for second. For example, the ''%TIMESTAMP#yyyy-mm-dd%'' resolves to ''2016-06-22'' on 22 June 2016. See [[https://docwiki.embarcadero.com/Libraries/en/System.SysUtils.FormatDateTime|other formats you can use]]. 
 + 
 +The optional ''rel'' part, with syntax ''[-+]time[YDHNS]'', produces past (''-'') or future (''+'') timestamps. One of the following units must be used: ''Y'' (years), ''D'' (days), ''H'' (hours), ''N'' (minutes) or ''S'' (seconds). For example, the ''%TIMESTAMP-1D#yyyy-mm-dd%'' (the ''-1D'' meaning one day in the past) resolves to ''2016-06-21'' on 22 June 2016. 
 + 
 +To use ''<;nowiki>%TIMESTAMP...%</nowiki>'' on a command-line in a batch file, you need to escape the ''%'' by doubling it to ''<nowiki>%%TIMESTAMP...%%</nowiki>'', to avoid a batch file interpreter trying to resolve the variable. 
 + 
 +==== [[arguments]] Script Arguments ==== 
 + 
 +You can reference script arguments (passed on command-line using parameter ''[[commandline#scripting|/parameter]]'') using syntax ''%N%'', where ''N'' is ordinal number of argument:((Generally do surround reference by double-quotes to cope properly with spaces in its value.)) 
 +<code winscp>
 +put "%1%" 
 +</code> 
 + 
 +==== Case Sensitivity of File Names ==== 
 + 
 +Note that WinSCP treats filenames in case sensitive manner. So even if your server treats filenames in case insensitive manner, make sure you specify case properly.((This is important particularly for FTP sessions.)) 
 + 
 +==== [[comments]] Comments ==== 
 + 
 +To insert comments into the script file, start the line with ''#'' (hash): 
 +<code winscp>
 +# Connect to the server 
 +open mysession 
 +</code>
 + 
 +===== [[commands]] Commands ===== 
 +The following commands are implemented. 
 + 
 +To see help for the command, read respective documentation article below or type command ''[[scriptcommand_help|help <;command>]]'' directly in console. 
 + 
 +^ Command ··························^ Description ^ 
 +| [[scriptcommand_call|call]]     | Executes arbitrary remote shell command | 
 +| [[scriptcommand_cd|cd]]        | Changes remote working directory | 
 +| [[scriptcommand_checksum|checksum]] | Calculates checksum of remote file | 
 +| [[scriptcommand_chmod|chmod]]   | Changes permissions of remote file | 
 +| [[scriptcommand_close|close]]  | Closes session | 
 +| [[scriptcommand_cp|cp]] ········| Duplicates remote file | 
 +| [[scriptcommand_echo|echo]]     | Prints message onto script output | 
 +| [[scriptcommand_exit|exit]]    | Closes all sessions and terminates the program | 
 +| [[scriptcommand_get|get]] ······| Downloads file from remote directory to local directory | 
 +| [[scriptcommand_help|help]]     | Displays help | 
 +| [[scriptcommand_keepuptodate|keepuptodate]] | Continuously reflects changes in local directory on remote one | 
 +| [[scriptcommand_lcd|lcd]]      | Changes local working directory | 
 +| [[scriptcommand_lls|lls]]      | Lists the contents of local directory | 
 +| [[scriptcommand_ln|ln]]        | Creates remote symbolic link | 
 +| [[scriptcommand_lpwd|lpwd]]    | Prints local working directory | 
 +| [[scriptcommand_ls|ls]]        | Lists the contents of remote directory | 
 +| [[scriptcommand_mkdir|mkdir]]  | Creates remote directory | 
 +| [[scriptcommand_mv|mv]]        | Moves or renames remote file | 
 +| [[scriptcommand_open|open]]    | Connects to server | 
 +| [[scriptcommand_option|option]] | Sets or shows value of script options | 
 +| [[scriptcommand_put|put]]      | Uploads file from local directory to remote directory | 
 +| [[scriptcommand_pwd|pwd]]      | Prints remote working directory | 
 +| [[scriptcommand_rm|rm]]        | Removes remote file | 
 +| [[scriptcommand_rmdir|rmdir]]  | Removes remote directory | 
 +| [[scriptcommand_session|session]] | Lists connected sessions or selects active session | 
 +| [[scriptcommand_stat|stat]]    | Retrieves attributes of remote file | 
 +| [[scriptcommand_synchronize|synchronize]] | Synchronizes remote directory with local one | 
 + 
 +===== [[console]] The Console Interface Tool ===== 
 +Learn about ''[[executables|winscp.com]]'', the console interface tool. 
 + 
 +===== [[hostkey]] Verifying the Host Key or Certificate in Script ===== 
 +The first connection to an SSH server requires [[ssh_verifying_the_host_key|verification of the host key]]. To automate the verification in script, use ''[[scriptcommand_open#hostkey|-hostkey]]'' switch of ''[[scriptcommand_open|open]]'' command to accept the expected host key automatically.
-char inbuf[ 65536 ]; +You can find the key fingerprint on [[ui_fsinfo|Server and Protocol Information Dialog]]. You can also copy the key fingerprint to clipboard from the [[ssh_verifying_the_host_key|confirmation prompt]] on the first (interactive) connection using //Copy key fingerprints to clipboard// command (in the script, use SHA-256 fingerprint of the host key only). //Learn more about [[faq_hostkey|obtaining host key fingerprint]]//.
-char outbuf[ 65536 ];+
-void convert_hex(char *str, uint8_t *bytes, int maxlen) +FTPS/WebDAVS [[tls#certificate|TLS/SSL certificate]] signed by untrusted authority may also need to be verified. To automate the verification in script, use ''[[scriptcommand_open#certificate|-certificate]]'' switch of ''[[scriptcommand_open|open]]'' command to accept the expected certificate automatically.
-  int slen = strlen(str); +
-··int bytelen = maxlen; +
-  int rpos, wpos = 0;+
-  for(rpos = 0; rpos < bytelen; rpos++) { 
-    sscanf(&str[rpos*2], "%02hhx", &bytes[wpos++]); 
-  } 
-} 
-void print_hex( char* text, uint8_t* data, uint32_t len ) 
-{ 
- uint32_t ctr; 
- char* sep; 
- if( len > 64 ) 
- len = 64; 
- printf( "%s", text ); 
- for( ctr = 0; ctr < len; ctr++ ) 
- { 
- printf( "%02x ", data[ ctr ] ); 
- } 
- printf( "\n" ); 
-} 
-int main( int argc, char** argv ) +===== [[different_account]] Running a Script under a Different Account (e.g., Using a Scheduler) ===== 
-{ +If you are going to run the script under a different account (for example [[guide_schedule|using the Windows Task Scheduler]]), make sure the script does not rely on a configuration settings that might differ on the other account. When using registry as [[config|configuration storage]], the settings are accessible only for your Windows account. Ideally, make sure the script does not rely on any external configuration, to make it completely portable. Note that the configuration also includes [[#hostkey|verified SSH host keys]] and FTPS/WebDAVS [[tls#certificate|TLS/SSL certificates]].
- FILE *infile, *outfile; +
- int encrypted; +
- off_t data_begin, data_current, data_end, data_len; +
- AES_KEY ctx, aes_decrypt_key; +
- uint8_t aes_key[16];+
-·unsigned char ramdiskKey[32]=&quot;188458A6D15034DFE386F23B61D43774"; +//For details, see the [[#configuration|next section]] and [[faq_environment|*]]//
- unsigned char ramdiskiv[1];+
-·unsigned char keybuf[ 16 ]; +===== [[configuration]] Sharing Configuration with Graphical Mode ====
- unsigned char iv[ AES_BLOCK_SIZE ]; +In scripting/console mode, WinSCP shares [[config|configuration]] with [[interfaces|graphical mode]] by default. While this can be useful in some cases, it can also be a disadvantage.
-  +
- if( argc != 3 ) +
- { +
-··fprintf( stderr, &quot;Usage: %s infile outfile\n&quot;, argv[ 0 ] )+
- return 1+
- }+
- infile = fopen( argv[ 1 ], &quot;r&quot; ); +The disadvantage is that change to configuration in graphical mode may break your script (common example is enabling //[[ui_synchronize|Existing files only]]// option for [[task_synchronize_full|synchronization]]). Also the script is not portable to other machines, when it relies on an external configuration.
- if( !infile ) +
- { +
-··perror( &quot;infile fopen&quot; )+
- return 1; +
- }+
- outfile = fopen( argv[ 2 ], "w+" ); +If you want to protect your script from such inadvertent change or if you want to make the script portable, you should isolate its configuration from graphical mode explicitly.
-·if( !outfile +
-+
- perror( "outfile fopen" )+
- return 1; +
- }+
-·if( sizeof( header8900 ) != fread( &amp;header8900, 1, sizeof( header8900 ), infile ) ) +The best way to do that is to configure all the options you need using script commands only (''[[scriptcommand_option|option]]'' command, switches of other commands, [[session_url|session URL]]), or if no such command is available, using [[rawsettings|raw site settings]] and [[rawconfig|raw configuration]]. Finally force scripting mode to [[config#no|start with the default configuration]] using ''[[commandline#configuration|/ini=nul]]'' command-line parameter.
- { +
-··fprintf( stderr, &quot;Can't read header\n&quot; ); +
-··return 1; +
- }+
-·if( ( header8900.magic[ 0 ] != 0x38 ) &amp;&amp; // 8 +Alternatively [[config#export|export your configuration]] to a separate INI file and reference it using ''[[commandline#configuration|/ini=]]'' command-line parameter. Also consider setting the INI file read-only, to prevent WinSCP writing to it, when exiting. Particularly, if you are running multiple scripts in parallel, to prevent different instances of WinSCP trying to write it at the same time.
-·····( header8900.magic[ 1 ] != 0x39 ) &amp;& // 9 +
-     ( header8900.magic[ 2 ] != 0x30 ) && // 0 +
-     ( header8900.magic[ 3 ] != 0x30 ) )  // +
-+
- fprintf( stderr, "Bad magic\n" )+
- return 1; +
- }+
-·if( header8900.encrypted == 0x03 +===== Generating Script =====
- encrypted = 1; +
- else if( header8900.encrypted = 0x04 ) +
- encrypted = 0;+
- data_begin = sizeof( header8900 ); +You can have WinSCP [[ui_generateurl|generate a script template for you]].
- data_len = header8900.sizeOfData;+
-·printf( &quot;iPhone 8900 decryptor by PmgR,\n&quot;); +===== [[example]] Example ===== 
- printf( "extended and modified from original file by aljen.\n&quot;); +In the example below, WinSCP connects to ''example.com'' server with account ''user'', downloads file and closes the session. Then it connects to the same server with the account ''user2'' and uploads the file back.  
- ·······printf( &quot;Thanks to hardware decrypt key found by by dev & elite teams.\n\n"); +&lt;code winscp&gt; 
- printf( "[*] filename \t\t: %s\n", argv[ 1 ] ); +# Connect 
- printf( &quot;[*] magic \t\t: %s\n&quot;, header8900.magic ); +open sftp://user:password@example.com/ -hostkey="ssh-rsa 2048 xxxxxxxxxxx..." 
- printf( &quot;[*] version \t\t: %s\n&quot;, header8900.version )+# Change remote directory 
- printf( "[*] encrypted \t\t: %d\n", encrypted ); +cd /home/user 
- printf( &quot;[*] start of data ···\t\t: 0x%02x\n&quot;, data_begin ); +# Download file to the local directory d:\ 
- printf( &quot;[*] size of data\t\t: 0x%02x\n&quot;, header8900.sizeOfData ); +get examplefile.txt d:\ 
- printf( &quot;[*] footer signature offset\t: 0x%02x\n", header8900.footerSignatureOffset ); +# Disconnect 
- printf( &quot;[*] footer certificate offset\t: 0x%02x\n&quot;, header8900.footerCertOffset ); +close 
- printf( &quot;[*] footer certificate length\t: 0x%02x\n&quot;, header8900.footerCertLen ); +# Connect as a different user 
- print_hex( &quot;[*] header key 1\t\t: &quot;, header8900.key1, sizeof( header8900.key1 ) ); +open sftp://user2:password@example.com/ 
- print_hex( &quot;[*] header key 2\t\t: &quot;, header8900.key2, sizeof( header8900.key2 ) );+# Change the remote directory 
 +cd /home/user2 
 +# Upload the file to current working directory 
 +put d:\examplefile.txt  
 +# Disconnect 
 +close 
 +# Exit WinSCP 
 +exit 
 +&lt;/code&gt; 
 +Save the script to the file ''example.txt''. To execute the script file use the following command.  
 +&lt;code batch&gt; 
 +winscp.com /ini=nul /script=example.txt 
 +&lt;/code&gt;
-·//memset( keybuf, 0, 32 ); +For simple scripts you can specify all the commands on [[commandline|command-line]] using ''/command'' switch
- ·······//memcpy( keybuf, header8900.key1, 32 ); +<code batch> 
- convert_hex(ramdiskKey, aes_key, 16); +winscp.com /ini=nul /command ";open sftp://user:password@example.com/ -hostkey=&quot;&quot;ssh-rsa 2048 xxxxxxxxxxx...&quot;";&quot; &quot;get examplefile.txt d:\" "exit"
- AES_set_decrypt_key( aes_key, 128, &amp;aes_decrypt_key ); +&lt;/code&gt;
- memset( iv, 0, AES_BLOCK_SIZE )+
- //memcpy( iv, header8900.key2, 16 );+
- fseek( infile, data_begin, SEEK_SET ); +In Windows batch file, you can use ''^'' to split too long command-line to separate lines by [[wp&gt;Batch_file#Escaped_characters_in_strings|escaping]] following new-line character:
- //printf(&quot;dataend: %d\n&quot;, data_len);+
-·data_current=0+&lt;code batch>
- while( fread( &amp;inbuf, 1, AES_BLOCK_SIZE, infile ) &gt; 0 &amp; data_current&lt;data_len) +winscp.com /ini=nul /command ^ 
- {+····&quot;open sftp://user:password@example.com/ -hostkey=""ssh-rsa 2048 xxxxxxxxxxx..."""
 +····&quot;get examplefile.txt d:\&quot;
 +····&quot;exit" 
 +</code>
-···AES_cbc_encrypt( inbuf, outbuf, AES_BLOCK_SIZE, &amp;aes_decrypt_key, iv, AES_DECRYPT ); +//See other [[scripts|useful example scripts]]//.
-···fwrite( outbuf, 1, AES_BLOCK_SIZE, outfile ); +
-   data_current = data_current + AES_BLOCK_SIZE; +
- }+
-·if( infile ) +===== Converting Script to Code Based on .NET Assembly ===== 
- fclose( infile ); +When you find yourself limited by scripting capabilities, you may consider [[library_from_script|converting your script to code that uses WinSCP .NET assembly]].
- if( outfile ) +
-··fclose( outfile ); +
- return 0; +
-}+
-===== Useful Scripts ===== +===== Further Reading ===== 
-You can see list of [[scripts]] other users found useful.+··* [[guide_automation|Guide to scripting]]; 
 + * [[faq#scripting|FAQs about scripting]]; 
 +  * [[scripts|Useful example scripts]]
 +  * [[library|WinSCP .NET assembly]].
-For more tips, see also [[faq#scripting_automation|FAQs on scripting]]. 

Last modified: by 67.2.35.174