'PowerShell script to SSH to Multiple Linux devices and restart/reboot them

I am comfortable with writing single queries. I am new to writing bash scripts trying to automate the daily stuff. I need help on creating a PowerShell or bash script where I can SSH to multiple Linux devices with same SSH key and then reboot the devices.

I access linux devices manually with the following command in PowerShell

ssh -i C:\<path-to-the-private-key\test.ppk [email protected] (X - IP Address)

Then I enter the following command

sudo reboot

It asks me to type the password and then restarts the device.

I have 100+ devices that I need to restart.

I can get a list of all IP address in a text file. How can we search for all the IP address in a text file, authenticate with the SSH private key and run the sudo command to restart the device?

Would it also be possible to throw a message if it was not able to restart a device?

Any help would be appreciated.


This is the script that I have.

testreboot.sh

#!/bin/bash

pw="test123"  
hosts='IP.txt'


while read -r line;  do {
    /usr/bin/expect << EOF  do
    ssh test@"$hosts" 'sudo reboot' 
    expect "*?assword*"
    send "%pw\r" 
EOF 
} 
    done < $hosts

IP.txt

XXX.XX.XX.XX 
XXX.XX.XX.XX
XXX.XX.XX.XX 
XXX.XX.XX.XX

I have Ubuntu 20.04 installed from Windows App Store. I am trying to run the testreboot.sh from PowerShell using the following command and get the following error message.

 bash testreboot.sh
testreboot.sh: line 2: $'\r': command not found
testreboot.sh: line 3: $'\r': command not found
testreboot.sh: line 5: $'\r': command not found
testreboot.sh: line 16: syntax error near unexpected token `done'
testreboot.sh: line 16: `done < $hosts'

enter image description here



Solution 1:[1]

A better solution to this problem is to use something like Ansible, Chef, or Puppet to solve these multi-server coordination needs.

Solution 2:[2]

Here is an example in a shell script using expect to ssh to another server and login:

NOTE: When you use expect in this manner, you need to escape " and $ and other items. If password has $, it must be escaped.

This is where after logging in and expect see a command prompt For example:

44 [localhost.localdomain]/home/map%

This is where you would need to add sudo reboot command

-re \"$reg_ex_prompt\" {
}

Test Script:

#!/bin/sh
#
debug=0
exit_val=0
spawn_item="ssh"
destination="user_name@<IP of server to shh>"
reg_ex_prompt='\[%|>|\$|#\] $'
#
# Change -D 0 to -D 1 to debug interactivly
#
expect -D $debug -c "
spawn $spawn_item $destination
set ret 1
set timeout 20
expect {
    timeout {
        send_user \"Timeout reached!\"
        exit \$ret
    }
    eof {
        puts \"End of test connection reached!\"
        if { \$ret == 0 } {
          puts \"Connection test Successful!\"
          puts \"Exiting $destination ...\"
        } else {
          puts \"Connection Failure!\"
        }
        exit \$ret
    }
    \"Connection refused\" {
        puts \"ERROR: Trouble connecting to $device_type_parm destination $destination\"
        puts \"Aborting...\"
        exit \$ret
    }
    \"Permission denied\" {
        puts \"ERROR: User name or password is incorrect for $destination\"
        puts \"Aborting...\"
        exit \$ret
    }
    \"Connection reset by peer\" {
        puts \"ERROR: Trouble connecting to $destination\"
        puts \"Aborting...\"
        exit \$ret
    }
    \"you sure you want to continue connecting\" {
        send \"yes\r\"
        exp_continue
    }
    \"assword:\" {
        puts \"\r\nSending password\"
        send \"password\\\$\r\"
        exp_continue
    }
    \"Choice? \" {
        send \"1\r\"
        exp_continue
     }
    \"Q. Quit\" {
        send \"q\r\"
        exp_continue
     }
    -re \"$reg_ex_prompt\" {
        send \"sudo reboot\r\"
        sleep 2
        set ret 0
        exit \$ret
     }
     interact
    } "

# get the exit value from expect statment above
exit_val=$?

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dean Householder
Solution 2