' IterateOverAllSessionRecursively_ConfFileOutputFormat.vbs ' ' Last Modified: ' 11 Dec, 2019 ' - Initial revision. ' ' Description: ' ' Shows how to iterate over all sessions in SecureCRT's session manager, and ' perform some custom action on that data. The example reads specific data ' from each session configuration and writes it to file formatted for .conf ' or Windows INI format (with the section heading being the "folder"). The ' format of the output file will follow this pattern: ' [folder_#1_name] ' session_#1_hostname ' session_#2_hostname ' session_#3_hostname ' . ' . ' . ' ' [folder_#2_name] ' session_#1_hostname ' session_#2_hostname ' session_#3_hostname ' . ' . ' . ' This script also illustrates how to use the VBScript built-in Shell ' and File System objects, as well as SecureCRT's SessionConfiguration object ' and how to create functions. ' ' This script must be run from within SecureCRT. Dim g_shell Set g_shell = CreateObject("WScript.Shell") Dim g_fso Set g_fso = CreateObject("Scripting.FileSystemObject") Const ForReading = 1 Const ForWriting = 2 Const ForAppending = 8 Dim g_strOutputFile, g_objLogFile g_strOutputFile = _ g_shell.SpecialFolders("MyDocuments") & "\IterationOutputFile.ini" If g_fso.FileExists(g_strOutputFile) Then If g_fso.FileExists(g_strOutputFile & ".bak") Then g_fso.DeleteFile g_strOutputFile & ".bak" End If g_fso.CopyFile g_strOutputFile, g_strOutputFile & ".bak" g_fso.DeleteFile g_strOutputFile End If Dim g_strConfigFolder, g_strSessionFolder, g_nSessionCount Dim g_cFolders Set g_cFolders = CreateObject("Scripting.Dictionary") '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sub Main() nStartTime = Timer ' Get SecureCRT's configuration folder path g_strConfigFolder = g_shell.ExpandEnvironmentStrings(GetConfigPath()) ' Get the Sessions folder path g_strSessionFolder = _ g_fso.GetAbsolutePathName(g_strConfigFolder & "\Sessions\") IterateOverFilesInFolder g_strSessionFolder IterateOverFolder g_strSessionFolder ' Now that we're done iterating over all sessions, let's work ' through the collection of folders that was populated and output ' the data to our file. For Each strFolder In g_cFolders.Keys() WriteToFile "[" & strFolder & "]", g_strOutputFile Set cFolder = g_cFolders(strFolder) Set cSessionsWritten = CreateObject("Scripting.Dictionary") For Each strSessionPath In cFolder.Keys() crt.Session.SetStatusText strSessionPath Set cSession = cFolder(strSessionPath) strHostname = cSession("Hostname") ' Only write out session host info if it's not blank If strHostname <> "" Then ' Don't write out duplicates within the same folder ' (copies of sessions can exist with different session ' names in the same folder) If Not cSessionsWritten.Exists(strHostname) Then WriteToFile strHostname, g_strOutputFile cSessionsWritten.Add strHostname, "" End If End If Next cSessionsWritten.RemoveAll WriteToFile vbcrlf, g_strOutputFile Next crt.Session.SetStatusText "" MsgBox "Finished iterating over " & g_nSessionCount & _ " sessions in " & Round(Timer - nStartTime, 2) & " seconds." g_shell.Run "explorer.exe /e,/select," & Chr(34) & g_strOutputFile & Chr(34) End Sub '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sub IterateOverFolder(strPath) Dim objFolder, objSubFolder, colFolders, strCurPath Set objFolder = g_fso.GetFolder(strPath) 'MsgBox "Processing " & objFolder Set colFolders = objFolder.SubFolders For Each objSubFolder In colFolders strCurPath = strPath & "\" & objSubFolder.name 'MsgBox "Processing folder: " & strCurPath IterateOverFilesInFolder strCurPath IterateOverFolder strCurPath Next End Sub '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sub IterateOverFilesInFolder(strPath) Dim colFiles, objFolder, objFile, strFilename, strSessionName Set objFolder = g_fso.GetFolder(strPath) Set colFiles = objFolder.Files For Each objFile In colFiles If objFile.Name <> "__FolderData__.ini" And _ objFile.Name <> "Default.ini" And _ LCase(g_fso.GetExtensionName(objFile.Path)) = "ini" Then g_nSessionCount = g_nSessionCount + 1 strFilename = strPath & "\" & objFile.Name ' Now iterate over each session. We need the path relative to ' Sessions so GetBaseName isn't enough; need to trim everything out ' of path through the ...\Sessions\, so compare to ' g_strSessionFolder. Dim nSessionLength nSessionLength = Len(strFilename) - Len(g_strSessionFolder) strSessionName = Right(strFilename, nSessionLength) ' Convert backslashes to forward slashes strSessionName = Replace(strSessionName, "\", "/") DoWorkWithSession strSessionName End If Next End Sub '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sub DoWorkWithSession(strSession) Dim objSessionConfig, strHostname, strProtocol, strEmulation, strDescription strPathToSecureCRT = g_strInstallFolder strSession = Replace(strSession, ".ini", "") ' Ignore errors to bypass failure to connect popup windows On Error Resume Next ' Open the session's config file Set objSessionConfig = crt.OpenSessionConfiguration(strSession) ' Get the specific data from session ini file ' Add or remove variables according to the information you want to extract ' from .ini files. If you visually inspect a .ini file you should be able ' to determine the parameter name to use with GetOption. For example, ' you would see the following in a .ini file for an SSH2 session: ' S:"Protocol Name"=SSH2 ' The parameter you provide to GetOption below would be "Protocol Name" ' if you wanted to know the protocol the session uses ' ' We quote all of the values in case they have commas or linefeeds (as ' in the case of the description, particularly) strFolder = g_fso.GetParentFolderName(strSession) strSessionName = g_fso.GetFileName(strSession) strSessionPath = """" & strSession & """" strHostname = objSessionConfig.GetOption("Hostname") strProtocol = objSessionConfig.GetOption("Protocol Name") strEmulation = objSessionConfig.GetOption("Emulation") strDescription = _ """" & Join(objSessionConfig.GetOption("Description"), vblf) & """" ' If g_bAttemptSSHConnections is True, and it's an SSH2 connection ' attempt to connect to the remote host and get the server's ident ' string. If the connection fails, write NO_RESPONSE in that field ' instead. If the protocol isn't SSH2, then write NOT_APPLICABLE ' in that field instead. crt.Session.SetStatusText "Protocol: <" & strProtocol & ">" crt.Session.SetStatusText "" ' Disable on error resume next On Error Goto 0 ' For each session's information, Add it to a collection of sessions ' belonging to a folder. If strFolder = "" or strFolder = "\" Then strFolder = "__Uncategorized__" End If ' Strip the leading slash or backslash character if it's present. If Left(strFolder, 1) = "/" or Left(strFolder, 1) = "\" Then strFolder = Mid(strFolder, 2) End If ' Get a reference to the existing folder if we've already seen it. If g_cFolders.Exists(strFolder) Then Set cSessions = g_cFolders(strFolder) Else ' Otherwise, let's create a new folder collection so we can ' begin adding session references to it. Set cSessions = CreateObject("Scripting.Dictionary") End If ' Collect the session data into a dictionary object that ' we'll add to our sessions collection (which is a collection of ' that we have found in the current folder) Set cSession = CreateObject("Scripting.Dictionary") cSession.Add "Folder", strFolder cSession.Add "Name", strSessionName cSession.Add "Path", strSessionPath cSession.Add "Hostname", strHostname cSession.Add "Protocol", strProtocol cSession.Add "Emulation", strEmulation cSession.Add "Description", strDescription ' Add the session to our collection of sessions cSessions.Add strSessionPath, cSession ' Now, add the collection of sessions back into (or for the first ' time) the folders collection, under the current folder's name: Set g_cFolders(strFolder) = cSessions End Sub '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sub WriteToFile(strText, strFilePath) Set objFile = g_fso.OpenTextFile(strFilePath, ForAppending, True) objFile.WriteLine strText objFile.Close End Sub ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Function GetConfigPath() ' Try and get at where your configuration folder is located strOptionName = "Upload Directory V2" strOrigValue = crt.Session.Config.GetOption(strOptionName) crt.Session.Config.SetOption strOptionName, "${VDS_CONFIG_PATH}" ' Make the change, so that the above templated name will get written ' to the config... crt.Session.Config.Save ' Now, load a fresh copy of the config, and pull the option... so ' that SecureCRT will convert from the template path value to the ' actual path value: Set objConfig = crt.OpenSessionConfiguration(crt.Session.Path) strConfigPath = objConfig.GetOption(strOptionName) ' Now, let's restore the setting to its original value crt.Session.Config.SetOption strOptionName, strOrigValue crt.Session.Config.Save ' Now return the config path GetConfigPath = strConfigPath End Function