How to Transfer Files via SCP from a Batch Script
Transferring files to Linux servers securely once required dedicated FTP clients or third-party wrappers like WinSCP. But just like regular SSH connections, modern Windows environments natively include the SCP (Secure Copy Protocol) command-line tool. While SFTP acts like an interactive file browser, SCP functions exactly like the local copy command, but securely over an SSH encrypted connection.
In this guide, we will demonstrate how to upload and download files using SCP in a Batch script.
Setup: Key-Based Authentication
Because the Windows scp.exe strictly refuses to accept a password passed inline via the command shell, you must configure Key-Based Authentication to allow your script to transfer files silently.
- Open a command prompt and type
ssh-keygen. Stick to the defaults to create a key pair inC:\Users\YourUser\.ssh\. - Copy the contents of the public key
id_rsa.pub. - Log into your remote Linux server and append the public key string to the
~/.ssh/authorized_keysfile. - Run an SCP command manually once so Windows can add the server to its
known_hostsfile without pausing the automated script later.
Method 1: Uploading a Local File (Push)
To copy a file from your Windows workstation to a remote server, specify the local file first, then the remote target.
@echo off
setlocal enabledelayedexpansion
:: Verify SCP is installed
where scp >nul 2>nul
if !errorlevel! neq 0 (
echo [ERROR] SCP is not installed or not in PATH.
pause
exit /b 1
)
:: Define the Local File
set "localFile=C:\Backups\database_dump.sql"
:: Define the Remote Target (user@host:/path/to/destination/)
set "remoteDest=admin@192.168.1.50:/home/admin/backups/"
:: Define the Private Key Path
set "privateKey=C:\Users\Admin\.ssh\id_rsa"
:: Ensure private key exists
if not exist "%privateKey%" (
echo [ERROR] Private key file "%privateKey%" not found.
pause
exit /b 1
)
:: Ensure local file exists
if not exist "%localFile%" (
echo [ERROR] File not found: "%localFile%"
pause
exit /b 1
)
echo Starting secure upload of "%localFile%"...
echo Destination: %remoteDest%
echo.
:: SCP Command Structure: scp -i key source destination
:: The -q flag makes SCP run quietly (no progress meter)
scp -q -i "%privateKey%" "%localFile%" "%remoteDest%"
:: Capture the exit code immediately
set "scpResult=!errorlevel!"
if !scpResult! equ 0 (
echo.
echo ==========================================
echo UPLOAD SUCCESSFUL
echo ==========================================
) else (
echo.
echo [ERROR] SCP transfer failed with exit code !scpResult!. Ensure path and keys are correct.
pause
exit /b 1
)
endlocal
pause
exit /b 0
Method 2: Downloading a Remote File (Pull)
To copy a file from a remote server to your Windows machine, just reverse the argument sequence.
@echo off
setlocal enabledelayedexpansion
:: Verify SCP is installed
where scp >nul 2>nul
if !errorlevel! neq 0 (
echo [ERROR] SCP is not installed or not in PATH.
pause
exit /b 1
)
:: Define the Remote Source
set "remoteSource=admin@192.168.1.50:/var/log/syslog"
:: Define the Local Destination
set "localDest=C:\Logs\Server50\"
:: Define the Private Key Path
set "privateKey=C:\Users\Admin\.ssh\id_rsa"
:: Ensure private key exists
if not exist "%privateKey%" (
echo [ERROR] Private key file "%privateKey%" not found.
pause
exit /b 1
)
echo Pulling remote file securely...
echo Source: %remoteSource%
echo.
:: Ensure the local directory exists
if not exist "%localDest%" mkdir "%localDest%"
:: Execute SCP Pull
scp -q -i "%privateKey%" "%remoteSource%" "%localDest%"
:: Capture the exit code immediately
set "scpResult=!errorlevel!"
if !scpResult! equ 0 (
echo [SUCCESS] Download complete. Check "%localDest%".
) else (
echo [ERROR] Download failed with exit code !scpResult!.
pause
exit /b 1
)
endlocal
pause
exit /b 0
Advanced: Recursive Copy for Directories
SCP has a -r flag to recursively copy entire folders, perfect for backing up a web directory.
@echo off
setlocal enabledelayedexpansion
:: Verify SCP is installed
where scp >nul 2>nul
if !errorlevel! neq 0 (
echo [ERROR] SCP is not installed or not in PATH.
pause
exit /b 1
)
set "remoteSrc=admin@192.168.1.50:/var/www/html/"
set "localDst=C:\WebBackups\Server50\"
set "privateKey=C:\Users\Admin\.ssh\id_rsa"
:: Ensure private key exists
if not exist "%privateKey%" (
echo [ERROR] Private key file "%privateKey%" not found.
pause
exit /b 1
)
:: Ensure local destination exists
if not exist "%localDst%" mkdir "%localDst%"
echo Downloading remote directory recursively...
:: Pulls the entire /html/ folder structure
scp -q -r -i "%privateKey%" "%remoteSrc%" "%localDst%"
:: Capture the exit code immediately
set "scpResult=!errorlevel!"
if !scpResult! equ 0 (
echo [SUCCESS] Directory downloaded to "%localDst%".
) else (
echo [ERROR] Recursive download failed with exit code !scpResult!.
pause
exit /b 1
)
endlocal
pause
exit /b 0
Why Copy Files via SCP in Batch?
- Server Migrations: A
.batfile that loops over dozens of Windows assets to bundle them into a.zipfile, and uses SCP to securely push the archive to the new remote deployment center. - Configuration Management: Pulling remote
/etc/configuration files down to an administrator's machine for auditing without firing up WinSCP every morning. - Cross-Platform Simplicity: Replacing convoluted legacy FTP servers with SCP secures the payload against interception natively.
Important Considerations
- Case Sensitivity: Windows paths (
C:\Logs) are case-insensitive, but Linux paths (/Var/Logvs/var/log) are strictly case-sensitive. Incorrect casing on the remote path is the number one cause of SCP failures. - Bandwidth Throttling: If you are running an automated backup in the middle of a workday, SCP provides a
-lflag to limit bandwidth (in Kbit/s):scp -q -l 8192 -i ...limits the transfer to 1MB/s. - Port Forwarding: If the SSH daemon on the target server relies on a non-standard port (e.g., 2222 instead of 22), use the capital
-Pflag:scp -P 2222 -i ....
Conclusion
The Secure Copy Protocol (SCP) transforms the local Batch copy command into a network-spanning tool capable of moving files perfectly across disparate operating systems. By marrying the simplicity of a Batch script with the unbreakable encryption of SSH keys, you construct resilient file transfer pipelines that are both highly automated and universally understood by cross-platform engineers.