As a DevOps Engineer, writing automation scripts is an essential part of your job. These scripts help streamline repetitive tasks and increase efficiency. In this task, we must create a bash script that reads a text file containing employees' usernames and group names, where each line is formatted as user; groups. The script must create the specified users and groups, set up home directories with the appropriate permissions and ownership, generate random passwords for each user, and log all actions to /var/log/user_management.log. Additionally, it should securely store the generated passwords in /var/secure/user_passwords.txt and implement error handling to manage scenarios where users already exist, all while providing clear documentation and comments within the script.
Requirements
- Linux Machine
- Bash Script
Steps
sudo nano create_users.sh
- creates a file to write the script
#!/bin/bash
# Ensure script is run as root
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" >&2
exit 1
fi
# Check if input file is provided
if [[ -z "$1" ]]; then
echo "Usage: $0 <user-list-file>"
exit 1
fi
USER_FILE="$1"
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"
# Ensure log and password directories exist
mkdir -p /var/secure
touch "$LOG_FILE" "$PASSWORD_FILE"
chmod 600 "$PASSWORD_FILE"
# Process each line in the file
while IFS=';' read -r username groups; do
username=$(echo "$username" | xargs)
groups=$(echo "$groups" | xargs)
# Skip empty lines
[[ -z "$username" ]] && continue
# Creates groups if it doesn't exist
if ! getent group "$username" >/dev/null; then
groupadd "$username"
echo "Created group: $username" | tee -a "$LOG_FILE"
fi
# Creates a user with and adds them to their group
if ! id "$username" &>/dev/null; then
useradd -m -g "$username" -s /bin/bash "$username"
echo "Created user: $username" | tee -a "$LOG_FILE"
else
echo "User $username already exists, skipping..." | tee -a "$LOG_FILE"
continue
fi
# Assign users to additional groups
if [[ -n "$groups" ]]; then
IFS=',' read -ra GROUPS_ARRAY <<< "$groups"
for group in "${GROUPS_ARRAY[@]}"; do
group=$(echo "$group" | xargs)
if ! getent group "$group" >/dev/null; then
groupadd "$group"
echo "Created group: $group" | tee -a "$LOG_FILE"
fi
usermod -aG "$group" "$username"
echo "Added $username to group: $group" | tee -a "$LOG_FILE"
done
fi
# Generate a random password
password=$(openssl rand -base64 8)
echo "$username,$password" >> "$PASSWORD_FILE"
echo "Generated password for $username" | tee -a "$LOG_FILE"
# Set password
echo "$username:$password" | chpasswd
done < "$USER_FILE"
echo "User creation process completed." | tee -a "$LOG_FILE"
exit 0
- explaining each section of the bash script
#!/bin/bash
- This section specifies that the script should be executed using the Bash shell
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" >&2
exit 1
fi
- This section ensures the script is executed with root privileges. Without root, actions like creating users and groups will fail.
if [[ -z "$1" ]]; then
echo "Usage: $0 <user-list-file>"
exit 1
fi
- This section, verifies that the user provided the input file which contains the usernames and groups.
USER_FILE="$1"
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"
mkdir -p /var/secure
touch "$LOG_FILE" "$PASSWORD_FILE"
chmod 600 "$PASSWORD_FILE"
This section sets file paths for the input file, log file, and password file, creates necessary directories and files, and sets secure permissions on the password file.
while IFS=';' read -r username groups; do
username=$(echo "$username" | xargs)
groups=$(echo "$groups" | xargs)
# Skip empty lines
[[ -z "$username" ]] && continue
- This section reads the input file line by line, using
;as a delimiter to separate the username from the groups, and trims any extra whitespace.
if ! getent group "$username" >/dev/null; then
groupadd "$username"
echo "Created group: $username" | tee -a "$LOG_FILE"
fi
- This section checks if a group with the same name as the username exists. If not, it creates the group and logs the action.
if ! id "$username" &>/dev/null; then
useradd -m -g "$username" -s /bin/bash "$username"
echo "Created user: $username" | tee -a "$LOG_FILE"
else
echo "User $username already exists, skipping..." | tee -a "$LOG_FILE"
continue
fi
- This section creates the user with the home directory, assigning them to their group. If the user already exists, it displays a message that the user already exists and skips further processing for that user.
if [[ -n "$groups" ]]; then
IFS=',' read -ra GROUPS_ARRAY <<< "$groups"
for group in "${GROUPS_ARRAY[@]}"; do
group=$(echo "$group" | xargs)
if ! getent group "$group" >/dev/null; then
groupadd "$group"
echo "Created group: $group" | tee -a "$LOG_FILE"
fi
usermod -aG "$group" "$username"
echo "Added $username to group: $group" | tee -a "$LOG_FILE"
done
fi
- This section processes additional groups by splitting the string on commas, creates them if they don't exist, adds the user to each, and logs the operations
password=$(openssl rand -base64 12)
echo "$username,$password" >> "$PASSWORD_FILE"
echo "Generated password for $username" | tee -a "$LOG_FILE"
# Set password
echo "$username:$password" | chpasswd
- This section generates a secure random password, appends the username and password to the secure password file, and sets the generated password for the user.
echo "User creation process completed." | tee -a "$LOG_FILE"
exit 0
- This section logs a message that the process is finished and exits the script successfully.
sudo nano users.txt
- This command helps opens a file where the script will be written.
light; sudo,dev,www-data
idimma; sudo
mayowa; dev,www-data
john; admin,dev
emma; sudo,www-data
alice; dev
bob; admin,sudo
charlie; www-data
dave; dev,admin
eve; sudo
- Input this in the file
sudo bash create_users.sh users.txt
- Use this command to run the script
sudo cat /var/log/user_management.log
sudo cat /var/secure/user_passwords.csv
- Use this command to view the content of the files created to ensure the script worked

Top comments (0)