PuTTY scripting to log onto host - command-line

I'm using PuTTY to remotely log onto my school's host. Upon logging in, we are required to do these steps:
enter username
enter password
command "add oracle"
command "sqlplus"
enter username
enter password
I will be logging into this host a lot over the course of this semester and I was hoping to create a script that would eliminate the redundancy of the above steps. Ignoring the obvious security oversights of having my password in the script, how would I achieve this? I have zero experience with scripting, so your feedback is greatly appreciated. Thanks!
Edit: I played around with the command-line options for Putty and I was able to bypass steps 1-2 using:
putty -load "host" -l username -pw password
I've also created a shell file that looks like so:
#!/bin/bash
add oracle10g
sqlplus username password
When I try to add this option to the command-line using the -m option, it looks like PuTTY logs into the host and then immediately exits. Is there a way to keep my session open after running the shell file or am I using the -m option wrongly? Here is a link to a PuTTY guide that I have been following: http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter3.html.
Here is the total command that I am trying to run from the command-line:
putty -load "host" -l username -pw password -m c:\test.sh

Figured this out with the help of a friend. The -m PuTTY option will end your session immediately after it executes the shell file. What I've done instead is I've created a batch script called putty.bat with these contents on my Windows machine:
#echo off
putty -load "host" -l username -pw password
This logs me in remotely to the Linux host. On the host side, I created a shell file called sql with these contents:
#!/bin/tcsh
add oracle10g
sqlplus username password
My host's Linux build used tcsh. Other Linux builds might use bash, so simply replace tcsh with bash and you should be fine.
To summarize, automating these steps are now done in two easy steps:
Double-click putty.bat. This opens PuTTY and logs me into the host.
Run command tcsh sql. This adds the oracle tool to my host, and logs me into the sql database.

I'm not sure why previous answers haven't suggested that the original poster set up a shell profile (bashrc, .tcshrc, etc.) that executed their commands automatically every time they log in on the server side.
The quest that brought me to this page for help was a bit different -- I wanted multiple PuTTY shortcuts for the same host that would execute different startup commands.
I came up with two solutions, both of which worked:
(background) I have a folder with a variety of PuTTY shortcuts, each with the "target" property in the shortcut tab looking something like:
"C:\Program Files (x86)\PuTTY\putty.exe" -load host01
with each load corresponding to a PuTTY profile I'd saved (with different hosts in the "Session" tab). (Mostly they only differ in color schemes -- I like to have each group of related tasks share a color scheme in the terminal window, with critical tasks, like logging in as root on a production system, performed only in distinctly colored windows.)
The folder's Windows properties are set to very clean and stripped down -- it functions as a small console with shortcut icons for each of my frequent remote PuTTY and RDP connections.
(solution 1)
As mentioned in other answers the -m switch is used to configure a script on the Windows side to run, the -t switch is used to stay connected, but I found that it was order-sensitive if I wanted to get it to run without exiting
What I finally got to work after a lot of trial and error was:
(shortcut target field):
"C:\Program Files (x86)\PuTTY\putty.exe" -t -load "SSH Proxy" -m "C:\Users\[me]\Documents\hello-world-bash.txt"
where the file being executed looked like
echo "Hello, World!"
echo ""
export PUTTYVAR=PROXY
/usr/local/bin/bash
(no semicolons needed)
This runs the scripted command (in my case just printing "Hello, world" on the terminal) and sets a variable that my remote session can interact with.
Note for debugging: when you run PuTTY it loads the -m script, if you edit the script you need to re-launch PuTTY instead of just restarting the session.
(solution 2)
This method feels a lot cleaner, as the brains are on the remote Unix side instead of the local Windows side:
From Putty master session (not "edit settings" from existing session) load a saved config and in the SSH tab set remote command to:
export PUTTYVAR=GREEN; bash -l
Then, in my .bashrc, I have a section that performs different actions based on that variable:
case ${PUTTYVAR} in
"")
echo ""
;;
"PROXY")
# this is the session config with all the SSH tunnels defined in it
echo "";
echo "Special window just for holding tunnels open." ;
echo "";
PROMPT_COMMAND='echo -ne "\033]0;Proxy Session #master01\$\007"'
alias temppass="ssh keyholder.example.com makeonetimepassword"
alias | grep temppass
;;
"GREEN")
echo "";
echo "It's not easy being green"
;;
"GRAY")
echo ""
echo "The gray ghost"
;;
*)
echo "";
echo "Unknown PUTTYVAR setting ${PUTTYVAR}"
;;
esac
(solution 3, untried)
It should also be possible to have bash skip my .bashrc and execute a different startup script, by putting this in the PuTTY SSH command field:
bash --rcfile .bashrc_variant -l

When you use the -m option putty does not allocate a tty, it runs the command and quits. If you want to run an interactive script (such as a sql client), you need to tell it to allocate a tty with -t, see 3.8.3.12 -t and -T: control pseudo-terminal allocation. You'll avoid keeping a script on the server, as well as having to invoke it once you're connected.
Here's what I'm using to connect to mysql from a batch file:
#mysql.bat
start putty -t -load "sessionname" -l username -pw password -m c:\mysql.sh
#mysql.sh
mysql -h localhost -u username --password="foo" mydb
https://superuser.com/questions/587629/putty-run-a-remote-command-after-login-keep-the-shell-running

I want to suggest a common solution for those requirements, maybe it is a use for you: AutoIt. With that program, you can write scripts on top of any window like Putty and execute all commands you want to (like button pressing or mouse clicking in textboxes or buttons).
This way you can emulate all steps you are always doing with Putty.

entering a command after you logged in can be done by going through SSH section at the bottom of putty and you should have an option Remote command (data to send to the server) separate the two commands with ;

mputty can do that but it does not seem to work always. (if that wait period is too slow)
mputty uses putty and it extends putty.
There is an option to run a script.
If it does not work, make sure that wait period before typing is a high value or increase that value. See putty sessions , then name of session, right mouse button,properties/script page.

For me it works this way:
putty -ssh root#1.1.1.1 22 -pw password
putty, protocol, user name # ip address port and password. To connect in less than a second.

You can use the -i privatekeyfilelocation in case you are using a private key instead of password based.

Related

How to execute ssh connect by script?

I have local Windows 10 and remote Ubuntu server.
I want to automate connection to server and write executable script witch connects by ssh to server and open new terminal from another server.
What it's supposed to look like
I double click on bat
And then script
inits ssh connect
writes password
gives the user a terminal with a ready ssh connection.
That is, it mimics the following
Problems
How to wait ssh password request? All commands executes immediately.
(additional) can I write it in .sh script, run script, execute all in "start" terminal (from which I run .sh script) and then pass ssh control to invoked terminal?
It's best if someone writes a ready-made script
Automatically enter SSH password with script
Answers:
Direct answer - use expects. But sshpass is better. Also RSA-key can be used.
Can`t tell anything.
Can be done without any 3rd party tools like this:
$env:TMPPW=Get-Content -Path 'secure_file.txt' ; $un='MyUserName'
$j=Start-Job -ScriptBlock{Start-Sleep -Seconds 1
(New-Object -ComObject wscript.shell).SendKeys("$env:TMPPW{ENTER}")}
& ssh.exe -q -4 -l $un 127.0.0.1 'whoami'
$env:TMPPW=([guid]::NewGuid()).Guid ; $env:TMPPW=$null

Reuse in PowerShell a running PuTTY agent (pageant)

Is there a way in PS 5.1 to reuse the PuTTY agent keys?
Now, the details.
To use key agents one has an Agent that holds the keys (left box), and Client Applications that delegate administration of the keys (right box).
E.g., client application C1=putty can use its own agent A1=pageant, of course.
Client application C2=winscp knows how to use directly A1.
Certain Clients cannot use certain Agents directly, but there are Proxy agents that bridge the gap.
For instance to use A1 with C3, I need Proxy P1=ssh-pageant, see example below.
This helps centralizing in a single Agent the keys for many Clients.
Now I mean to use A1 for all my Clients (currently, only missing A1-C5 and A1-C6).
Is there a way in PS 5.1 to reuse the same PuTTY agent keys?
(I.e., a Proxy Px to use A1 with C5)
Possibly helpful:
https://superuser.com/a/1173570/245595
NOTES:
I did not try it, but it seems like winssh-pageant is a Proxy to link A2 with Client applications that understand A1 directly.
I am currently trying to use in PS the same ssh-pageant from msys2 (it is a Windows program in the end, and often times they do work), manually replacing what eval does in msys2 (so far with no luck, but I think this is fixable):
> cd <dir where ssh-pageant is>
> .\ssh-pageant -r -a "$env:USERPROFILE\tmp\.ssh-pageant-$env:USERNAME"
SSH_AUTH_SOCK='C:\Users\USER1\tmp\.ssh-pageant-USER1'; export SSH_AUTH_SOCK;
SSH_PAGEANT_PID=714; export SSH_PAGEANT_PID;
echo ssh-pageant pid 714;
> $env:SSH_AUTH_SOCK='C:\Users\USER1\tmp\.ssh-pageant-USER1'
> $env:SSH_PAGEANT_PID=714
> ssh myserver
Enter passphrase for key 'C:\Users\USER1/.ssh/id_rsa':
As an alternative workaround, is there a non-admin (I wouldn't want to interfere with it) way to load keys into a separate agent such that when I start a PS session it uses those other keys, and which allows me to keep working with my reused keys in msys2?
This would perhaps amount to using a two different agents at the same time...
weasel-pageant is such a proxy agent (based on Cygwin's ssh-pageant), for WSL (A1-C7)... still looking for a solution for PS.
ssh-agent-wsl
is a fork of weasel-pageant that includes support for using keys held by Microsoft's SSH Agent service (instead of PuTTY Pageant) (A2-C7... I guess it's remarkable that WSL needs a proxy to use Win OpenSSH agent).
Example on how to use "Proxy" agent ssh-pageant to link PuTTY pageant with Cygwin bash
The steps to achieve this are:
When I start my session in Windows, the portable PuTTY agent (pageant) is executed, loading at the same time one key.
For this, a shortcut pageant is added to C:\Users\USER1\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup, pointing at %myputty%\pageant.exe "%mykeys%\key1.ppk".
This makes the key usable by PuTTY and WinSCP, e.g.
But if I now enter a PS session, or an msys2/cygwin terminal, the keys would not be used, and I am asked for the password for the keys.
So if I now
$ ssh myserver
Enter passphrase for key 'C:\Users\USER1/.ssh/id_rsa':
In msys2/cygwin I can use ssh-pageant ("An SSH authentication agent for Cygwin/MSYS that links OpenSSH to PuTTY's Pageant"), such that it reuses whatever keys a previously loaded PuTTY agent has.
For this purpose, I simply add eval $(/usr/bin/ssh-pageant -r -a "/tmp/.ssh-pageant-$USERNAME") to my ~/.bashrc of msys2.
Now whenever I start an msys2 terminal, the link PuTTY's Pageant -> ssh-pageant is established, a couple of environment variables are created, and I can ssh without entering the password
$ env | grep -i ssh
SSH_AUTH_SOCK=/tmp/.ssh-pageant-USER1
SSH_PAGEANT_PID=960
$ ssh myserver
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-40-generic x86_64)
...
Judging from this, it seems the same can be achieved for Git bash.
Related:
http://rabexc.org/posts/pitfalls-of-ssh-agents
How to check if ssh-agent is already running in bash?
https://superuser.com/questions/1327633/how-to-maintain-ssh-agent-login-session-with-windows-10s-new-openssh-and-powers
https://superuser.com/questions/1293725/gpg-agent-under-windows-as-ssh-agent-for-git-bash
I made this work, using the same Cygwin tools (i.e., both ssh-pageant and Cygwin OpenSSH client) in a PS session.
So I would do (assuming ssh-pageant is already running from Msys2):
> cd <dir where ssh-pageant is>
> .\ssh-pageant -r -a "$env:USERPROFILE\tmp\.ssh-pageant-$env:USERNAME"
SSH_AUTH_SOCK='C:\Users\USER1\tmp\.ssh-pageant-USER1'; export SSH_AUTH_SOCK;
> $env:SSH_AUTH_SOCK='C:\Users\USER1\tmp\.ssh-pageant-USER1'
> .\ssh myserver
Logged in to myserver
I have added this to my profile.ps1 (again, it will work when ssh-pageant is already running when I start the PS session)
$env:MSYS2_DIR=<mydir>
# Assuming a proxy ssh agent is already running
$env:SSH_AUTH_SOCK="$env:MSYS2_DIR\tmp\.ssh-pageant-$env:USERNAME"
# We have to make sure we use Msys2 OpenSSH ssh client, not Windows OpenSSH ssh client
function ssh_msys2 {
& $env:MSYS2_DIR\usr\bin\ssh.exe $args
}
If an ssh-pageant is not yet active, this should work (not tested yet; the PID number may be different):
> cd <dir where ssh-pageant is>
> .\ssh-pageant -r -a "$env:USERPROFILE\tmp\.ssh-pageant-$env:USERNAME"
SSH_AUTH_SOCK='C:\Users\USER1\tmp\.ssh-pageant-USER1'; export SSH_AUTH_SOCK;
SSH_PAGEANT_PID=714; export SSH_PAGEANT_PID;
echo ssh-pageant pid 714;
> $env:SSH_AUTH_SOCK='C:\Users\USER1\tmp\.ssh-pageant-USER1'
> $env:SSH_PAGEANT_PID=714
> .\ssh myserver
Logged in to myserver
Still have to test a couple of points, and automate the operation.
In particular, executing ssh-pageant, detecting the PID # if it is returned, and setting environment variable SSH_PAGEANT_PID from PS if that is the case.
This is a little bit more cumbersome than in Msys2, since ssh-pageant spits something directly executable by bash.

Using Plink to change configs on multiple cisco switches

I have a PS script right now that lets me log into a range of switches one after another.
70..80 | % { plink "172.16.15.$_" -l enterusername -pw enterpassword}
This allows me to start at switch ending in .70 and once I am done and type exit, it automatically logs into the next one in sequence.
I want to create a text file that contains the changes I want to make to the running-config on the switch, such as maybe adding a user to 100 or so switches. How can I add to the PS script to make it so that it applies the changes to the config contained in the created text file? I am trying to automate changes to 100 edge switches vs having to type the config into each switch.
Or instead of pointing to a text file, can I somehow add the changes for the switch config right into the PS script?
When in doubt, read the documentation (emphasis mine):
7.2 Using Plink
This section describes the basics of how to use Plink for interactive logins and for automated processes.
Once you've got a console window to type into, you can just type plink on its own to bring up a usage message. This tells you the version of Plink you're using, and gives you a brief summary of how to use Plink:
Z:\sysosd>plink
PuTTY Link: command-line connection utility
Release 0.53
Usage: plink [options] [user#]host [command]
("host" can also be a PuTTY saved session name)
Options:
-v show verbose messages
-load sessname Load settings from saved session
-ssh -telnet -rlogin -raw
force use of a particular protocol (default SSH)
-P port connect to specified port
-l user connect with specified username
-m file read remote command(s) from file
-batch disable all interactive prompts
So all you need to do is create your command file, and add it to the commandline:
70..80 | ForEach-Object {
plink "172.16.15.$_" -l enterusername -pw enterpassword -m 'C:\commands.txt'
}

Send command to Putty (Windows) [duplicate]

I have a scenario where I need to run a linux shell command frequently (with different filenames) from windows. I am using PuTTY and WinSCP to do that (requires login name and password). The file is copied to a predefined folder in the linux machine through WinSCP and then the command is run from PuTTY. Is there a way by which I can automate this through a program. Ideally I would like to right click the file from windows and issue the command which would copy the file to remote machine and run the predefined command (in PuTTy) with the filename as argument.
Putty usually comes with the "plink" utility.
This is essentially the "ssh" command line command implemented as a windows .exe.
It pretty well documented in the putty manual under "Using the command line tool plink".
You just need to wrap a command like:
plink root#myserver /etc/backups/do-backup.sh
in a .bat script.
You can also use common shell constructs, like semicolons to execute multiple commands. e.g:
plink read#myhost ls -lrt /home/read/files;/etc/backups/do-backup.sh
There could be security issues with common methods for auto-login.
One of the most easiest ways is documented below:
Running Putty from the Windows Command Line
And as for the part the executes the command
In putty UI, Connection>SSH> there's a field for remote command.
4.17 The SSH panel
The SSH panel allows you to configure
options that only apply to SSH
sessions.
4.17.1 Executing a specific command on the server
In SSH, you don't have to run a
general shell session on the server.
Instead, you can choose to run a
single specific command (such as a
mail user agent, for example). If you
want to do this, enter the command in
the "Remote command" box.
http://the.earth.li/~sgtatham/putty/0.53/htmldoc/Chapter4.html
in short, your answers might just as well be similar to the text below:
let Putty run command in remote server
You can write a TCL script and establish SSH session to that Linux machine and issue commands automatically. Check http://wiki.tcl.tk/11542 for a short tutorial.
You can create a putty session, and auto load the script on the server, when starting the session:
putty -load "sessionName"
At remote command, point to the remote script.
You can do both tasks (the upload and the command execution) using WinSCP. Use WinSCP script like:
option batch abort
option confirm off
open your_session
put %1%
call script.sh
exit
Reference for the call command:
https://winscp.net/eng/docs/scriptcommand_call
Reference for the %1% syntax:
https://winscp.net/eng/docs/scripting#syntax
You can then run the script like:
winscp.exe /console /script=script_path\upload.txt /parameter file_to_upload.dat
Actually, you can put a shortcut to the above command to the Windows Explorer's Send To menu, so that you can then just right-click any file and go to the Send To > Upload using WinSCP and Execute Remote Command (=name of the shortcut).
For that, go to the folder %USERPROFILE%\SendTo and create a shortcut with the following target:
winscp_path\winscp.exe /console /script=script_path\upload.txt /parameter %1
See Creating entry in Explorer's "Send To" menu.
Here is a totally out of the box solution.
Install AutoHotKey (ahk)
Map the script to a key (e.g. F9)
In the ahk script,
a) Ftp the commands (.ksh) file to the linux machine
b) Use plink like below. Plink should be installed if you have putty.
plink sessionname -l username -pw password test.ksh
or
plink -ssh example.com -l username -pw password test.ksh
All the steps will be performed in sequence whenever you press F9 in windows.
Code:
using System;
using System.Diagnostics;
namespace playSound
{
class Program
{
public static void Main(string[] args)
{
Console.WriteLine(args[0]);
Process amixerMediaProcess = new Process();
amixerMediaProcess.StartInfo.CreateNoWindow = false;
amixerMediaProcess.StartInfo.UseShellExecute = false;
amixerMediaProcess.StartInfo.ErrorDialog = false;
amixerMediaProcess.StartInfo.RedirectStandardOutput = false;
amixerMediaProcess.StartInfo.RedirectStandardInput = false;
amixerMediaProcess.StartInfo.RedirectStandardError = false;
amixerMediaProcess.EnableRaisingEvents = true;
amixerMediaProcess.StartInfo.Arguments = string.Format("{0}","-ssh username#"+args[0]+" -pw password -m commands.txt");
amixerMediaProcess.StartInfo.FileName = "plink.exe";
amixerMediaProcess.Start();
Console.Write("Presskey to continue . . . ");
Console.ReadKey(true);
}
}
}
Sample commands.txt:
ps
Link: https://huseyincakir.wordpress.com/2015/08/27/send-commands-to-a-remote-device-over-puttyssh-putty-send-command-from-command-line/
Try MtPutty,
you can automate the ssh login in it. Its a great tool especially if you need to login to multiple servers many times. Try it here
Another tool worth trying is TeraTerm. Its really easy to use for the ssh automation stuff. You can get it here. But my favorite one is always MtPutty.
In case you are using Key based authentication, using saved Putty session seems to work great, for example to run a shell script on a remote server(In my case an ec2).Saved configuration will take care of authentication.
C:\Users> plink saved_putty_session_name path_to_shell_file/filename.sh
Please remember if you save your session with name like(user#hostname), this command would not work as it will be treated as part of the remote command.

Save PuTTY output to file from command-line

Is there any way to save the PuTTY output to a file using the command line? I know this is easily done using the GUI but in my case it has to be done automatically.
What I'm working on:
User clicks batch file -> starts PuTTY, automatically connects to my device over SSH and runs a bunch of commands -> PuTTY should save the output to a file.
The last part I can't get working. Is there any command to do this?
This can be done with putty. The answer is little late considering the time the questions was asked, however this might help someone.
In putty, using GUI, you can save sessions with logging option on, as shown below.
Enter Host Name, Name the session, Go to Logging Option in the left top corner, select all sessions, provide log file name and location, go back to Session tab, click on the save button. Done, you have saved a session.
Now open CMD and write the command as below
You are done. Every time this session is invoked, the commands and output will be logged.
Hope this helps.
The specific program putty is not designed for this. Instead use plink, a different program in the PuTTY suite,
which uses the same session settings and keys as putty but gets input from stdin and puts output to stdout,
both of which can be redirected in the usual ways. See http://the.earth.li/~sgtatham/putty/0.63/htmldoc/Chapter7.html#plink .
As mentioned in previous answer, use plink for this.
Make sure it is in your environment path, by typing
plink -V
in your console. If it returns a version number, then you know it is in environment path variables. If it doesn't, probably best to fix this first. There are plenty of good SO answers to help you with this. Failing that, use the full path to your plink.exe in the CLI command that follows.
Then use plink to open your ssh connection, with the option -v set to provide verbose output. Finally, this all needs to be piped to a log file.
The complete cli command that I use is
plink -v username#xxx.xxx.xxx.xxx > ssh-output.log 2>&1
Open up the file ssh-ouput.log to see the results.
Expanding on Dave's and Charlie's answers...
Apart from making sure plink is in the path, also check whether you have write access to local ouput file.
This is how you redirect command output from remote machine to local file with plink. In this example we store an output from man page for nfcapd:
plink joe#192.168.50.50 -pw joespassword man nfcapd > output.log 2>&1
The first time you try to access the server, it will ask you store key in cache. So make sure to access the machine at least once before:
plink joe#192.168.50.50 -pw joespassword
The server's host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
...
Store key in cache? (y/n)