Script Name
add_users.sh
Script Summary
Add users to a system en-masse.
Script Description
This script will read a list of space separated Firstname Lastname entries, one per line, from a file specified. It will create an appropriate group (specified within the script) to add users to if it doesn’t already exist. If the group does exist, the users will be created via useradd and a random password set, and those passwords outputted to STDOUT.
Script Limitations
- Only tested on RHEL/OEL/CentOS 5.x and 6.x.
- Will handle duplicate usernames semi-gracefully by exiting with an error, rather than doing anything fancy - you’ll need to add those users manually
Sample Input/Output
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# cat userlist John Doe Sam Smith Jane Whittleton Peter Piper Debbie Smith # ./add_users.sh -f userlist Creating group newgroup Username: jdoe Password: WbzUBF Username: ssmith Password: lj1Jw0 Username: jwhittleton Password: ipt211 Username: ppiper Password: ElM8up Username: dsmith Password: D05agM |
Or with duplicate usernames:
|
1 2 3 4 5 6 |
[root@gooby tmp]# cat userlist Adrian Smith Anthony Smith # ./add_users.sh -f userlist Error: Duplicate usernames found: asmith |
Script
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
#!/bin/bash AWK="/bin/awk" BASENAME="/bin/basename" CAT="/bin/cat" CUT="/bin/cut" DATE="/bin/date" ECHO="builtin echo" EGREP="/bin/egrep" GREP="/bin/grep" GROUPADD="/usr/sbin/groupadd" PASSWD="/usr/bin/passwd" SED="/bin/sed" SEQ="/usr/bin/seq" SORT="/bin/sort" UNIQ="/usr/bin/uniq" USERADD="/usr/sbin/useradd" WC="/usr/bin/wc" PASSSTRING="ABCDEGFFHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz0123456789" THISPROG=$( ${BASENAME} $0 ) GROUPNAME="newgroup" GID="6868" VERBOSE=0 function print_error { ${ECHO} "Error: $@" >&2 } function printv { (( VERBOSE )) && { ${ECHO} "--> $@" } } function print_usage { { ${ECHO} "Usage: ${THISPROG} [-hv] -f <userlist_file>" ${ECHO} " -f Userlist file" ${ECHO} " -h Display this usage message" ${ECHO} " -v Verbose mode" } >&2 } function check_userlist_file { # First, perform basic sanity check of Firstname Lastname ERROR_COUNT=0 COUNTER=0 while read LINE; do (( COUNTER = COUNTER + 1 )) ${ECHO} "${LINE}" | ${EGREP} -qs "^[A-Za-z]+ [A-Za-z-]+$" if [ "$?" -ne "0" ]; then ${ECHO} "Malformed user entry at line ${COUNTER}: ${LINE}" (( ERROR_COUNT = ERROR_COUNT + 1 )) fi done < ${USERLIST_FILE} if [ "${ERROR_COUNT}" -gt "0" ]; then exit 1 fi # Next, ensure this list is non-empty, and no duplicate usernames would be created USERNAME_LIST=$( ${CAT} ${USERLIST_FILE} | ${AWK} '{ print tolower( $0 ) }' | ${SED} 's/^\(.\)[^ ]* \(.*\)$/\1\2/' ) if [ "${USERNAME_LIST}" = "" ]; then print_error "Username list file empty - nothing to do" exit 1 fi #SORTED_LIST=$( ${ECHO} "${USERNAME_LIST}" | ${AWK} '{ print tolower( $0 ) }' | ${SED} 's/^\(.\)[^ ]* \(.*\)$/\1\2/' | ${SORT} | ${UNIQ} -c | ${SORT} -k1,1,rn ) SORTED_LIST=$( ${ECHO} "${USERNAME_LIST}" | ${SORT} | ${UNIQ} -c | ${SORT} -k1,1rn ) DUPLICATE_COUNT=$( ${ECHO} "${SORTED_LIST}" | ${GREP} -vc '^[ ]*1' ) if [ "${DUPLICATE_COUNT}" -gt "0" ]; then print_error "Duplicate usernames found:" ${ECHO} "$( ${ECHO} "${SORTED_LIST}" | ${AWK} '$1 > 1 { print $2 }' )" 2>&1 exit 1 fi } function get_random_number { ${AWK} -vs=$( ${DATE} +%N ) -vu=$(( $( ${ECHO} "${PASSSTRING}" | ${WC} -c ) -1 )) 'BEGIN { srand(s); printf( "%0.0f\n", rand() * u ); }' } function get_randomish_pass { unset RETURNME for i in $( ${SEQ} 0 5 ); do CHARPOS=$( get_random_number ) if [ "${CHARPOS}" -eq "0" ]; then CHARPOS=1 fi PASSCHAR=$( ${ECHO} "${PASSSTRING}" | ${CUT} -c ${CHARPOS} ) RETURNME="${RETURNME}${PASSCHAR}" done ${ECHO} ${RETURNME} } function process_userlist { ${ECHO} "${USERNAME_LIST}" | while read USERNAME; do printv "Processing [${USERNAME}]" ${GREP} -qs "^${USERNAME}:" /etc/passwd && { printv "${USERNAME} already exists - skipping" continue } PASSWORD=$( get_randomish_pass ) printv "Password for [${USERNAME}] - ${PASSWORD}" ${USERADD} -m -d /home/${USERNAME} -s /bin/bash -g ${GROUPNAME} ${USERNAME} if [ "$?" -ne "0" ]; then print_error "Error during useradd for ${USERNAME}... bailing out!" exit 1 fi ${ECHO} "${PASSWORD}" | ${PASSWD} --stdin ${USERNAME} >/dev/null 2>&1 ${ECHO} "Username: ${USERNAME} Password: ${PASSWORD}" done } function check_group { ${GREP} -qs "^${GROUPNAME}:" /etc/group || { ${ECHO} "Creating group ${GROUPNAME}" ${GROUPADD} -g ${GID} ${GROUPNAME} } } # # main() # while getopts ":f:hv" OPTION; do case ${OPTION} in "f") USERLIST_FILE="${OPTARG}" ;; "h") print_usage && exit 0 ;; "v") VERBOSE=1 ;; * ) print_usage && exit 1 ;; esac done shift $(( ${OPTIND} - 1 )) if [ "$#" -ne "0" ]; then print_usage && exit 1 fi if [ -z "${USERLIST_FILE}" ]; then print_error "-f option mandatory" exit 1 else if [ ! -f "${USERLIST_FILE}" ]; then print_error "${USERLIST_FILE}: No such file" exit 1 fi fi check_userlist_file check_group process_userlist exit 0 |