VanDyke Software Forums

VanDyke Software Forums (https://forums.vandyke.com/index.php)
-   Scripting (https://forums.vandyke.com/forumdisplay.php?f=14)
-   -   VB Script to automate deploying RSA (https://forums.vandyke.com/showthread.php?t=13932)

mmckeehan 10-11-2019 02:48 PM

VB Script to automate deploying RSA
 
Hello,

I am attempting to deploy RSA keys across around 4000 servers for my account, however they do exist on some servers already. I have a script that will deploy them if they did not exist already (below):

Code:

#$language = "VBScript"
#$interface = "1.0"
' the above tells the system what language and interface version we are using
'
'The below tells the system to keep the commands and the screen results in sync and start the script
'
crt.Screen.Synchronous = True

Sub Main

' this section sets the variables for reading the server list from a file
'

Dim fso, file, str
  Set fso = CreateObject("Scripting.FileSystemObject")

  ' Note: A runtime exception will be generated if 'UnlockHosts.txt' doesn't exist.
  ' the below sets the location for the hostfile
  '
  Set file = fso.OpenTextFile("C:\Hostfiles\scphosts.txt")

  crt.Screen.Synchronous = True

  Do While file.AtEndOfStream <> True

    str = file.Readline

    ' the below will send the commands shown and send the line with an appended CR
    ' note the wait for system prompt between each command this is required or the script will run to fast and not execute commands properly on the servers.

    ' check the failed login and reset then set the password, unlock the password then set it temp
    ' just edit the user ID
    '
    crt.Screen.Send "ssh -n -q " & str & " 'mkdir .ssh'" &chr(13)
        crt.Screen.WaitForString "sword:"
    crt.Screen.Send "password" &chr(13)
    crt.Screen.WaitForString "$"
    crt.Screen.Send "scp /local_home/uname/.ssh/authorized_keys uname@" & str & ":/local_home/uname/.ssh/authorized_keys" &chr(13)
        crt.Screen.WaitForString "sword:"
    crt.Screen.Send "password" &chr(13)
    crt.Screen.WaitForString "$"

        Loop
        End Sub

The servers are on saved to a .txt file that we are importing. When the keys are on a server, we get a message "File exist" To get around this I tried the below but keep getting an error:

Code:

#$language = "VBScript"
#$interface = "1.0"
' the above tells the system what language and interface version we are using
'
'The below tells the system to keep the commands and the screen results in sync and start the script
'
crt.Screen.Synchronous = True

Sub Main

' this section sets the variables for reading the server list from a file
'

Dim fso, file, str, result
        'Creates an array of the outcomes'
        result = Array ("File exists", _
                                        "sword:")

  Set fso = CreateObject("Scripting.FileSystemObject")

  ' Note: A runtime exception will be generated if 'UnlockHosts.txt' doesn't exist.
  ' the below sets the location for the hostfile
  '
  Set file = fso.OpenTextFile("C:\Hostfiles\scphosts.txt")

  crt.Screen.Synchronous = True

  Do While file.AtEndOfStream <> True

    str = file.Readline
       
  nResult = crt.Screen.WaitForString (result, 30)

    ' the below will send the commands shown and send the line with an appended CR
    ' note the wait for system prompt between each command this is required or the script will run to fast and not execute commands properly on the servers.

    ' check the failed login and reset then set the password, unlock the password then set it temp
    ' just edit the user ID
    '
    crt.Screen.Send "ssh -n -q " & str & " 'mkdir .ssh'" &chr(13)
        Select Case nResult
                Case 1
                        'File Exist:  This will loop the process'
                        crt.Screen.Send "ssh -n -q " & str & " 'mkdir .ssh'" &chr(13)
       
                Case 2
                        'Asking for password: this will continue the process'
                        crt.Screen.Send "password" &chr(13)
                        crt.Screen.WaitForString "$"
                        crt.Screen.Send "scp /local_home/uname/.ssh/authorized_keys uname@" & str & ":/local_home/uname/.ssh/authorized_keys" &chr(13)
                        crt.Screen.WaitForString "sword:"
                        crt.Screen.Send "password" &chr(13)
                        crt.Screen.WaitForString "$"
                End Select
               
Loop               
End Sub


My thought was to create an array of different returns from the servers because and set a 30 second timer because sometimes there could just not be a response from the server.

ashiosee 10-11-2019 05:40 PM

Quote:

Originally Posted by mmckeehan (Post 52435)
... I tried... but keep getting an error:

You did not include any details about the error, but I can only imagine that you meant to call WaitForStrings() (multiple of string) instead of WaitForString() (singular of string).

If you call WaitForStrings() instead of WaitForString(), do you get better behavior?

If making that singular change doesn't resolve the problem, would you be so kind as to provide details about the error message(s) you see?

mmckeehan 10-16-2019 02:51 PM

Quote:

...If you call WaitForStrings() instead of WaitForString(), do you get better behavior?
I was getting the error for using "WaitForString()". Making it plural did fix that issue, but came across another.

When running the script, Case 1 is working perfectly fine. When I come across a server where I need a password, it will not go directly to Case 2, but stop. I get a return of:

$ ssh -n -q SERVER1 'mkdir .ssh'
mkdir: cannot create directory ‘.ssh’: File exists
$ ssh -n -q SERVER2 'mkdir .ssh'
mkdir: cannot create directory ‘.ssh’: File exists
$ ssh -n -q SERVER3 'mkdir .ssh'
mkdir: cannot create directory ‘.ssh’: File exists
$ ssh -n -q SERVER4 'mkdir .ssh'
Enter Active Directory (US) Password:

I am wanting this to be essentially automated so I can run without any interaction

ashiosee 10-16-2019 06:10 PM

Hi mmckeehan,

I'm not sure I have your current script code, but if it's anything like the prior script code you shared, I think you have an ordering problem. You're waiting for the results of the 'ssh' command before you've even sent the 'ssh' command.

Code:

  Set file = fso.OpenTextFile("C:\Hostfiles\scphosts.txt")

  crt.Screen.Synchronous = True

  Do While file.AtEndOfStream <> True

    str = file.Readline
   
  nResult = crt.Screen.WaitForStrings (result, 30)

    ' the below will send the commands shown and send the line with an appended CR
    ' note the wait for system prompt between each command this is required or the script will run to fast and not execute commands properly on the servers.

    ' check the failed login and reset then set the password, unlock the password then set it temp
    ' just edit the user ID
    '
    crt.Screen.Send "ssh -n -q " & str & " 'mkdir .ssh'" &chr(13)
    Select Case nResult
          Case 1
              'File Exist:  This will loop the process'
              crt.Screen.Send "ssh -n -q " & str & " 'mkdir .ssh'" &chr(13)
   
          Case 2
              'Asking for password: this will continue the process'
              crt.Screen.Send "password" &chr(13)
              crt.Screen.WaitForString "$"
              crt.Screen.Send "scp /local_home/uname/.ssh/authorized_keys uname@" & str & ":/local_home/uname/.ssh/authorized_keys" &chr(13)
              crt.Screen.WaitForString "sword:"
              crt.Screen.Send "password" &chr(13)
              crt.Screen.WaitForString "$"
          End Select
         
Loop

In general, it's not going to work if you first wait for a response to a command that you have not yet sent.

One fix would be to move your WaitForStrings() call down to the line AFTER the line where the prerequisite ssh command has been sent. For example:
Code:

  Set file = fso.OpenTextFile("C:\Hostfiles\scphosts.txt")

  crt.Screen.Synchronous = True

  Do While file.AtEndOfStream <> True

    str = file.Readline
   
    ' the below will send the commands shown and send the line with an appended CR
    ' note the wait for system prompt between each command this is required or the script will run to fast and not execute commands properly on the servers.

    ' check the failed login and reset then set the password, unlock the password then set it temp
    ' just edit the user ID
    '
    crt.Screen.Send "ssh -n -q " & str & " 'mkdir .ssh'" &chr(13)

  nResult = crt.Screen.WaitForStrings (result, 30)
    Select Case nResult
          Case 1
              'File Exist:  This will loop the process'
              crt.Screen.Send "ssh -n -q " & str & " 'mkdir .ssh'" &chr(13)
   
          Case 2
              'Asking for password: this will continue the process'
              crt.Screen.Send "password" &chr(13)
              crt.Screen.WaitForString "$"
              crt.Screen.Send "scp /local_home/uname/.ssh/authorized_keys uname@" & str & ":/local_home/uname/.ssh/authorized_keys" &chr(13)
              crt.Screen.WaitForString "sword:"
              crt.Screen.Send "password" &chr(13)
              crt.Screen.WaitForString "$"
          End Select
         
Loop

Note that I've highlighted the timeout parameter (30) for your attention. Your scenario doesn't warrant the use of any timeout parameters -- after all, you're not even handling the case where WaitForStrings() times out.

If you feel you must keep the time out in place, you should at least add a Case 0 statement and corresponding block aimed to help you bail -- if that's what you want to do. For example:

Code:

          Case 0
              ' Timed out waiting for one of our strings. Gotta bail.
              crt.Dialog.MessageBox "Timed out waiting for one of our strings. Stopping the script before things get worse."
              Exit Sub



All times are GMT -6. The time now is 05:51 AM.