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.

Update: A more recent article exists about opening PuTTY sessions and sending commands.

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

Recent Articles

Top Commenters

Recent Comments