Automating User and Group Management Using Bash Script

Automating User and Group Management Using Bash Script

Bash, short for Bourne Again Shell, is a Unix shell and command language that has been a fundamental part of system administration and development for many years. As the default shell on many Unix-like operating systems, including Linux and macOS, Bash is renowned for its powerful capabilities in scripting and automation.

Imagine having to create user accounts, assign them to appropriate groups, set up home directories, and generate secure passwords for each new developer joining your team. Doing this manually can be tedious and error-prone. This is where Bash comes in. You can automate these repetitive tasks with Bash scripting, ensuring consistency and saving valuable time.

In this article, I used a Bash script to automate the onboarding process for new developers. This script reads a text file containing usernames and their respective groups, creates users, assigns them to groups, sets up their home directories, generates random passwords, and logs all actions.

Prerequisites

A Unix-based system (Linux or macOS)
Basic knowledge of Unix commands and Bash scripting

Objective

The script should create users and groups as specified, set up home directories with appropriate permissions and ownership, generate random passwords for the users, and log all actions to /var/log/user_management.log. Additionally, store the generated passwords securely in /var/secure/user_passwords.txt

My create_users.sh Script

#!/bin/bash

# Log file and password storage
LOG_FILE=”/var/log/user_management.log”
PASSWORD_FILE=”/var/secure/user_passwords.txt”

# Ensure the /var/secure directory exists
if [ ! -d “/var/secure” ]; then
mkdir -p /var/secure
chmod 700 /var/secure
fi

# Ensure the log file and password file exist and have correct permissions
touch $LOG_FILE
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE

# Function to log messages
log_message() {
echo “$(date ‘+%Y-%m-%d %H:%M:%S’) – $1” >> $LOG_FILE
}

# Check if the file is supplied
if [ $# -ne 1 ]; then
log_message “ERROR: No input file supplied”
echo “Usage: $0 <name-of-text-file>”
exit 1
fi

INPUT_FILE=$1

# Check if input file exists
if [ ! -f $INPUT_FILE ]; then
log_message “ERROR: Input file does not exist”
echo “ERROR: Input file does not exist”
exit 1
fi

# Read the input file line by line
while IFS=’;’ read -r username groups; do
# Trim whitespace
username=$(echo $username | xargs)
groups=$(echo $groups | xargs)

# Skip empty lines
if [ -z “$username” ]; then
continue
fi

# Create a personal group for the user
if ! getent group $username >/dev/null; then
groupadd $username
log_message “Group $username created.”
else
log_message “Group $username already exists.”
fi

# Create the user with the personal group
if ! id -u $username >/dev/null 2>&1; then
useradd -m -g $username $username
log_message “User $username created.”
else
log_message “User $username already exists.”
fi

# Assign the user to additional groups
IFS=’,’ read -ra ADDR <<< “$groups”
for group in “${ADDR[@]}”; do
group=$(echo $group | xargs)
if [ ! -z “$group” ]; then
if ! getent group $group >/dev/null; then
groupadd $group
log_message “Group $group created.”
fi
usermod -aG $group $username
log_message “User $username added to group $group.”
fi
done

# Generate a random password
password=$(openssl rand -base64 12)

# Set the user’s password
echo “$username:$password” | chpasswd
log_message “Password set for user $username.”

# Store the password securely
echo “$username,$password” >> $PASSWORD_FILE
done < “$INPUT_FILE”

# Set the correct permissions on the password file
chmod 600 $PASSWORD_FILE

log_message “User creation process completed.”

echo “User creation process completed. Check $LOG_FILE for details.”

A detailed breakdown of the Script

Here is what this script does:

Shebang
The #!/bin/bash known as the shebang indicates that the script should be run on the BASH shell.

Path to Log file and Password file

LOG_FILE=”/var/log/user_management.log”
PASSWORD_FILE=”/var/secure/user_passwords.txt”

The LOG_FILE and PASSWORD_FILE are variables that store the path to the log file and password file respectively.

Create /var/secure directory and set permission if it doesn’t exist

if [ ! -d “/var/secure” ]; then
mkdir -p /var/secure
chmod 700 /var/secure
fi

Create Log file and Password file if they don’t exist and set permission

touch $LOG_FILE
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE

touch $LOG_FILE and touch $PASSWORD_FILE creates the log and password files if they do not already exist.
chmod 600 $PASSWORD_FILE sets the permissions for the password file so that only the file owner can read and write to it.

Log message function

log_message() {
echo “$(date ‘+%Y-%m-%d %H:%M:%S’) – $1” >> $LOG_FILE
}

The log_message function takes a message as an argument and appends it to the log file with a timestamp.

Check if input file is provided

if [ $# -ne 1 ]; then
log_message “ERROR: No input file supplied”
echo “Usage: $0 <name-of-text-file>”
exit 1
fi

This checks if [ $# -ne 1 ]; then checks if exactly one argument (the input file) is supplied to the script.
If not, it logs an error, prints a usage message, and exits the script.

INPUT_FILE=$1 assigns the first argument (input file) to the variable INPUT_FILE

Check if the input file exists

if [ ! -f $INPUT_FILE ]; then
log_message “ERROR: Input file does not exist”
echo “ERROR: Input file does not exist”
exit 1
fi

The if [ ! -f $INPUT_FILE ]; then checks if the input file exists.
If not, it logs an error, prints an error message, and exits the script.Cre

Read and process the input file

The while IFS=’;’ read -r username groups; do starts a loop to read the input file line by line, expecting each line to contain a username and groups separated by a semicolon (;).

The command below trims whitespace from the username and groups variables if any.

username=$(echo $username | xargs)
groups=$(echo $groups | xargs)

While

if [ -z “$username” ]; then
continue
fi

Skips empty lines (where username is empty).

Create a group for user

if ! getent group $username >/dev/null; then
groupadd $username
log_message “Group $username created.”
else
log_message “Group $username already exists.”
fi

This creates a personal group for the user if it doesn’t exist and logs the action.

Creates user for group

if ! id -u $username >/dev/null 2>&1; then
useradd -m -g $username $username
log_message “User $username created.”
else
log_message “User $username already exists.”
fi

This creates the user with their group if they don’t already exist and logs the action.

Creates additional groups for users.

IFS=’,’ read -ra ADDR <<< “$groups”
for group in “${ADDR[@]}”; do
group=$(echo $group | xargs)
if [ ! -z “$group” ]; then
if ! getent group $group >/dev/null; then
groupadd $group
log_message “Group $group created.”
fi
usermod -aG $group $username
log_message “User $username added to group $group.”
fi
done

This command splits the group’s string into an array, iterates over it, checks if the group exists (creating it if necessary) and adds the user to the group, logging each action.

Generate a random password
The password=$(openssl rand -base64 12) generates a random password using the OpenSSL

Set the user’s password

echo “$username:$password” | chpasswd
log_message “Password set for user $username.”
echo “$username,$password” >> $PASSWORD_FILE
done < “$INPUT_FILE”

The code above sets the user’s password and then appends the username and password to the PASSWORD_FILE

This done < “$INPUT_FILE” code ends the loop that reads from the INPUT FILE

The chmod 600 $PASSWORD_FILE code ensures the password file’s permissions are secure after all passwords have been added.

Log completion of the user creation process
log_message “User creation process completed.”

Test the Script

To test this script, let’s create a users.txt file
nano users.txt

In the text file, enter the usernames and groups
wendy; engineering,webteam
florenceokoli; admins, dev_team
chi; support

Execute the Script

`chmod create_users.sh

Run the Script

sudo ./create_users.sh users.txt

Output

Management Log

Password.txt File

Conclusion

Bash is a powerful scripting tool used to automate various tasks on Unix-like operating systems. This script is designed to read a text file containing usernames and their respective groups, create users and their personal groups, assign users to additional groups, set up home directories, generate random passwords, and log all these actions for auditing purposes. Additionally, it stores the generated passwords securely in a dedicated file.

This project is a stage 1 task in the Devops HNG-11 Internship. For more information about the HNG Internship and its various opportunities, visit HNG Internship and HNG Hire.