How to Execute a Remote SSH Command from a Batch Script
Managing Linux servers or networking equipment often requires running commands remotely. While PowerShell has robust remoting capabilities for Windows targets (via WinRM), SSH (Secure Shell) is the universal standard for everything else. Fortunately, modern Windows 10/11 includes an OpenSSH client natively, allowing your Batch scripts to execute remote commands without third-party utilities like PuTTY.
In this guide, we will demonstrate how to authenticate and execute commands over SSH directly from a Batch script.
Setup: Key-Based Authentication
Because the native ssh.exe strictly refuses to accept passwords passed inline as text, you must configure Key-Based Authentication to allow your script to connect silently.
- Open a command prompt and type
ssh-keygen. Press Enter through all the default prompts to create a key pair inC:\Users\YourUser\.ssh\. - Copy the contents of
id_rsa.pub. - Log into your remote Linux server and append the public key string to
~/.ssh/authorized_keys. - Test the connection manually once:
ssh user@linux-server. This ensures the server's thumbprint is registered in your localknown_hostsfile.
Method 1: Single Remote Command
If you only need to trigger a quick reload or check a service status, you can pass the command directly as the final argument to ssh.
@echo off
setlocal enabledelayedexpansion
:: Verify OpenSSH client is installed
where ssh >nul 2>nul
if !errorlevel! neq 0 (
echo [ERROR] OpenSSH client is not installed or not in PATH.
pause
exit /b 1
)
:: Define connection
set "remoteUser=admin"
set "remoteHost=192.168.1.100"
set "privateKey=C:\Users\Admin\.ssh\id_rsa"
:: Verify the private key file exists
if not exist "%privateKey%" (
echo [ERROR] Private key file "%privateKey%" not found.
pause
exit /b 1
)
:: Define the remote command (e.g., restarting a web server)
set "remoteCmd=sudo systemctl restart nginx"
echo Connecting to %remoteHost%...
echo Executing command: %remoteCmd%
echo.
:: Run SSH silently using the private key
:: Note: The remote command must be in quotes
ssh -i "%privateKey%" %remoteUser%@%remoteHost% "%remoteCmd%"
:: Capture the exit code immediately
set "sshResult=!errorlevel!"
if !sshResult! equ 0 (
echo.
echo ==========================================
echo COMMAND EXECUTED SUCCESSFULLY
echo ==========================================
) else (
echo.
echo [ERROR] SSH execution failed with exit code !sshResult!.
pause
exit /b 1
)
endlocal
pause
exit /b 0
Method 2: Multi-line Remote Script (Here-Document Style)
If you need to execute a complex sequence of commands (setting variables, looping, parsing files on the remote side), passing them as a single string is unmanageable. Instead, you can save the commands to a local temporary file and stream them to the ssh process via stdin redirection <.
@echo off
setlocal enabledelayedexpansion
:: Verify OpenSSH client is installed
where ssh >nul 2>nul
if !errorlevel! neq 0 (
echo [ERROR] OpenSSH client is not installed or not in PATH.
pause
exit /b 1
)
set "remoteTarget=admin@192.168.1.100"
set "keyfile=C:\Users\Admin\.ssh\id_rsa"
set "tempScript=%TEMP%\remote_script.sh"
:: Verify the private key file exists
if not exist "%keyfile%" (
echo [ERROR] Private key file "%keyfile%" not found.
pause
exit /b 1
)
:: 1. Build the shell script to execute on the remote machine
(
echo #!/bin/bash
echo echo "Starting system cleanup..."
echo sudo apt-get autoremove -y
echo sudo apt-get clean
echo df -h /
echo echo "Cleanup complete."
) > "%tempScript%"
echo Executing multi-line script on %remoteTarget%...
echo.
:: 2. Pipe the script into the SSH connection
ssh -i "%keyfile%" "%remoteTarget%" < "%tempScript%"
:: Capture the exit code immediately
set "sshResult=!errorlevel!"
:: 3. Cleanup the temporary script file
del "%tempScript%" 2>nul
:: 4. Validate the result
if !sshResult! equ 0 (
echo.
echo [SUCCESS] Remote script executed successfully.
) else (
echo.
echo [ERROR] Remote script failed with exit code !sshResult!.
pause
exit /b 1
)
endlocal
pause
exit /b 0
Why Execute SSH Commands via Batch?
- Cross-Platform Automation: Triggering a MySQL database dump on a Linux server, downloading it (via SFTP), and processing it locally on your Windows workstation, all orchestrated by a single
.batfile. - Health Checks: Iterating through a list of 50 Apache web servers and running
systemctl status apache2, returning the results to a single central console. - Deployment Pipelines: After compiling code locally, using
sshto restart a remote Docker container or trigger agit pullon the production server.
Important Considerations
- Sudo Prompts: If your remote command requires
sudo, the Linux server will prompt for the user's password, which freezes the Batch script. To fix this, you must configure the remote user in the Linux/etc/sudoersfile to haveNOPASSWDpermissions for that specific command. - Quoting and Escaping: When passing strings ending in quotes, or utilizing
$variables within the remote command (ssh user@host "echo $PATH"), you must ensure Batch doesn't attempt to expand the variable locally before transmission. This is why streaming a script file (Method 2) is considerably safer for complex commands. - Known Hosts Prompt: If the remote server's IP or signature changes, the script will silently hang waiting for a "yes/no" confirmation on the host key.
Conclusion
Executing remote SSH commands effortlessly bridges the gap between Windows automation scripts and Linux server management. By leveraging the native Windows OpenSSH client paired with secure identity keys, your single local Batch script becomes capable of commanding your entire multi-platform infrastructure.