@ECHO OFF
SETLOCAL
set /a count=5
set "filelist="
for /f "delims=" %%a in ('dir /s /r /b /a-d /o:-d "C:\sample\Test" ') do if defined count set "filename=%%a" &call :transfer
"C:\Program Files (x86)\WinSCP\WinSCP.com" ^
/command ^
"open sftp://username:password@ip_address/ -hostkey=""key""" ^
"put %filelist% /test/async_messages/" ^
"exit"
goto :eof
:transfer
echo %filename%
set "filelist=%filelist% "%filename%""
set /a count-=1
if %count%==0 set "count="
goto :eof
[not tested - should work]
First, add a setlocal command so that the environment is restored after running the batch.
then set a variable (count, for example) to the required number of transfers.
NOTE that the dir command has been altered - /o:-d to generate the file-list in reverse-date order.
If count is defined, execute the transfer in the routine :transfer. Decrement the count variable, and if it has now been decremented to 0, then remove it from the environment by assigning an empty string to it.
So, once that number of files has been transferred, count will become undefined and the call :transfer will not be executed.
Note the addition of goto :eof which transfers execution to the end-of-batch-file, terminating the batch or routine.
I've no idea of what your transfer code is doing - it's an unfamiliar construct to me. I've no idea whether the "exit" is part of the normal operation of whatever the command is, or whether it's an exit-from-batch, in which case it's likely that it would need to be removed.
Comment:
Modified per suggestion by Martin Prikryl. The list built in filelist is a space-separated list of filenames. Since filenames may contain spaces, I have quoted those filenames as they are added, so filelist should contain "filename1" "file name one" "file1". I don't know whether this will interfere with the WinSCP command. If a different character is used in place of the rabbit's ears (") then substitute (or remove, if required) the inner two " in the set "filelist=%filelist% "%filename%"" command.
The syntax SET "var=value" (where value may be empty; in which case var becomes undefined) is used to ensure that any stray trailing spaces are NOT included in the value assigned. In this particular case, it may not be required, it's just a general rule of batch.