Automating Linux User and Group Creation in Linux with Bash Scripts

Rotimi Abiola
6 min readJul 3, 2024

--

Photo by Gabriel Heinzer on Unsplash

As a System Administrator or SysOps Engineer, creating and managing users and groups on a Linux system is a common task. As a result, manually performing these tasks can become repetitive and prone to errors. Automating user and group management saves time and ensures consistency and accuracy. Bash scripts are an effective tool for automating these processes.

A bash script is a text file containing commands written in the Bash (Bourne Again SHell) scripting language. It is used to automate tasks, simplify complex operations, and manage system configurations on Unix-based operating systems like Linux and macOS.

In this article, we’ll walk through a bash script designed to create users and groups, 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, it securely stores the generated passwords in /var/secure/user_passwords.txt .

Prerequisites

Before diving into the script, ensure you have the necessary permissions to create users and groups on your Linux system. Typically, you will need root or sudo privileges.

The Script

The script, written in Bash, takes a single argument: the name of a text file containing user information. The text file should contain lines in the format username;group1,group2,..., where username is the desired username and group1, group2, etc. are the groups to which the user should be assigned. A sample user list below is user_list.txt:

light; sudo,dev,www-data
idimma; sudo
mayowa; dev,www-data
alice; admin,developers
bob; testers

Run the script by making it executable using the chmod command and providing the path to your user list file as an argument. For example, if your user list file is named user_list.txt and is in the same directory as the script, use the following command:

chmod +x create_users.sh
sudo ./create_users.sh user_list.txt

Here’s the complete create_users.sh script:

#!/bin/bash
set -e

terminate() {
local msg="${1:-"An error occured"}"
local code="${2:-160}"
echo "ERROR: ${msg}" >&2
exit "${code}"
}
# Check if the user has provided a filename as an argument
if [ "$#" -ne 1 ]; then
terminate "Please pass one argument referencing the name of the text file containing users' information
Sample Usage: bash $0 <name-of-text-file>"
fi

# Define the input file
user_list_file=$1

# Check if the input file exists
if [ ! -f "$user_list_file" ]; then
terminate "File '$user_list_file' not found!"
fi

# Log file and secure passwords file
user_log_file="/var/log/user_management.log"
secure_password_file="/var/secure/user_passwords.csv"

# Ensure the log file and password file directories exist
mkdir -p /var/log
mkdir -p /var/secure

# Initialize the log file and password file
echo "User management log" > "$user_log_file"
echo "Username, Password" > "$secure_password_file"

# Set permissions for the password file
chmod 600 "$secure_password_file"

# Function to generate a random password
generate_password() {
tr -dc A-Za-z0-9 </dev/urandom | head -c 15
}

# Read the input file line by line
while IFS=';' read -r username groups; do
# Remove leading and trailing whitespace
username=$(echo "$username" | xargs)
groups=$(echo "$groups" | xargs)

# Create a personal group with the same name as the username
if ! getent group "$username" >/dev/null; then
groupadd "$username"
echo "Created group: $username" >> "$user_log_file"
else
echo "Group $username already exists" >> "$user_log_file"
fi

# Create the user
if ! id "$username" >/dev/null 2>&1; then
password=$(generate_password)
useradd -m -g "$username" -s /bin/bash "$username"
echo "$username:$password" | chpasswd
echo "$username,$password" >> "$secure_password_file"
echo "Created user: $username with home directory and set password" >> "$user_log_file"
else
echo "User $username already exists" >> "$user_log_file"
fi

# Add the user to the specified groups
IFS=',' read -ra group_array <<< "$groups"
for group in "${group_array[@]}"; do
group=$(echo "$group" | xargs)
if ! getent group "$group" >/dev/null; then
groupadd "$group"
echo "Created group: $group" >> "$user_log_file"
fi
usermod -aG "$group" "$username"
echo "Added user $username to group $group" >> "$user_log_file"
done

done < "$user_list_file"

echo "User creation and group assignment completed."

exit 0

Step-by-Step Explanation

Step 1: Define an Error Handling Function

The script starts with set -e, which means that if any command in the script fails (i.e., returns a non-zero exit code), the script will immediately exit.

The terminate function is defined to handle errors. It takes two arguments: a message and an exit code. If no message is provided, it defaults to "An error occurred". The function prints the error message to stderr and exits with the specified code.

set -e

terminate() {
local msg="${1:-"An error occured"}"
local code="${2:-160}"
echo "ERROR: ${msg}" >&2
exit "${code}"
}

Step 2: Check if an Argument is Provided

The script checks if the user has provided exactly one argument, which should be the name of a text file containing user information. If not, it calls the terminate function with an appropriate error message.

# Check if the user has provided a filename as an argument
if [ "$#" -ne 1 ]; then
terminate "Please pass one argument referencing the name of the text file containing users' information
Sample Usage: bash $0 <name-of-text-file>"
fi

Step 3: Validate the Input File

Next, the script verifies if the input file that was supplied as an argument exists. If the file is not found, it calls the terminate function.

# Define the input file
user_list_file=$1

# Check if the input file exists
if [ ! -f "$user_list_file" ]; then
terminate "File '$user_list_file' not found!"
fi

Step 4: Setup Log and Password Files

The script initializes the log and password files, creating the necessary directories if they don’t already exist. To make the password file secure, access to the file is restricted to only the current user using the chmod command.

# Log file and secure passwords file
user_log_file="/var/log/user_management.log"
secure_password_file="/var/secure/user_passwords.csv"

# Ensure the log file and password file directories exist
mkdir -p /var/log
mkdir -p /var/secure

# Initialize the log file and password file
echo "User management log" > "$user_log_file"
echo "Username, Password" > "$secure_password_file"

# Set permissions for the password file
chmod 600 "$secure_password_file"

Step 5: Create a Password Generation Function

This function generates a random password of 15 characters using tr command and /dev/urandom.

generate_password() {
tr -dc A-Za-z0-9 </dev/urandom | head -c 15
}

Step 6: Read Input File

The script reads the input file line by line, splits each line into username and groups using ; as the delimiter, and removes leading and trailing whitespaces.

# Read the input file line by line
while IFS=';' read -r username groups; do
# Remove leading and trailing whitespace
username=$(echo "$username" | xargs)
groups=$(echo "$groups" | xargs)

Step 7: Create a personal group with the same name as the username

Next, it checks if the username exists in the groups database using the getent command. If it doesn’t, a personal group is created for the user using the same username.

if ! getent group "$username" >/dev/null; then
groupadd "$username"
echo "Created group: $username" >> "$user_log_file"
else
echo "Group $username already exists" >> "$user_log_file"
fi

Step 8: Create the User

If the user doesn’t already exist, the script creates the user, sets up the home directory, and assigns a generated password.

if ! id "$username" >/dev/null 2>&1; then
password=$(generate_password)
useradd -m -g "$username" -s /bin/bash "$username"
echo "$username:$password" | chpasswd
echo "$username,$password" >> "$secure_password_file"
echo "Created user: $username with home directory and set password" >> "$user_log_file"
else
echo "User $username already exists" >> "$user_log_file"
fi

Step 9: Add the user to specified groups

The script reads the groups for each user, creates any missing groups, and assigns the user to the specified groups.

IFS=',' read -ra group_array <<< "$groups"
for group in "${group_array[@]}"; do
group=$(echo "$group" | xargs)
if ! getent group "$group" >/dev/null; then
groupadd "$group"
echo "Created group: $group" >> "$user_log_file"
fi
usermod -aG "$group" "$username"
echo "Added user $username to group $group" >> "$user_log_file"
done

Conclusion

This bash script provides an efficient and secure way to automate the process of user and group management in a Linux environment. By automating these tasks, you can save time, reduce errors, and ensure consistency across your system.

Learn More

The HNG Internship program offers invaluable experience for aspiring developers and engineers. It provides an opportunity to work on real-world projects, enhancing both skills and employability. Additionally, if you’re looking to hire top talent, consider visiting the HNG Hire page to find skilled professionals trained through the program.

By leveraging automation tools and enhancing your skills through programs like HNG Internship, you can significantly boost your productivity and career growth.

--

--