# $language = "VBScript" # $interface = "1.0" ' ImportPuttyConnectionManagerInfoIntoSecureCRTSessions.vbs ' DESCRIPTION: ' ' ************************************************************** ' * NOTE: This script must be run from within SecureCRT. * ' ************************************************************** ' ' Imports PuttyCM session configurations into SecureCRT saved sessions. ' ' To ensure that any pre-existing sessions are not overwritten, duplicate ' imported sessions are saved with "(duplicate from PuttyCM)" appended ' to name ' ' --------------------------------------------------------------------- ' Last Modified: ' 22 Apr, 2020 ' - Removed unsupported Logon Actions import that will not work with ' SecureCRT. ' ' 29 Dec, 2016 ' - Some saved putty sessions might have characters that ' are not allowed in filenames. Added code to translate ' such session names to ones that will work for ' SecureCRT (function named GetSafeFilename). Set g_shell = CreateObject("WScript.Shell") Set g_fso = CreateObject("Scripting.FileSystemObject") Const ForReading = 1 Const ForWriting = 2 Const ForAppending = 8 g_strDesktop = g_shell.SpecialFolders("Desktop") Dim g_nSessionsCreated, g_strWarnings g_nSessionsCreated = 0 Dim g_colDuplicatesOfExistingSessions, g_colSessionsCreated Set g_colDuplicatesOfExistingSessions = CreateObject("Scripting.Dictionary") Set g_colSessionsCreated = CreateObject("Scripting.Dictionary") Dim g_vCommands(5) Sub Main() strPathToDataFile = _ crt.Dialog.FileOpenDialog( _ "Specify Path to existing putty CCM config file", _ "Import", _ g_strDesktop & "\*.dat", _ "DAT files (*.dat)|*.dat|XML files (*.xml)|*.xml||") If strPathToDataFile = "" Then Exit Sub ' Create an XML document object using Microsoft's building XMLDOM object: Set xmlDoc = CreateObject("Microsoft.XMLDOM") ' Instruct the XMLDOM object to be synchronous (wait for the XML file ' to be fully parsed prior to moving on with the script): xmlDoc.Async = False ' Now, actually load the contents of the XML file into the xmlDoc object xmlDoc.Load strPathToDataFile If xmlDoc.parseError.errorCode <> 0 Then crt.Dialog.MessageBox "A parsing error was detected while attempting to " & _ "read in the specified XML file: " & strPathToDataFile & _ vbcrlf & vbcrlf & _ "Error description: " & vbcrlf & xmlDoc.parseError.reason & vbcrlf & _ "This could mean that your XML file is saved with an encoding " & _ "that does not match the XML content-specified encoding. For " & _ "example, if your XML file were saved in ASCII format, but the " & _ "first line of the XML file said the following, then you would " & _ "need to either change the line in your XML file to reflect the " & _ "actual format of the file, or re-save the file in the format or " & _ "encoding specified on the line:" & vbcrlf & _ vbtab & "" Exit Sub End If ' XPath instruction to return all 'connection' nodes where the type is "PuTTY" strXPathQuery = "//connection[@type='PuTTY']" ' Get a list of all connections of type "PuTTY" in the XML doc Set objNodeList = xmlDoc.SelectNodes(strXPathQuery) If objNodeList.Length > 0 Then ' Iterate over each connection node and pull out the associated data For Each objNode in objNodeList ' Get the full path for the current session by walking up the ' XML tree, visiting each parent node until we reach the root ' node: strSessionPath = GetFullPathForNode(objNode) strProtocol = objNode.SelectNodes("connection_info/protocol")(0).Text strHost = objNode.SelectNodes("connection_info/host")(0).Text strPort = objNode.SelectNodes("connection_info/port")(0).Text ' Remove any spaces in folder path that would prevent nested ' folders from being created dynamically Set re = New regexp re.global = True re.pattern = "\s*\\\s*" strSessionPath = re.Replace(strSessionPath, "\") ' Remove initial backslash strSessionPath = Right(strSessionPath, Len(strSessionPath) - 2) ' Copy the default session settings into new session name and set the ' protocol. Setting protocol is essential since some variables ' within a config are only available with certain protocols. Set objConfig = crt.OpenSessionConfiguration("Default") objConfig.SetOption "Protocol Name", strProtocol ' Before saving a session to the existing configuration, find out if there ' is already an existing session with that same name. If there is, we'll ' append a tag to the session name: " - Imported from PuttyCM" so as to avoid ' wiping out any existing sessions that might already exist. On Error Resume Next Set objTosserConfig = crt.OpenSessionConfiguration(strSessionPath) nError = Err.Number strErr = Err.Description On Error Goto 0 ' We only used this to detect an error indicating non-existance of session. ' Let's get rid of the reference now since we won't be using it: Set objTosserConfig = Nothing ' If there wasn't any error opening the session, then it's a 100% indication ' that we should modify the session name so we can avoid wiping out any ' existing session information. If nError = 0 Then If g_colDuplicatesOfExistingSessions.Exists(strSessionPath) Then g_colDuplicatesOfExistingSessions(strSessionPath) = _ CInt(g_colDuplicatesOfExistingSessions(strSessionPath)) + 1 Else g_colDuplicatesOfExistingSessions.Add strSessionPath, 1 End If strSessionPath = strSessionPath & " (duplicate from PuttyCM)" End If ' Save the config, then reload it, so the protocol, if changed, is accurate. ' Setting protocol is essential since some variables within a config ' are only available with certain protocols. objConfig.Save GetSafeFilename(strSessionPath) ' Get a handle to new session config Set objConfig = crt.OpenSessionConfiguration(GetSafeFilename(strSessionPath)) objConfig.SetOption "Hostname", strHost ' Putty's default emulation configuration objConfig.SetOption "Emulation", "Xterm" objConfig.SetOption "ANSI Color", True Select Case LCase(strProtocol) Case "ssh" objConfig.SetOption "[SSH2] Port", cInt(strPort) Case "telnet" objConfig.SetOption "Port", cInt(strPort) End Select objConfig.Save GetSafeFilename(strSessionPath) On Error Resume Next g_colSessionsCreated.Add strSessionPath, 1 On Error Goto 0 g_nSessionsCreated = g_nSessionsCreated + 1 Next Else MsgBox "No connections found in XML file using path: " & vbcrlf & vbcrlf & _ strXPathQuery & _ vbcrlf & vbcrlf & _ "Are you sure the data file is an XML file from PuttyCM?" End If If g_colSessionsCreated.Count > 0 Then strSummaryMsg = _ "Successfully created " & g_colSessionsCreated.Count & _ " sessions" & vbcrlf If g_colDuplicatesOfExistingSessions.Count > 0 Then strSummaryMsg = strSummaryMsg & vbcrlf & vbcrlf & _ "Total of " & g_colDuplicatesOfExistingSessions.Count & _ " sessions already existed in SecureCRT prior to import." End If Else strSummaryMsg = _ "No PuttyCM session configurations were detected in the .xml file" & _ " you specified: " & strPathToDataFile End If crt.Dialog.MessageBox strSummaryMsg & vbcrlf & g_strWarnings ' Open up the Connect dialog automatically. crt.Screen.SendSpecial "MENU_TOGGLE_SESSION_MANAGER" End Sub '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Function CreateXMLDocObject(byRef objXMLDoc, byRef strInterface) g_strLastError = "" Dim nIndex ' Get the 2nd (0-based) element of the interface number ' MsgBox strInterface nIndex = split(strInterface, ".")(2) On Error Resume Next Err.Clear Set objXMLDoc = CreateObject("Msxml2.DOMDocument." & nIndex & ".0") if Err.Number <> 0 then if nIndex < 2 then g_strLastError = "Error creating xml DOM object(" & strInterface & "): " & Err.Description On Error Goto 0 exit Function else strInterface = "Msxml2.DOMDocument." & nIndex - 1 & ".0" CreateXMLDocObject = CreateXMLDocObject(objXMLDoc, strInterface) On Error Goto 0 exit function end if end if On Error Goto 0 CreateXMLDocObject = True End Function '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Function GetFullPathForNode(objNode) Set objNodeCopy = objNode x = 0 strNodePath = "" Do While Not objNodeCopy Is Nothing ' Get the node's name, but be cautious since ' a node might not have a "name" attribute (like ' the root 'configuration' node) 'stop On Error Resume Next strCurName = objNodeCopy.getAttribute("name") nError = Err.Number strErr = Err.Description On Error Goto 0 ' If there's an error, we probably just reached ' the node that doesn't have a name, and we're done If nError <> 0 Then Exit Do On Error Resume Next strType = objNodeCopy.getAttribute("type") On Error Goto 0 If strType = "database" Then Exit Do ' Otherwise, start building upon the path strNodePath = "\" & strCurName & strNodePath ' Now, replace the node copy with its parent, and then ' loop up to the top again Set objNodeCopy = objNodeCopy.parentNode Loop GetFullPathForNode = strNodePath End Function '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Function GetSafeFilename(strName) ' Replace any illegal characters that might have been introduced by the ' command we are running or the date. Since Python can run on multiple ' platforms, replace illegal characters for all platforms. ' We exclude these next two because they are used to indicate nested session folders 'strName = Replace(strName, "/", "[SLASH]") 'strName = Replace(strName, "\", "[BKSLASH]") strName = Replace(strName, ":", "-") strName = Replace(strName, ":", "[COLON]") strName = Replace(strName, "*", "[STAR]") strName = Replace(strName, "?", "[QUESTION]") strName = Replace(strName, """", "[QUOTE]") strName = Replace(strName, "<", "[LT]") strName = Replace(strName, ">", "[GT]") strName = Replace(strName, "|", "[PIPE]") GetSafeFilename = strName End Function