AutoHotkey: Launch putty or RDP sessions via a tree-driven selection menu

From TotalcmdWiki
Jump to: navigation, search

The following GUI (autohotkey script) is a standalone script that is useful for UNIX admins that need to administer dozens or more UNIX servers. Simply drop it into the same directory as where your PuTTY executable is and modify hostnames to suit your environment. Some might find it amateurish or not particularly well coded, but it works for me. If you have constructive or useful suggestions contact me: mrbinary but complaints or criticism of my coding end up in /dev/null.

IN the screenshot below, double-clicking on any of the leaf objects results in a putty session being launched to the specified UNIX server or an RDP session to the specified windows server.

screenshot: screenshot of PuTTY GUI navigation utility

In the UNIX environment at my workplace, we have several hundred UNIX hosts (by hostname at least), and of course it is not easy to remember the application that a given server is hosting. We make some limited use of DNS aliasing, and if you use Putty you can use profiles and choose an arbitrary name for the profile, but when I started learning AutoHotKey the tree-based GUI caught my attention as being really useful and well-suited to the task I wanted to accomplish. Our server names are very similar to the names in the script below, which of course are not descriptive at all, so key servers you generally get to know from memory, but infrequently accessed ones are easy to forget. Plus if somebody pages me at 03:00 (in the a.m.) and says "There's a problem with the webserver for the financial application", I don't want to have to think too hard what that is. Usually the person calling will know the actual name of the server, but just in case.

Since all of our servers have a relatively straightforward method of organization by name, it's easy to write a shell script to grab all of the names from DNS and then sort them by name prefix for use in this PuTTY utility. Actually, we have an internal wiki also powered by MediaWiki software that all of our hosts are listed on, and the function that the host provides. When we are installing a new host, one of the steps involved is to provide a short description of the nature of the host, and that gets populated into the wiki, so I simply harvest the name and the text description of the host's function from the wiki to populate this AutoHotKey script.

However, it can also be used to group servers that all perform a specific function. One application environment at my workplace requires 9 servers to provide all of the necessary portions of the application (2 databases, LDAP server, appserver, webserver etc.), and so I have a different version that has a heading for the 3 environment tiers (dev, Quality Assurance and production). Since that is 27 servers total, it's easy to forget which specific portion of the environment is hosted on which server name, and I don't want to ssh to 5 incorrect servers before hitting the correct one. Without too much modification this script will allow you to launch any Windows-based client program, but it is really useful for when you have dozens to hundreds of things to manage that use a common client program.

One of our application admins also needs to do RDP (windows remote desktop protocol) sessions to windows servers to administer some stuff, so I extended it to permit him to launch rdp to a specific server. I can't verify that the RDP portion works, because happily I don't need to deal with Windows as a server, I only need to use Windows on my work-provided desktop, hence I am a heavy user of AutoHotKey and Cygwin. I believe this script could be used to also launch Windows-based database client software to a specific database or something of that nature with little modification required.

AIX admins may recognize the portion of the script which allows you to organize server partitions by frame name rather than by application description. If anybody needs the AIX / HMC script that I use to generate the list of partitions, contact me directly. This is also a semi-manually maintained portion of the script, the list is generated on AIX and then copied and pasted into the .ahk script (or FTP if you have so many servers that a cut & paste is painful). I haven't gotten around to making the AIX scripts generate the entire .ahk script so that I can simply sftp it to my workstation, but one day...

You can actually extend this to enable putty to launch serial connections to AIX LPARs and I have that portion done as well. The only downside is that it does not close the terminal connection on the HMC cleanly so I haven't included that functionality on this page as yet. When (if?) I eventually get the chance to fix this bug / issue I will post the updated version.

I had to sanitize hostnames, serial numbers and such from the script, it's possible that I have mangled things a bit in the process. If so, please forgive me for the oversight. I have tested the version reproduced below and it seems to work. Hope somebody finds this script useful, if so, please send me mrbinary an email to let me know that my efforts didn't go to waste! Also, if you want the image that is in the screencap above on the lefthand side of the GUI contact me and I can send it to you. Finally, it looks best and most organized if you use a fixed-width font and try to line up all items consistently in a given branch of the tree.

; Uncomment the "FileInstall" line below if you want to include an image in a compiled AutoHotKey executable
; This makes the GUI look a little more polished and professional but in no way changes it's essential functionality

;FileInstall, globe_2b.jpg, globe_2b.jpg, 1

;================================================================================================================================
; First section simply checks if conf file for the utility exists and reads it's contents into variables
; If it doesn't exist it prompts users for the information and writes the values into the conf file
;================================================================================================================================

PuttyFound = false
RDPFound = false

IfExist, %A_WorkingDir%\puttytree_conf.txt
{
   PuttyFound = true
   FileReadLine, PuttyLoc, puttytree_conf.txt, 1
   FileReadLine, PrsnId, puttytree_conf.txt, 2
}

if PuttyFound != true
{
    MsgBox Please indicate location of Putty or program will not function correctly
    FileSelectFile, PuttyLoc, 1, %A_MyDocument%, Please indicate location of Putty or program will not function correctly, *.exe
    FileAppend, %PuttyLoc%`n, puttytree_conf.txt
    InputBox, vPrsnId, Please enter your UNIX userid
    FileAppend, %vPrsnId%, puttytree_conf.txt
    MsgBox The conf file with the location of putty and your userid has now been created.`n`nThe name of the file is puttytree_conf.txt and 

it can be found in the same directory as this utility.`n`nThe utility will now exit - please rerun it and it should no longer ask for the 

putty location or your userid.`nThis should also be the last time you see this message.
    ExitApp
}

IfExist, %A_WorkingDir%\RDPtree_conf.txt
{
   RDPFound = true
   FileReadLine, RDPLoc, RDPtree_conf.txt, 1
   FileReadLine, RrsnId, RDPtree_conf.txt, 2
   ;MsgBox Found the conf file so value of PuttyFound is %RDPFound%
   ;MsgBox Putty location is %RDPLoc% User ID is %RrsnId%
}

if RDPFound != true
{
    MsgBox Please indicate location of AutoRDP or program will not function correctly
    FileSelectFile, RDPLoc, 1, %A_MyDocument%, Please indicate location of AutoRDP or program will not function correctly, *.exe
    FileAppend, %RDPLoc%`n, RDPtree_conf.txt
    InputBox, vRrsnId, Please enter your wintel domain userid
    FileAppend, %vRrsnId%, RDPtree_conf.txt
    MsgBox The conf file with the location of putty and your userid has now been created.`n`nThe name of the file is RDPtree_conf.txt and it 

can be found in the same directory as this utility.`n`nThe utility will now exit - please rerun it and it should no longer ask for the putty 

location or your userid.`nThis should also be the last time you see this message.
    ExitApp
}

;================================================================================================================================

; Now to begin creating the actual GUI that the user will interact with

Gui, +Resize

Gui, Add, Picture,, %A_WorkingDir%\globe_2b.jpg

Gui, Font, s10, Lucida Console

Gui, Add, TreeView, ym r42 w500 Background33669F cWhite gSvr4Putty

svrs_by_name := TV_Add("Servers by name")
svrs_by_frame := TV_Add("Servers by frame")
rdp_svrs := TV_Add("Available RDP Sessions")

dev_svrs := TV_Add("DEV Servers", svrs_by_name)
qat_svrs := TV_Add("QAT Servers", svrs_by_name)
prd_svrs := TV_Add("PRD Servers", svrs_by_name)

;                             ------ This is the user-defined / arbitrary text that describes the function of the server
;                             |                               
;                             |                               ------ This is the value that will be used by putty for SSH or by RDP 
;                             |                               |
;                             \/                              \/

 PRD001 := TV_Add("Production WebServer #1 Application FOO : PRD001", prd_svrs)  ; parent is prd_svrs
 PRD002 := TV_Add("Production AppServer #1 Application BAR : PRD002", prd_svrs)  ; parent is prd_svrs
 QAT001 := TV_Add("QA WebServer #1  Application FOOBAR     : QAT001", qat_svrs)  ; parent is qat_svrs
 QAT002 := TV_Add("QA AppServer #1  Application REBAR      : QAT002", qat_svrs)  ; parent is qat_svrs
 DEV001 := TV_Add("DEV WebServer #1 Application WebWhiz    : DEV001", dev_svrs)  ; parent is dev_svrs
 DEV002 := TV_Add("DEV Tomcat Application WebWhiz          : DEV002", dev_svrs)  ; parent is dev_svrs

9117_P6_570A_SN1091111 := TV_Add("9117_P6_570A_SN1091111", svrs_by_frame)
PRD001_LPAR := TV_Add("PRD001_LPAR      : PRD001", 9117_P6_570A_SN1091111)
PRD002_LPAR := TV_Add("PRD002_LPAR      : PRD002", 9117_P6_570A_SN1091111)

9117_P6_570B_SN1091112 := TV_Add("9117_P6_570B_SN1091112", svrs_by_frame)
DEV001_LPAR := TV_Add("DEV001_LPAR      : DEV001", 9117_P6_570B_SN1091112)
DEV002_LPAR := TV_Add("DEV002_LPAR      : DEV002", 9117_P6_570B_SN1091112)

9117_P6_570C_SN1091113 := TV_Add("9117_P6_570C_SN1091113", svrs_by_frame)
QAT001_LPAR := TV_Add("QAT001_LPAR      : QAT001", 9117_P6_570C_SN1091113)
QAT002_LPAR := TV_Add("QAT002_LPAR      : QAT002", 9117_P6_570C_SN1091113)

winhost001 := TV_Add("winhost001#junkyardAPP#RDP            : winhost001#junkyardAPP", rdp_svrs)


Gui, Show  ; Show the window and its TreeView.
return

Svr4Putty:

if A_GuiEvent = DoubleClick
{
   SelectedSvr := TV_GetSelection()
   ParentNumber := TV_GetParent(SelectedSvr)
   TV_GetText(TmpParentName, ParentNumber)
   StringReplace, ParentNameOfSelected, TmpParentName, #, -, All

   ;MsgBox %ParentNameOfSelected%
   
   TV_GetText(ItemText, SelectedSvr)

   ;MsgBox %ItemText%
   

   if ( InStr( ItemText, "RDP") != 0) {
       MsgBox RDP session selected
       

       StringSplit, StringRA, ItemText, `:

       ; var StringRA2 contains a leading space - next line of code removes it but changes the variable that will be used to _FinalSvrVar_
       StringReplace, FinalSvrVar, StringRA2, %A_Space%

       StringReplace, TmpRDPVar, FinalSvrVar, #RDP,

       StringReplace, RDPVar, TmpRDPVar, #, -

       MsgBox %RDPVar%

       ;Run %RDPLoc% "/v: %RDPVar%.yourcorp.com /u:%RrsnID%"

   }
   
   else {
       StringSplit, StringRA, ItemText, `:

       ; var StringRA2 contains a leading space - next line of code removes it but changes the variable that will be used to _FinalSvrVar_
       StringReplace, FinalSvrVar, StringRA2, %A_Space%

       Run %PuttyLoc% -load %FinalSvrVar%
   }
       

   ;StringSplit, StringRA, ItemText, `:
   
 
   ; var StringRA2 contains a leading space - next line of code removes it but changes the variable that will be used to _FinalSvrVar_
   ;StringReplace, FinalSvrVar, StringRA2, %A_Space%

   ;uncomment following line if you use PuTTY profiles and would like to launch a profile instead of a generic PuTTY session
   ;Run %PuttyLoc% -load %FinalSvrVar%

   ;comment out following line if you uncomment the line above to use putty with profiles instead of generic putty sessions
   ;Run %PuttyLoc% "%PrsnId%@%FinalSvrVar%.yourcorp.com"

}

return

GuiClose:  ; Exit the script when the user closes the TreeView's GUI window.
ExitApp

Back to AutoHotkey