PuTTY automatic logon script: LogonPutty

Recently I found myself using putty quite often. I needed to connect to different servers in order to open log files. Opening all log files on all servers was a tedious task as it required me to connect with Putty to each machine. Next I had to navigate to the log by typing the tail command and the correct log path. By creating a simple autoit tool I managed to automate this boring task which is making life much easier for everyone in our team needing access to log files.

The script interacts with Putty via the GUI. Several ways to drive GUI exist, like using the component coordinates, interacting with the controls themselves or sending keystrokes. I opted for sending key strokes as this approach requires very litle change to the configuration file if a new version of putty would implement some GUI changes. There's one drawback though. Blindlessley sending keystroke commands without implementing synchronization can lead to unexpected results :-)

Like for many other scripts I have used AutoIt to write the script. I just love AutoIt and it's my most preferable scripting language after Ruby. In order to run the script you need to download AutoIt. You can download the latest version from http://www.autoitscript.com/. Pick "AutoIt Full Installation" which includes ScITE, an excellent AutoIt editor providing syntax highlighting, autocompletion, and more.


How it works

Functionally

The user can identify several environments which each can have multiple servers. For each server a corresponding session exists in Putty and allows the user to connect to that server. The script launches a putty instance for each session, connects to the server and executes the commands related to the environment. Within a same environment the path to logfiles is usually the same, but accross environments differences can easily exist.

This enables the user to easily connect to all servers on environment TEST for instance. Every log file of the application on that environment is opened by executing the commands related to the environment.


Technically

The script reads the configuration and launches Putty. When the Putty window appears, it navigates to the "Saved Sessions" list and selects a session according to the selected environment(s). For each session in the selected environment a new Putty instance is launched. Every command belonging to the environment of the server/session is executed.

Putty is launched:

Putty window

The first item in the session list is selected:

Putty window first session selected

The session is selected:

Putty window correct session selected

Username/password information is entered and commands are being executed:

Putty connected to prompt


Preparation of the script

The putty logon script consists out of two main files:



A configuration file (.ini)
The script file (.au3)
These files need to be created manually by copying and pasting the code below.


The configuration file

Create a file "logonPutty.ini" and add following code to it:

[launch]
#possible values: TEST,PREPROD
selectedEnvironments=TEST

[common]
#The full path of putty, including the executable name
puttyLocation=D:\machtst\My Documents\Tools\putty.exe
#The username to authenticate with
puttyUsername=yourusername
#The password to authenticate with
puttyPassword=yourpassword
#The title of the Putty window
puttyWindowTitle=PuTTY Configuration
#The number of seconds to wait for the Putty window after launching putty
puttyWindowCheckTimeout=5
#The send key commands to navigate to the saved sessions list
defaultCommands={TAB 4}{DOWN 1}
#The send key command ending the input
commandEnter={ENTER}
#The delimiter to seperate the commands in the command section with
commanddelimiter=;
#The amount of milliseconds to wait after sending commands
inputInterval=600
#The delay in between the keystrokes
sendKeyDelay=15

#The environment section: each environment together with their (putty) sessions
[environments]
TEST=bravo2,tapir
PREPROD=bravo8,panda

#The session section: each session with the send key command to access them,
#...relative to first item in the saved session list
[sessions]
alpha2={DOWN 1}
bravo2={DOWN 2}
bravo8={DOWN 3}
panda={DOWN 4}
tapir={DOWN 5}

#The command section: each environment with the commands to send for all (putty) sessions on the environment
[commands]
TEST=pwd;tail -2000lf domain-home/test/logging/nef-oracle.log
PREPROD=tail -2000lf domain-home/preprod/logging/nef-oracle.log

The script file

Create a file "logonPutty.au3" and add following code to it:

;----------------------- TESTINGMINDED -----------------------
;- Automatic Putty logon script from www.testingminded.com ---
;-------------------- DECLARATION SECTION --------------------

#include 

Global $Paused
HotKeySet("{PAUSE}", "TogglePause")
HotKeySet("{ESC}", "Terminate")

$scriptName = StringLeft(@ScriptName, StringLen(@ScriptName) - 4)
$iniLocation = @ScriptDir & '\' & $scriptName & '.ini'
If not(FileExists($iniLocation)) Then
MsgBox(0, "Exception", "The configuration file could not be found: " & $iniLocation)
exit
EndIf

$puttyLocation = IniRead($iniLocation, "common", "puttyLocation", "NotFound")
$puttyUsername = IniRead($iniLocation, "common", "puttyUsername", "NotFound")
$puttyPassword = IniRead($iniLocation, "common", "puttyPassword", "NotFound")
$defaultCommands = IniRead($iniLocation, "common", "defaultCommands", "NotFound")
$commandEnter = IniRead($iniLocation, "common", "commandEnter", "NotFound")
$inputInterval = IniRead($iniLocation, "common", "inputInterval", "NotFound")
$sendKeyDelay = IniRead($iniLocation, "common", "sendKeyDelay", "NotFound")
$commanddelimiter = IniRead($iniLocation, "common", "commanddelimiter", "NotFound")
$puttyWindowTitle = IniRead($iniLocation, "common", "puttyWindowTitle", "NotFound")
$puttyWindowCheckTimeout = IniRead($iniLocation, "common", "puttyWindowCheckTimeout", "NotFound")

$selectedSessions = _arraycreate("","","","","","","","","","","")
$selectedSessionCommands = _arraycreate("","","","","","","","","","","")
$commands = _arraycreate("","","","","","","","","","","")

$selectedEnvironments = IniRead($iniLocation, "launch", "selectedEnvironments", "NotFound")
$selectedSessions = _getsessions($selectedEnvironments)

; ------------------------------------------------------------------------------
; MAIN
; ------------------------------------------------------------------------------

$selectedSessionCommands = _getSelectedSessionCommands($selectedSessions)
$commands = _getCommands($selectedSessions)

Opt("SendKeyDelay", $sendKeyDelay)

for $i = 1 to UBound($selectedSessionCommands) - 1
Run($puttyLocation, "", @SW_MAXIMIZE)
if not (FileExists($puttyLocation)) Then
msgbox(0,"","The putty exe could not be found at location " & $puttyLocation)
Exit
EndIf

if WinWaitActive($puttyWindowTitle, "", $puttyWindowCheckTimeout) then
sleep(1000)
send ($defaultCommands)
Send ($selectedSessionCommands[$i])
send($commandEnter)

sleep($inputInterval)
if not($puttyUsername) = "" Then
Send ($puttyUsername)
send ($commandEnter)
sleep($inputInterval)
EndIf

sleep($inputInterval)
if not($puttyPassword) = "" Then
Send ($puttyPassword)
send ($commandEnter)
sleep($inputInterval)
EndIf

$commandArray = $commands[$i]
for $commandId = 1 to Ubound($commandArray) - 1
send($commandArray[$commandId])
send($commandEnter)
Next

Else
msgbox(0,"","The putty window with title " & $puttyWindowTitle & " could not be find within the foreseen timeframe")
Exit
EndIf
next

; ------------------------------------------------------------------------------
; FUNCTIONS
; ------------------------------------------------------------------------------

Func _getSelectedSessionCommands($selectedSessions)
redim $selectedSessionCommands [ubound($selectedSessions)]
$selectedSessionCommands[0] = ubound($selectedSessions)

for $i = 1 to ubound($selectedSessions) - 1
$session = $selectedSessions[$i]
$selectedSessionCommands[$i] = IniRead($iniLocation, "sessions", $session[0], "NotFound")

if $selectedSessionCommands[$i] == "NotFound" Then
MsgBox(0, "Exception", "Could not find session " & $selectedSessionCommands[$i] & " in the configuration file")
exit
EndIf

Next
return $selectedSessionCommands
EndFunc

Func _getsessions($selectedEnvironments)
$selectedEnvironments =  StringSplit($selectedEnvironments, ",")
$sessionNumber = 0

for $i = 1 to ubound($selectedEnvironments) - 1
$tempSessions = IniRead($iniLocation, "environments", $selectedEnvironments[$i], "NotFound")
if $tempSessions == "NotFound" Then
MsgBox(0, "Exception", "Could not find environment " & $selectedEnvironments[$i] & " in the configuration file")
exit
EndIf

$tempSessions = StringSplit($tempSessions, ",")

for $j = 1 to ubound($tempSessions) - 1
$sessionNumber = $sessionNumber + 1
$selectedSessions[$sessionNumber] = _arraycreate($tempSessions[$j],$selectedEnvironments[$i])
next

Next

redim $selectedSessions [$sessionNumber + 1]
$selectedSessions[0] = ubound($selectedSessions)
return $selectedSessions

EndFunc


Func _getCommands($selectedSessions)
redim $commands [ubound($selectedSessions)]
$commands[0] = ubound($selectedSessions)

for $i = 1 to ubound($selectedSessions) - 1
$session = $selectedSessions[$i]
$commandString = IniRead($iniLocation, "commands", $session[1], "NotFound")
$commands[$i] = stringsplit($commandString, $commanddelimiter)

if $selectedSessionCommands[$i] == "NotFound" Then
MsgBox(0, "Exception", "Could not find command " & $commands[$i] & " in the configuration file")
exit
EndIf

Next
return $commands
EndFunc

Func TogglePause()
$Paused = NOT $Paused
While $Paused
sleep(100)
ToolTip('Script is "Paused"',0,0)
WEnd
ToolTip("")
EndFunc

Func Terminate()
Exit 0
EndFunc

Configuration and proof running the script

Open the configuration file and update parameter puttyLocation with the location of Putty, including the file name of the Putty executable. Change parameters puttyUsername and puttyPassword into the username and password you need to connect to the servers with Putty.

Define the environments in the [environments] section. Add server names after each of the environments. The names don't have to match the name of the stored Putty sessions. Next add each server name to the [sessions] section as parameter name and add the {DOWN 1} command as value. The number indicates the order of the stored Putty session, after the first "Default settings" items. Finally add the environments to the [command] section. For each environment, fill in the commands you want PuttyLogon to execute on the servers. You can use multiple commands by seperating them with the command seperator, which is ";" by default.

Before running the script, update the "selectedEnvironments" parameter in the [launch] section. You can specify multiple environments. Run the script by opening it with the SciTE editor and pressing F5 or by creating and running the executable.

Related Posts by Categories

Comments

23 Responses to "PuTTY automatic logon script: LogonPutty"

myT said... October 11, 2009 at 2:15 PM

This can be usefull in some situations, but I think I would still prefer to install Samba and use BareTail or LogExpert to navigate through large log files instead ;). With Samba you can use these scripts instead: http://mytselection.blogspot.com/2009/03/baretail-easy-scripted-usage.html

Steven Machtelinckx said... October 12, 2009 at 8:10 AM

I prefer to use BareTail or Hoo Wintail as well, but unfortunately our client doesn't provide windows access to the log files.
Though, I find your script very interesting. Anyone having windows access to log files I would certainly advise to try it out.

Anonymous said... December 4, 2009 at 1:57 AM

SSH.. What about using ssh keys?

Steven Machtelinckx said... December 4, 2009 at 7:38 AM

Using SSH keys should not be any problem. I think putting the 'puttyUsername' and 'puttyPassword' parameters in the configuration file to '' should to the trick. In that case LogonPutty shouldn't send try to send the username/password.

Anonymous said... February 1, 2010 at 9:40 PM

I want to call this au file from DTS package on SQL Server. I'm able to manually run the exe from DTS package but when DTS is scheduled as a job, this exe file is getting stuck with no error.

I did comment all the message boxes in the code.

Any idea why it is happening?

Steven Machtelinckx said... February 2, 2010 at 7:55 AM

Personally I don't have any experience with DTS packages, nor with SQL Server.
I recommend adding logging to the autoit script in order to debug. You should be able to get any output like that. If not, then the exe can't be called at all. Can you tell if that worked?

Anonymous said... January 25, 2011 at 6:38 PM

Have you tried using Plink instead? It can be used in fully automated ways and also in semi-automated ways. Seems more straightforward than all this glue.

Anonymous said... March 14, 2011 at 8:12 PM

What is the reference to ARRAY.AU3? Is that a separate file?

Steven Machtelinckx said... May 24, 2011 at 11:52 AM

Thanks for the Plink suggestion.

Anonymous said... August 10, 2011 at 7:31 PM

Will this close after execution, or is there any way to make this work so you will be left at a command prompt?

Anonymous said... August 29, 2011 at 2:44 PM

I'm having problems if the password have characters like @ or |. Any idea about how to solve this? I can't change the password...
Thank's in advance.

Anonymous said... November 20, 2011 at 1:06 PM

Hi All,
I'm new in IT and my Boss assign me Backup task,there more then 100's of cisco asa and pix firewall's and i have to take manually backup for all the firewall can any one help me out how this script running.currently i'm using putty to login the device and manually click on change setting and then select saved all session out put and then run the command sh run for the backup i want it run automatic at night.any suggestion please help me guys....

Thank's in Advance

Vikram Koushik said... November 24, 2011 at 8:38 AM

Is there any Script to Shutdown my network switch or firewall from remote location

Anonymous said... June 4, 2012 at 8:31 PM

Hi nice script :D
how to show log Tunnelier (Bitvise) to my GUI ?

Software Testing Class said... June 19, 2012 at 8:47 PM

You are doing excellent job, cleared some basic tips on PuTTY. You can get info on Software Testing Tools List as well with some guidelines with different way of thinking.

Dani Rubio said... July 2, 2012 at 4:37 AM
This comment has been removed by the author.
Dani Rubio said... July 2, 2012 at 4:39 AM

Line 162 in logonPutty.au3 wich says "< /array.au3>" NOT NEEDED (can't compile if present)
Correct that please.
Thank you.
Nice post anyway.

SoftwareQATestings.com said... December 5, 2012 at 12:40 PM

Real nice article on putty. Also check more about free software testing tools here
Free list of Software Testing Tools

TestWithUs said... May 7, 2013 at 6:18 AM

SWIFT Interview questions on

http://testwithus.blogspot.in/p/swift.htm

For selenium solution visit
http://testwithus.blogspot.in/p/blog-page.html


For QTP interview questions

http://testwithus.blogspot.in/p/qtp-questions.html


www.searchyourpolicy.com




Sebastian Bärgård said... May 16, 2013 at 6:27 PM

How do you send this as a command: "ps -ef | grep -i "

#The command section: each environment with the commands to send for all (putty) sessions on the environment
[commands]
server="ps -ef | grep -i ";

Sebastian Bärgård said... May 16, 2013 at 6:31 PM

How do I send the following command:
"ps -ef | grep -i ProcessName"?

The problem is that the command excludes the character '|' for some reason. Anyone know why?

#The command section: each environment with the commands to send for all (putty) sessions on the environment
[commands]
server="ps -ef | grep -i ProcessName";

zuvuya said... October 7, 2013 at 10:30 AM

This looks great. My first Autoit experiment.

on all compile/run attempts:

"Auto2Exe Error

Line 5 (path to logonputty.au3)

#include

Error: Cannot parse #include"

- line 5 just contains #include - what am i doing wrong?=

zuvuya said... October 7, 2013 at 10:36 AM

commenting out line 5 reveals that line 28 calls function array - including Array.au3 in line 5 produces,
"[...]
#include Array.au3

Error: Cannot parse #include"

Post a Comment

Recent Articles

Top Commenters

Recent Comments

Books