I often find myself opening an SSH session to run the same single command. I have everything setup to login without entering a password (Via SSH Key-Based Auth), so I wondered if there was a way to create a shortcut or a batch file in Windows that would load PuTTY or a similar program, then fire off that command (and likely exit if result is good).
Use the commandline PuTTY version
plink.exe to initate a SSH connection to a host of choice. Use the
-ssh switch to connect with SSH. With the
-m switch you can include a command file:
plink.exe -ssh host1 -m C:\path\to\commands.txt
You can download
plink.exe from here.
Last step would be to create a shortcut including
plink.exe with the desired parameters.
Check out the Plink documentation for other various parameters: Plink.exe documentation
You can use putty configurations to achieve this.
Load putty and configure your session.
Enter the remote command that you'd like to run here:
Then, before clicking "Open", go back to the "Session" tab (at the top), and save your configuration.
Now, create a shortcut to
putty.exe, adding the
-load flag, for example:
%PATH_TO_PUTTY%\putty.exe -load my_config
Now, you can just click on the shortcut and it will load your session, executing your command.
If you're using Windows 10 or higher, you might be interested to know that Microsoft has a beta of OpenSSH, both the client and the server. You can install OpenSSH with Windows Features as below or download the portable version from GitHub.
To install the OpenSSH [client]:
- Open Settings, select Apps, then select Optional Features.
- Scan the list to see if the OpenSSH is already installed. If not, at the top of the page, select Add a feature, then:
- Find OpenSSH Client, then select Install
- […server installation, if needed…]
- Once setup completes, return to Apps and Optional Features and confirm OpenSSH is listed.
- […server configuration, if needed…]
After this, you should be able to use
ssh like you would on a Unix-like system:
C:\WINDOWS\system32>ssh user@host "ls -l ~"
You should only need the server running on machines you log in to and only need the client on machines you log in from. Correspondingly, if you log into one machine as a proxy to hop into another one, that middle machine will need both.
Here is the script I made to hopefully save some people hours of syntax and
man page research.
- SingleIP, IP Range, or IPList file
- Script name to run on the IP/range (actual Unix
- Optionally do
nmapscan for port 22 open (i.e. subnet with some non-Linux machines)
- want to avoid IPs putty cannot connect to, avoiding script being able to continue properly
- Optionally run
pscpcommand to autocache the host key (PuTTY does not do this automatically)
This batch assumes:
- You have the full PuTTY package and SSH key are installed in
- Batch scripts and IPlist files are installed in
nmapand PuTTY working directories are in your command path
This is mostly useful for having a single script (such as updating an SSL certificate) across a range of machines.
Here is the complete batch file:
@ECHO OFF rem You must modify the CACHEKEY and SCRIPT section to reflect your SSH key location set IPFILE=IPList_temp.txt set runagain=n set OPTION=1 set RANGE= set IP= set SCAN=n set KEYCACHE=n :OPTION CLS ECHO (Working directory is set to C:\Program Files\PuTTY\scripts\) ECHO. ECHO 1. Single IP ECHO 2. IP list file ECHO 3. IP Range ECHO. set /p OPTION="Choose IP type:" IF %OPTION%==3 GOTO IPRANGE IF %OPTION%==2 GOTO IPLIST IF %OPTION%==1 GOTO SINGLEIP echo Please select a valid option GOTO OPTION :IPRANGE ECHO Enter the IP range(s) as in the following example. Use a space between multiple ranges: ECHO i.e. "10.21.0.15-99 10.21.1.15-100" set /p RANGE=Enter Range: echo %RANGE% > %IPFILE% GOTO SCRIPTNAME :SINGLEIP set /p IP=Enter IP: echo %IP% > %IPFILE% GOTO SCRIPTNAME :IPLIST set /p IP=Enter IPList filename: copy /Y %IP% %IPFILE% GOTO SCRIPTNAME :SCRIPTNAME set /p SCRIPT=Enter script name: if not exist %SCRIPT% ( echo filename does not exist! GOTO SCRIPTNAME ) ECHO. set /p SCAN=Do Nmap scan first? (recommended): if %SCAN%==n GOTO :RUNCACHE rem Check whether IP type is "range" as nmap cannot read an IP range from file and must be type directly in nmap command IF %OPTION%==3 GOTO NMAPRANGE :NMAP echo Scanning IPs for port 22 open... nmap --open -n -p22 -iL %IPFILE% -oG - | findstr /E Up > nmap_temp.txt GOTO AFTERNMAP :NMAPRANGE echo Scanning IPs for port 22 open... nmap --open -n -p22 %RANGE% -oG - | findstr /E Up > nmap_temp.txt :AFTERNMAP echo DONE rem nmap formatting is not correct, the following removes extra info for /f "tokens=2" %%A in (nmap_temp.txt) do echo %%A >> nmap_temp2.txt rem remove hidden space at end of IP (requires "repl" be in the batch file directory) type "nmap_temp2.txt" | repl " " "" > %IPFILE% :RUNCACHE set /p KEYCACHE=Scan and cache SSH key (y/n) ? if %KEYCACHE%==n GOTO SCRIPT :CACHEKEY rem Run through all IPs to cache the SSH Host Key if not already cached for /F "tokens=*" %%A in (%IPFILE%) do ( echo y | "C:\Program Files\PuTTY\pscp.exe" -l root -i "C:\Program Files\PuTTY\SSH.ppk" -touch %%A:/tmp/test ) :SCRIPT for /F "tokens=1" %%A in (%IPFILE%) do ( "C:\Program Files\PuTTY\putty.exe" -ssh %%A -t -l root -i "C:\Program Files\PuTTY\SSH.ppk" -m "C:\Program Files\PuTTY\scripts\%SCRIPT%" ) if exist nmap_temp.txt (del nmap_temp.txt) if exist nmap_temp2.txt (del nmap_temp2.txt) set /p runagain="Press Enter to Finish or y to rerun" if %runagain%==y GOTO OPTION
This is the final "CMD" which I can just save on my FileServer and create a shortcut on my Desktop.
::FreeSoftwareServers ::Automated Opening of SSH Tunnel & Execute CMD on Remote Host ::https://superuser.com/questions/1278434/create-a-batch-file-or-shortcut-to-putty-ssh-that-opens-a-session-and-runs-a-c set puttydir="C:\Program Files\PuTTY" set exe=plink.exe ::Profile must exist in PuTTY set remotehost=FileServer set remotecmd="chmod 777 /mnt/mdadm/torrents -R" cd %puttydir% %exe% %remotehost% %remotecmd% ::Test First Manually in CMD Prompt ::Note Remote Host does NOT have access to BashRC Alias's ::start "C:\Program Files\PuTTY\" plink.exe -ssh FileServer touch /tmp/testfile ::start "C:\Program Files\PuTTY\" plink.exe -ssh FileServer ~/script.sh