DEV Community

Cover image for Automating user and group management with Bash

Automating user and group management with Bash

Introduction

As a SysOps engineer, managing users and groups on a server is one of your routine tasks. This process can be quite time-consuming and susceptible to errors, particularly when handling numerous users. Automating these tasks is crucial for achieving efficiency and reliability. This article will guide you through a Bash script that automates the creation of users and groups, sets up home directories with correct permissions, generates random passwords, and logs all actions.

Bash

Bash which stands for "Bourne Again Shell" is a command language interpreter and scripting language commonly used in Unix-like operating systems, such as linux and macOS. It's the default shell for most linux distributions and is widely used for automation tasks, managing system operations, and write scrips.

What is Bash script?

A Bash script is a file typically ending with the extension .sh that contain a logical series of related commands to be executed

This project was inspired by HNG internship 11 https://hng.tech/hire, DevOps track of stage one.
visit https://hng.tech/internship to learn more about the program

Prerequisite

Before we start, ensure you have:

  • Access to a linux server with root privileges
  • Basic knowledge of Bash scripting

Script Overview

The script we'll create will:

  1. Create users and groups
  2. set up home directories with the correct permissions
  3. Generate random passwords for users
  4. Log all actions to a specified log file

User Management Automation project

Let's dive into an extensive project that will show us a step by step guide on how to create user and group management with Bash script.

Here is a step by step guide on how to create user and groups management:

Creating the script file

First and foremost, Create a new Bash script file

touch create_user.sh
Enter fullscreen mode Exit fullscreen mode

Open the file in your preferred text editor:

vim create_user.sh
Enter fullscreen mode Exit fullscreen mode

Create an employee file where users and group would be located

touch employeefile.txt
Enter fullscreen mode Exit fullscreen mode

edit your user_data.txt file with a text editor and enter the following user and group below:

vim employeefile.txt
Enter fullscreen mode Exit fullscreen mode

Example Input File

light; sudo,dev, www-data
idimma;sudo
mayowa;dev,www-data

Insert the following script below into your 'create_users.sh' file

The Script

#!/bin/bash

# Define log and password files
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"

# Create log and password files if they don't exist
touch $LOG_FILE
mkdir -p /var/secure
touch $PASSWORD_FILE

# Function to log messages
log_message() {
    echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}

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

# Check if the input file is provided
if [ $# -ne 1 ]; then
    echo "Usage: $0 <input_file>"
    exit 1
fi

# Read the input file
INPUT_FILE=$1

# Check if the input file exists
if [ ! -f $INPUT_FILE ]; then
    echo "Input file not found!"
    exit 1
fi

while IFS=';' read -r username groups; do
    # Remove leading and trailing whitespaces
    username=$(echo $username | xargs)
    groups=$(echo $groups | xargs)

    if id "$username" &>/dev/null; then
        log_message "User $username already exists. Skipping..."
        continue
    fi

    # Create a personal group for the user
    groupadd $username
    if [ $? -ne 0 ]; then
        log_message "Failed to create group $username."
        continue
    fi
    log_message "Group $username created successfully."

    # Create user and add to personal group
    useradd -m -g $username -s /bin/bash $username
    if [ $? -ne 0 ]; then
        log_message "Failed to create user $username."
        continue
    fi
    log_message "User $username created successfully."

    # Create additional groups if they don't exist and add user to groups
    IFS=',' read -ra group_array <<< "$groups"
    for group in "${group_array[@]}"; do
        group=$(echo $group | xargs)
        if [ -z "$group" ]; then
            continue
        fi
        if ! getent group $group >/dev/null; then
            groupadd $group
            if [ $? -ne 0 ]; then
                log_message "Failed to create group $group."
                continue
            fi
            log_message "Group $group created successfully."
        fi
        usermod -aG $group $username
        log_message "User $username added to group $group."
    done

    # Set up home directory permissions
    chmod 700 /home/$username
    chown $username:$username /home/$username
    log_message "Permissions set for home directory of $username."

    # Generate random password and store it
    password=$(generate_password)
    echo "$username:$password" | chpasswd
    echo "$username:$password" >> $PASSWORD_FILE
    log_message "Password set for user $username."

done < "$INPUT_FILE"

log_message "User and group creation process completed."

exit 0

Enter fullscreen mode Exit fullscreen mode

Make the script executable

chmod +x create_user.sh
Enter fullscreen mode Exit fullscreen mode

Execute the script

sudo bash ./create_users.sh employeefile.txt
Enter fullscreen mode Exit fullscreen mode

Defining the Script

Start by defining the script header and setting some initial variables:
Define Log and Password Files

#!/bin/bash

# Define log and password files
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"
Enter fullscreen mode Exit fullscreen mode

These lines set the paths for the log file and the file where passwords will be stored.

Create Log and Password Files if They Don't Exist

# Create log and password files if they don't exist
touch $LOG_FILE
mkdir -p /var/secure
touch $PASSWORD_FILE

Enter fullscreen mode Exit fullscreen mode
  • touch $LOG_FILE creates the log file if it doesn't already exist.
  • mkdir -p /var/secure creates the directory /var/secure if it doesn't exist.
  • touch $PASSWORD_FILE creates the password file if it doesn't exist.

Function to Log Messages

# Function to log messages
log_message() {
    echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}

Enter fullscreen mode Exit fullscreen mode

This function logs messages with a timestamp. tee -a $LOG_FILE appends the log message to the log file while also displaying it on the console.

Function to Generate Random Password

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

Enter fullscreen mode Exit fullscreen mode

This function generates a random 12-character password using characters from A-Z, a-z, and 0-9.

Check if the Input File is Provided

# Check if the input file is provided
if [ $# -ne 1 ]; then
    echo "Usage: $0 <input_file>"
    exit 1
fi

Enter fullscreen mode Exit fullscreen mode

This part ensures that the script is called with exactly one argument (the input file). If not, it displays a usage message and exits.

Read the Input File

# Read the input file
INPUT_FILE=$1

Enter fullscreen mode Exit fullscreen mode

This assigns the first argument (input file) to the variable INPUT_FILE.

Check if the Input File Exists

# Check if the input file exists
if [ ! -f $INPUT_FILE ]; then
    echo "Input file not found!"
    exit 1
fi

Enter fullscreen mode Exit fullscreen mode

This checks if the input file exists. If not, it prints an error message and exits.

Process Each Line of the Input File

while IFS=';' read -r username groups; do
    # Remove leading and trailing whitespaces
    username=$(echo $username | xargs)
    groups=$(echo $groups | xargs)

Enter fullscreen mode Exit fullscreen mode
  • IFS=';' read -r username groups reads each line of the input file, splitting the line into username and groups using ; as a delimiter.
  • xargs is used to trim leading and trailing whitespaces from username and groups.

Check if the User Already Exists

    if id "$username" &>/dev/null; then
        log_message "User $username already exists. Skipping..."
        continue
    fi

Enter fullscreen mode Exit fullscreen mode

This checks if the user already exists. If the user exists, it logs a message and skips to the next iteration.

Create a Personal Group for the User

    # Create a personal group for the user
    groupadd $username
    if [ $? -ne 0 ]; then
        log_message "Failed to create group $username."
        continue
    fi
    log_message "Group $username created successfully."

Enter fullscreen mode Exit fullscreen mode
  • groupadd $username creates a new group with the same name as the user.
  • $? checks the exit status of the groupadd command. If it's not zero (indicating an error), it logs a failure message and skips to the next iteration.
  • If the group is created successfully, it logs a success message.

Create the User and Add to Personal Group

    # Create user and add to personal group
    useradd -m -g $username -s /bin/bash $username
    if [ $? -ne 0 ]; then
        log_message "Failed to create user $username."
        continue
    fi
    log_message "User $username created successfully."

Enter fullscreen mode Exit fullscreen mode
  • useradd -m -g $username -s /bin/bash $username creates the user with a home directory and assigns the personal group.
  • The exit status is checked, and appropriate messages are logged.

Create Additional Groups and Add User to Them

    # Create additional groups if they don't exist and add user to groups
    IFS=',' read -ra group_array <<< "$groups"
    for group in "${group_array[@]}"; do
        group=$(echo $group | xargs)
        if [ -z "$group" ]; then
            continue
        fi
        if ! getent group $group >/dev/null; then
            groupadd $group
            if [ $? -ne 0 ]; then
                log_message "Failed to create group $group."
                continue
            fi
            log_message "Group $group created successfully."
        fi
        usermod -aG $group $username
        log_message "User $username added to group $group."
    done

Enter fullscreen mode Exit fullscreen mode
  • IFS=',' read -ra group_array <<< "$groups" splits the groups string into an array.
  • The script iterates over the array, trims whitespaces, checks if the group is empty, and continues to the next iteration if it is.
  • It checks if each group exists using getent group $group. If the group does not exist, it creates it.
  • The user is added to the group using usermod -aG $group $username. Appropriate messages are logged throughout

Set Up Home Directory Permissions

    # Set up home directory permissions
    chmod 700 /home/$username
    chown $username:$username /home/$username
    log_message "Permissions set for home directory of $username."

Enter fullscreen mode Exit fullscreen mode
  • chmod 700 /home/$username sets the permissions of the user's home directory.
  • chown $username:$username /home/$username changes the ownership of the home directory to the user.
  • A log message is recorded.

Generate Random Password and Store It

    # Generate random password and store it
    password=$(generate_password)
    echo "$username:$password" | chpasswd
    echo "$username:$password" >> $PASSWORD_FILE
    log_message "Password set for user $username."

Enter fullscreen mode Exit fullscreen mode
  • password=$(generate_password) generates a random password.
  • echo "$username:$password" | chpasswd sets the user's password.
  • The password is stored in the password file.
  • A log message is recorded.

Complete the Process

done < "$INPUT_FILE"

log_message "User and group creation process completed."

exit 0

Enter fullscreen mode Exit fullscreen mode
  • The done statement ends the while loop.
  • A log message indicates that the process is complete.
  • exit 0 exits the script successfully.

This detailed breakdown should help you understand each part of the script and its function as you run it in your terminal.

Top comments (0)