View Single Post
  #3  
Old 07-27-2018, 01:46 AM
Rainer Rainer is offline
Registered User
 
Join Date: Jul 2018
Posts: 3
Lightbulb

I found out, that the script is waiting for a promt or the readline command cant read the current line.

Here is the functioning Code, its a little bit messy
Code:
# $language = "VBScript"
# $interface = "1.0"


Set g_fso = CreateObject("Scripting.FileSystemObject")
Set g_shell = CreateObject("WScript.Shell")
path = g_fso.GetParentFolderName(crt.ScriptFullName)
g_strHostsFile = path & "\##hosts.txt"
g_strCommandsFile = path & "\##commands.txt"
g_strMyDocs = path
g_strLogFileTemplate = _
    g_strMyDocs & "\Log\##IPADDRESS-COMMAND-YYYY-MM-DD--hh'mm'ss'.txt"

g_bLogToIndividualFilesPerHost = True
g_bLogToIndividualFilesPerCommand = False

g_strLogFileTemplate = Replace(g_strLogFileTemplate, "YYYY-", Year(Date) & "-")
g_strLogFileTemplate = Replace(g_strLogFileTemplate, "-MM-", "-" & NN(Month(Date)) & "-")
g_strLogFileTemplate = Replace(g_strLogFileTemplate, "-DD-", "-" & NN(Day(Date)) & "-")
g_strLogFileTemplate = Replace(g_strLogFileTemplate, "-hh'", "-" & NN(Hour(Time)) & "'")
g_strLogFileTemplate = Replace(g_strLogFileTemplate, "'mm'", "'" & NN(Minute(Time)) & "'")
g_strLogFileTemplate = Replace(g_strLogFileTemplate, "'ss", "'" & NN(Second(Time)))

g_strFirewall = ""
g_strComment = "#"
g_strError = ""
Const ForReading   = 1
Const ForWriting   = 2
Const ForAppending = 8

Const strZahl = 1
Const contZahl = 5
Dim g_objNewTab, g_strHost

Dim g_bUseExistingSessions
g_bUseExistingSessions = False

g_strUsername = "username"
g_strPassword = "password"

MainSub
Sub MainSub()
 Dim vHosts(), vCommands()
 Dim nHostCount, nCommandCount, nCommentLines
 Dim nanswer
 nanswer = msgbox("This will skip the read in form the hosts file!" & vbcr & _
                  "The command file will still be read!", vbYesNo , "manual input?")

 if nanswer = vbYes Then
    inputhost = InputBox(_
    "Please specify the hosts to connect:", _
    "Target Host?", _
    "10.16.16.10;10.16.16.20")
    vHost = Split(inputhost,";")
    nHostCount = UBound(vhost)+1
 else
 If Not ReadDataFromFile(g_strHostsFile, _
			g_strComment, _
			vHosts, _
			nHostCount, _
			nCommentLines) Then
 crt.Dialog.MessageBox g_strError
 Exit Sub
 End If
 End If

 Dim strErrors, strSuccesses
    if nanswer = vbNo Then
    If Not g_fso.FileExists(g_strCommandsFile) Then
        strError = "WARNING: Default commands file does not contain any " & _
            "commands: " & g_strCommandsFile & "." & vbcrlf & _
            "Any lines in the hosts file which don't include a " & _
            "commands file specification will fail."
        strErrors = CaptureError(strErrors, strError)
        DisplayMessage inputhost
    End If
    End If

    For nIndex = 0 To nHostCount - 1
      if nanswer = vbYes Then
        g_strHost = vHost(nIndex)
      else
        g_strHost = vHosts(nIndex)
      end If
        If g_strHost = "" Then Exit For

        strCommandsFilename = ""
        bContinue = True

        If Instr(g_strHost, ";") > 0 Then
            vHostElems = Split(g_strHost, ";")
            g_strHost = vHostElems(0)
            strCommandsFilename = vHostElems(1)
            If strCommandsFilename = "" Then
                strCommandsFilename = g_strCommandsFile
            End If

            If Not g_fso.FileExists(strCommandsFilename) Then
                strCommandsFilename = g_fso.GetParentFolderName(g_strHostsFile) & "\" & strCommandsFilename
                If Not g_fso.FileExists(strCommandsFilename) Then
                    strError = "Host-specific command file not found for host '" & g_strHost & _
                        "': " & strCommandsFilename
                    strErrors = CaptureError(strErrors, strError)
                    bContinue = False
                End If
            End If

            If bContinue Then
                g_strError = ""
                If Not ReadDataFromFile(strCommandsFilename, _
                    g_strComment, _
                    vCommands, _
                    nCommandCount, _
                    nCommentLines) Then

                    strError = "Error attempting to read host-specific file for host '" & _
                            g_strHost & "': " & g_strError
                    strErrors = CaptureError(strErrors, strError)
                    bContinue = False
                End If
            End If
        Else
            If Not ReadDataFromFile(g_strCommandsFile, _
                                    g_strComment, _
                                    vCommands, _
                                    nCommandCount, _
                                    nCommentLines) Then
                strError = "While working on host '" & g_strHost & "... " & g_strError
                strErrors = CaptureError(strErrors, strError)
                bContinue = False
            End If
        End If

        If bContinue Then
            If g_bUseExistingSessions Then
                strConnectString = "/S " & g_strHost
            Else
                 strConnectString = _
                    g_strFirewall & _
                    " /SSH2 " & _
                    " /L " & g_strUsername & _
                    " /AUTH password,keyboard-interactive /PASSWORD " & g_strPassword & _
                    " " & g_strHost
            End If

            If Not Connect(strConnectString) Then
                strError = "Failed to connect to " & g_strHost & _
                            ": " & g_strError
                strErrors = CaptureError(strErrors, strError)
            Else

                g_objNewTab.Screen.Synchronous = True
                g_objNewTab.Screen.IgnoreEscape = True

                If Not WaitForScreenContentsToStopChanging(350) Then
                    strError = "Error: " & _
                        "Failed to detect remote ready status for host: " & _
                        g_strHost & ".  " & g_strError
                    strErrors = CaptureError(strErrors, strError)
					Else
					nRow = g_objNewTab.Screen.CurrentRow
                    strPrompt = g_objNewTab.screen.Get(nRow, _
                                               0, _
                                               nRow, _
                                               g_objNewTab.Screen.CurrentColumn)
                    strPrompt = Trim(strPrompt)

                    For Each strCommand In vCommands
					If strCommand = "" Then Exit For

							g_objNewTab.Screen.Send strCommand
							g_objNewTab.Screen.Send vbCr
							if InStr(1, strCommand, "arch", vbTextCompare) = 1 then
							g_objNewTab.Screen.WaitForString(strPrompt)
							End If
							if InStr(1, strCommand, "conf t", vbTextCompare) & InStr(1, strCommand, "wr", vbTextCompare) = 1 Then
							g_objNewTab.Screen.WaitForString(strCommand)
							if InStr(1, strCommand, "wr", vbTextCompare) = 1 then
							g_objNewTab.Screen.WaitForString(strPrompt)
							End If
							End if

						vWaitFors = Array(vbcr, vblf)
                        bFoundEOLMarker = False
                        Do
                            g_objNewTab.Screen.WaitForStrings vWaitFors, 1

                            Select Case g_objNewTab.Screen.MatchIndex
                                Case 0
                                    Exit Do

                                Case 1,2
                                    If bFoundEOLMarker Then Exit Do

                                    bFoundEOLMarker = True
                            End Select
                        Loop

                        Dim strResult
						if InStr(1, strCommand, "sis", vbTextCompare) = 1 Then
                        strResult = g_objNewTab.Screen.ReadString(strPrompt)
						End If
						if InStr(1, strCommand, "sh", vbTextCompare) = 1 Then
						strResult = g_objNewTab.Screen.ReadString(strPrompt)
						End If

                        Dim objFile, strLogFile

                        If g_bLogToIndividualFilesPerHost Then
                            strLogFile = Replace( _
                                g_strLogFileTemplate, _
                                "IPADDRESS", _
                                g_objNewTab.Session.RemoteAddress)
                        Else
                            strLogFile = Replace( _
                                g_strLogFileTemplate, _
                                "IPADDRESS", _
                                "ALLHOSTS")
                        End If

                        If Instr(strLogFile, "COMMAND") Then
                            If g_bLogToIndividualFilesPerCommand Then
                                strCleanCmd = Replace(strCleanCmd, "|", "[PIPE]")
                                strLogFile = Replace(strLogFile, "COMMAND", strCleanCmd)
                            Else
                                strLogFile = Replace(strLogFile, "COMMAND", "ALLCMDS")
                            End If
                        End If

                        strParentFolder = g_fso.GetParentFolderName(strLogFile)
                        If Not g_fso.FolderExists(strParentFolder) Then
                            If Not CreateFolderTree(strParentFolder) Then
                                strErrors = CaptureError(strErrors, _
                                    "Failed to create folder '" & _
                                    strParentFolder & "' for logging " & _
                                    "results of command '" & strCommand & _
                                    "'.")
                            End If
                        End If


                        Set objFile = g_fso.OpenTextFile(strLogFile, ForAppending, True)
                        If Err.Number <> 0 Then
                            strError = "Failed to open '" & _
                                strLogFile & "' for writing results of " & _
                                "'" & strCommand & "' command: " & Err.Description
                            strErrors = CaptureError(strErrors, strError)
                        Else
                            objFile.WriteLine String(80, "=") & vbcrlf & _
                                "Results of command """ & strCommand & _
                                """ sent to host """ & g_strHost & """:" & vbcrlf & _
                                String(80, "-")
                            objFile.WriteLine strResult
                            If Err.Number <> 0 Then
                                strError = "Failed to write results to " & _
                                    "log file (" & strLogFile & "): " & _
                                    Err.Description
                                strErrors = CaptureError(strErrors, strError)
                            End If
                            ' Close the log file
                            objFile.Close
                        End If
                        On Error Goto 0
                    Next
                    Do
                        g_objNewTab.Session.Disconnect
                        crt.Sleep(100)
                    Loop While g_objNewTab.Session.Connected

                    strSuccesses = strSuccesses & vbcrlf & g_strHost
                End If
            End If
        End If
    Next


		strMsg = "Commands were sent to the following hosts: " & _
        vbcrlf & strSuccesses

    If strErrors <> "" Then
        strMsg = strMsg & vbcrlf & vbcrlf & _
        "Errors encountered include:" & _
        vbcrlf & strErrors
    End If

    DisplayMessage strMsg
    If strErrors <> "" Then
        If crt.Dialog.MessageBox("Would you like these errors copied to the clipboard?", "Copy to Clipboard?", vbyesNo) = vbYes Then
            crt.Clipboard.Text = strErrors
        End If
    End If
End Sub

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Function ReadDataFromFile(strFile, _
                          strComment, _
                          ByRef vLines, _
                          ByRef nLineCount, _
                          ByRef nCommentLines)
    If Not g_fso.FileExists(strFile) Then
        g_strError = "ReadDataFromFromFile: File not found: " & strFile
        Exit Function
    End If

    On Error Resume Next
    ' Open a TextStream Object to the file...
    Set objTextStream = g_fso.OpenTextFile(strFile, 1, False, 0)
    nError = Err.Number
    strErr = Err.Description
    On Error Goto 0

    If nError <> 0 Then
        g_strError = "ReadDataFromFile: Error opening file for reading (" & _
            nError & "): " & strErr & vbcrlf & vbtab & strFile
        Exit Function
    End If

    Set objFFile = g_fso.GetFile(strFile)
    If objFFile.Size < 1 Then
        g_strError = "ReadDataFromFile: File is empty: " & strFile
        ReadDataFromFile = False
        Exit Function
    End If

    ' Attempt to determine file encoding
    b1 = objTextStream.Read(1)
    objTextStream.Close

    ' Re-open the file using the proper encoding
    nVal = ASC(b1)
    Select Case nVal
        Case 255 ' Unicode
            Set objTextStream = g_fso.OpenTextFile(strFile, 1, False, -1)

        Case 239
            g_strError = "ReadDataFromFile: 'UTF-8' File type is not supported." & _
                "File must be saved in Unicode or ANSI format." & vbcrlf & _
                vbtab & strFile
            Exit Function

        Case 254 ' Unicode BE
            g_strError = "ReadDataFromFile: 'Unicode BE' File type is not supported." & _
                "File must be saved in Unicode or ANSI format." & vbcrlf & _
                vbtab & strFile
            Exit Function

        Case Else ' Regular ASCII/ANSI
            Set objTextStream = g_fso.OpenTextFile(strFile, 1, False, 0)
    End Select

    ' Start of with a reasonable size for the array:
    ReDim vLines(5)


    ' Used for detecting comment lines, a regular expression object
    Set re = New RegExp
    re.Pattern = "(^[ \t]*(?:" & strComment & ")+.*$)|(^[ \t]+$)|(^$)"
    re.Multiline = False
    re.IgnoreCase = False

    ' Now read in each line of the file and add an element to
    ' the array for each line that isn't just spaces...
    nLineCount = 0
    nCommentLines = 0

    Do While Not objTextStream.AtEndOfStream
        strLine = ""

        ' Find out if we need to make our array bigger yet
        ' to accommodate all the lines in the file.  For large
        ' files, this can be very memory-intensive.
        If UBound(vLines) >= nLineCount Then
            ReDim Preserve vLines(nLineCount + 5)
        End If

        strLine = Trim(objTextStream.ReadLine)

        ' Look for comment lines that match the pattern
        '   [whitespace][strComment]
        If re.Test(strLine) Then
            ' Line matches our comment pattern... ignore it
            nCommentLines = nCommentLines + 1
        Else
            vLines(nLineCount) = strLine
            nLineCount = nLineCount + 1
        End If
    Loop

    objTextStream.Close

    If nLineCount < 1 Then
        g_strError = "ReadDataFromFile: No valid lines found in file: " & strFile
        ReadDataFromFile = False
        Exit Function
    End If

    ReadDataFromFile = True
End Function

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Function Connect(strConnectInfo)
    bWaitForAuthToCompleteBeforeReturning = False
    bLetCallerDetectAndHandleConnectionErrors = True
    Set g_objNewTab = crt.Session.ConnectInTab( _
        strConnectInfo, _
        bWaitForAuthToCompleteBeforeReturning, _
        bLetCallerDetectAndHandleConnectionErrors)

    If g_objNewTab.Session.Connected <> True Then
        If crt.GetLastErrorMessage = "" Then
            g_strError = "Unknown error"
        Else
            g_strError = crt.GetLastErrorMessage
        End If
        If g_objNewTab.Index <> crt.GetScriptTab().Index Then g_objNewTab.Close

        Exit Function
    End If
    g_objNewTab.Screen.Synchronous = True

    nAuthTimeout = 1000  ' seconds

    vPossibleShellPrompts = Array(_
        "ogin:", _
        "name:", _
        "sword:", _
        "Login incorrect", _
        "authentication failed.", _
        "$", _
        "#", _
        ">")

    bSendUsername = True
    bSendPassword = True
    If SessionExists(g_strHost) Then
        Set objConfig = crt.OpenSessionConfiguration(g_strHost)
        If objConfig.GetOption("Use Login Script") = True Then
            bSendUsername = False
            bSendPassword = False
        End If

        If objConfig.GetOption("Session Password Saved") = True Then
            bSendPassword = False
        End If

        If objConfig.GetOption("Username") <> "" Then
            bSendUsername = False
        End If
    End If

    Do
        On Error Resume Next
        g_objNewTab.Screen.WaitForStrings vPossibleShellPrompts, nAuthTimeout
        nError = Err.Number
        strErr = Err.Description
        On Error Goto 0
        If nError <> 0 Then
            g_strError = Err.Description

            Do
                g_objNewTab.Session.Disconnect
                crt.Sleep 100
            Loop While g_objNewTab.Session.Connected

            Exit Function
        End If
        Select Case g_objNewTab.Screen.MatchIndex
            Case 0
                g_strError = "Authentication timed out!" & vbcrlf & _
                    "(Or you forgot to add a case for a successful shell " & _
                    "prompt in the vPossibleShellPrompts array)"
                ' Disconnect from the host so that we can reuse the disconnected
                ' tab for the next connection in the loop
                Do
                    g_objNewTab.Session.Disconnect
                    crt.Sleep 100
                Loop While g_objNewTab.Session.Connected

                Exit Function

            Case 1' "ogin:"
                If bSendUsername Then
                    If crt.Screen.CurrentColumn <= Len("Login: ") Then
                        g_objNewTab.Screen.Send g_strUsername & vbcr
                    End If
                End If


            Case 2' "name:"
                If bSendUsername Then
                    If crt.Screen.CurrentColumn <= Len("Username: ") Then
                        g_objNewTab.Screen.Send g_strUsername & vbcr
                    End If
                End If

            Case 3 ' "sword:"
                If bSendPassword Then
                    ' Send the password... but ONLY if the cursor position
                    ' makes sense (If "Password:" shows up on the screen,
                    ' anywhere but as the left-most word on the line, ignore
                    ' it, so that we don't send the password command)
                    If crt.Screen.CurrentColumn <= Len("Password: ") Then
                        g_objNewTab.Screen.Send g_strPassword & vbcr
                    End If
                End If

            Case 4,5 ' "Login incorrect", "authentication failed."
                g_strError = _
                    "Password authentication to '" & g_strHost & "' as user '" & _
                    g_strUsername & "' failed." & vbcrlf & vbcrlf & _
                    "Please specify the correct password for user " & _
                    "'" & g_strUsername & "'"

                Do
                    g_objNewTab.Session.Disconnect
                    crt.Sleep 100
                Loop While g_objNewTab.Session.Connected

                Exit Function

            Case 6,7,8 ' "$", "#", or ">" <-- Shell prompt means auth success
                g_objNewTab.Session.SetStatusText _
                    "Connected to " & g_strHost & " as " & g_strUsername
                Exit Do

            Case Else
                g_strError = _
                    "Ooops! Looks like you forgot to add code " & _
                    "to handle this index: " & g_objNewTab.Screen.MatchIndex & _
                    vbcrlf & _
                    vbcrlf & _
                    "Modify your script code's ""Select Case"" block " & _
                    "to have 'Case' statements for all of the strings you " & _
                    "are passing to the ""WaitForStrings"" method."

                Do
                    g_objNewTab.Session.Disconnect
                    crt.Sleep 100
                Loop While g_objNewTab.Session.Connected

                Exit Function
        End Select
    Loop


    Connect = True
End Function

' -----------------------------------------------------------------------------
Function CaptureError(strErrors, strError)
    If strErrors = "" Then
        strErrors = strError
    Else
        If Right(strErrors, 2) <> vbcrlf Then
            strErrors = strErrors & vbcrlf & strError
        Else
            strErrors = strErrors & strError
        End If
    End If

    strLogFile = g_strLogFileTemplate
    If Instr(strLogFile, "IPADDRESS") > 0 Then
        strLogFile = Replace(strLogFile, "IPADDRESS", "All(Errors)")
    Else
        strLogFile = g_fso.GetParentFolderName(strLogFile) & "\" & _
            "All(Errors)" + g_fso.GetFileName(strLogFile)
    End If
    strLogFile = Replace(strLogFile, "COMMAND", "")

    strParentFolder = g_fso.GetParentFolderName(strLogFile)
    If Not g_fso.FolderExists(strParentFolder) Then
        CreateFolderTree(strParentFolder)
    End If

    On Error Resume Next
    Set objFile = g_fso.OpenTextFile(strLogFile, ForAppending, True)
    If Err.Number <> 0 Then
        If Instr(strError, "Failed to open") = 0 And _
           Instr(strError, "Failed to write") = 0 And _
           Instr(strError, "Failed to create") = 0 Then
            strAdditionalErrors = "Error opening log file (" & strLogFile & _
                ") for writing: " & Err.Description
        End If
    Else
        Err.Clear
        objFile.WriteLine String(80, "=") & vbcrlf & strError & vbcrlf
        If Err.Number <> 0 Then
            strAdditionalErrors = "Error writing to log file (" & strLogFile & _
                "): " & Err.Description
        End If
    End If
    On Error Goto 0

    If strAdditionalErrors <> "" Then
        strErrors = strErrors & vbcrlf & vbtab & strAdditionalErrors
    End If

    CaptureError = strErrors
End Function

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Function CreateFolderTree(szFolderPath)
 On Error Resume Next

    if g_fso.FolderExists(szFolderPath) then
        CreateFolderTree = False
        exit function
    end if

    Do
        Err.Clear
        g_fso.CreateFolder szFolderPath
        If Err.Number <> 0 then
            if Err.Number <> 70 Then
                Err.Clear
                CreateFolderTree(g_fso.GetParentFolderName(szFolderPath))
            Else
                CreateFolderTree = False
                Exit Function
            End If
        Else
            Exit do
        end if
    Loop

    CreateFolderTree = True

 On Error Goto 0
End Function

' -----------------------------------------------------------------------------
Function WaitForScreenContentsToStopChanging(nMsDataReceiveWindow)

    bOrig = g_objNewTab.Screen.Synchronous

    g_objNewTab.Screen.Synchronous = False

    On Error Resume Next
        strLastScreen = g_objNewTab.Screen.Get(1,1,g_objNewTab.Screen.Rows,g_objNewTab.Screen.Columns)
        nError = Err.Number
        strErr = Err.Description
    On Error Goto 0
    If nError <> 0 Then
        g_strError = strErr
        Exit Function
    End If
    Do
        crt.Sleep nMsDataReceiveWindow

        ' Be "safe" about trying to access Screen.Get().  If for any reason we
        ' get disconnected, we don't want the script to error out on the problem
        ' so we'll just return false and handle writing something to our log
        ' file for this host.
        On Error Resume Next
            strNewScreen = g_objNewTab.Screen.Get(1,1,g_objNewTab.Screen.Rows, g_objNewTab.Screen.Columns)
            nError = Err.Number
            strErr = Err.Description
        On Error Goto 0
        If nError <> 0 Then
            g_strError = strErr
            Exit Function
        End If

        If strNewScreen = strLastScreen Then Exit Do

        strLastScreen = strNewScreen
    Loop

    WaitForScreenContentsToStopChanging = True
    ' Restore the Synch setting
    g_objNewTab.Screen.Synchronous = bOrig
End Function


'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Function NN(nNumber)
 ' Normalizes a single digit number into a double-digit number with a leading 0
    If Len(nNumber) < 2 Then nNumber = "0" & nNumber
    NN = nNumber
End Function

'-------------------------------------------------------------------------------
Function PromptYesNo(strText)
    PromptYesNo = crt.Dialog.MessageBox(strText, "SecureCRT", vbYesNo)
End Function

'-------------------------------------------------------------------------------
Function DisplayMessage(strText)
    crt.Dialog.MessageBox strText
End Function

'-------------------------------------------------------------------------------
Function SessionExists(strSessionPath)
 ' Returns True if a session specified as value for strSessionPath already
 ' exists within the SecureCRT configuration.
 ' Returns False otherwise.
    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, it's a 100% indication
    ' that the session named in strSessionPath already exists
    If nError = 0 Then
        SessionExists = True
    Else
        SessionExists = False
    End If
End Function
Reply With Quote