BASH with sshpass send same command to multiple servers based on list of servers?

1k Views Asked by At

Hi I have the following "script" below which works fine.

#!/bin/bash
TARGET="vm-windows-server01.local"
TARGET_USER="administrator"
TARGET_PASSWORD="Qwerty"

TARGET2="vm-linux-server01.local"
TARGET_USER2="root"
TARGET_PASSWORD2="Qwerty123"

#Windows server shutdown
sshpass -p $TARGET_PASSWORD ssh -o stricthostkeychecking=no $TARGET_USER@$TARGET 'shutdown /s /c "Shutting down"'

#Linux server shutdown
sshpass -p $TARGET_PASSWORD2 ssh -o stricthostkeychecking=no $TARGET_USER2@$TARGET2 'shutdown 3 "Shutting down"'

Now instead of copying TARGET variables for over 50 servers along with 50 more lines of the sshpass Can something like this below be done? Please be advised its bogus code just to give the idea what i want. I'm new to bash so be gently :-)

#!/bin/bash
WINDOWS_SERVERS="
     vm-windows-server01.local,
     vm-windows-server02.local,
     vm-windows-server03.local"

WINDOWS_USER="administrator"
WINDOWS_PASSWORD="Qwerty"

LINUX_SERVERS="
     vm-linux-server01.local,
     vm-linux-server02.local,
     vm-linux-server03.local"

LINUX_USER="root"
LINUX_PASSWORD="Qwerty123"

#Windows server shutdown
sshpass -p $WINDOWS_PASSWORD ssh -o stricthostkeychecking=no $WINDOWS_USER@$WINDOWS_SERVERS 'shutdown /s /c "Shutting down"'
    
#Linux server shutdown
sshpass -p $LINUX_PASSWORD ssh -o stricthostkeychecking=no $LINUX_USER@$LINUX_SERVERS 'shutdown 3 "Shutting down"'

Basically runs the sshpass for all the hosts in the list.

1

There are 1 best solutions below

0
On BEST ANSWER

If you are unsure about the availability of Bash, or another shell which knows about arrays; you can adapt your code to iterate over your server lists with the POSIX available grammar (no array):

#!/usr/bin/env sh

WINDOWS_SERVERS="
     vm-windows-server01.local,
     vm-windows-server02.local,
     vm-windows-server03.local"

WINDOWS_USER="administrator"
WINDOWS_PASSWORD="Qwerty"

LINUX_SERVERS="
     vm-linux-server01.local,
     vm-linux-server02.local,
     vm-linux-server03.local"

LINUX_USER="root"
LINUX_PASSWORD="Qwerty123"

echo "$WINDOWS_SERVERS" | {
  IFS=$(printf '\t\n, ')
  while read -r windows_host || [ "$windows_host" ]
  do
    sshpass -p "$WINDOWS_PASSWORD" ssh -o stricthostkeychecking=no "$WINDOWS_USER@$windows_host" 'shutdown /s /c "Shutting down"'
  done
}

echo "$LINUX_SERVERS" | {
  IFS=$(printf '\t\n, ')
  while read -r linux_host || [ "$linux_host" ]
  do
    sshpass -p "$LINUX_PASSWORD" ssh -o stricthostkeychecking=no "$LINUX_USER@$linux_host" 'shutdown 3 "Shutting down"'
  done
}

But if you have bash, zsh or ksh 93+ who supports arrays, your script syntax is simpler and easier to maintain:

#!/usr/bin/env bash

WINDOWS_SERVERS=(
  'vm-windows-server01.local'
  'vm-windows-server02.local'
  'vm-windows-server03.local'
)

WINDOWS_USER='administrator'
WINDOWS_PASSWORD='Qwerty'

LINUX_SERVERS=(
  'vm-linux-server01.local'
  'vm-linux-server02.local'
  'vm-linux-server03.local'
)

LINUX_USER='root'
LINUX_PASSWORD='Qwerty123'

for windows_host in "${WINDOWS_SERVERS[@]}"
do
  sshpass -p "$WINDOWS_PASSWORD" ssh -o stricthostkeychecking=no "$WINDOWS_USER@$windows_host" 'shutdown /s /c "Shutting down"'
done

for linux_host in "${LINUX_SERVERS[@]}"
do
  sshpass -p "$LINUX_PASSWORD" ssh -o stricthostkeychecking=no "$LINUX_USER@$linux_host" 'shutdown 3 "Shutting down"'
done