Automate User Creation on Your Linux System - A Beginner's Guide

This guide walks you through a bash script that simplifies creating user accounts and managing groups on your Linux system. It automates the process, saving you time and effort, especially when dealing with multiple users.

Prerequisite

A Basic understanding of Bash Scripting and Linux users and groups

Understanding the Script:

The script takes a text file as input, containing information about users and the groups they should belong to. Here's a breakdown of its functionality:

  • User Input: You provide the script with the path to a text file containing user data.

  • User Creation: The script creates user accounts with random, secure passwords.

  • Group Management: It creates primary groups for users if they don't exist and assigns them to additional groups based on the user list file.

  • Logging: All actions are logged with timestamps in a separate file for tracking purposes.

Preparing the User List File:

Create a plain text file with one user per line, formatted like this:

username;group1,group2,...groupN

  • username: The desired username for the account.

  • group1,group2,...groupN (optional): Comma-separated list of additional groups the user should belong to (besides their primary group).

Steps To Create The Script

Step 1

Add a shebang line to the beginning of your script. The #! shebang is used to tell the kernel which interpreter should be used to run the commands present in the file.

#!/bin/bash

Step 2

Create variables to store both your log and password files and also a variable to house your text file argument.

user_file="$1"

# Log file and password storage
log_file="/var/log/user_management.log"
password_file="/var/secure/user_passwords.txt"

Step 3

Validate your input to ensure the correct file is provided. The usage() function displays instructions on how to run the script and the expected content of the text file if any of the conditions are met.

# Function to explain the script usage
usage() {
  echo "Usage: $0 <user_list_file>" >&2
  echo "  user_list_file: Path to a text file containing usernames and groups (username;group1,group2,...groupN)"
  exit 1
}

# Check if exactly one argument is provided
if [ $# -ne 1 ]; then
  usage
  exit 1
fi

# Check if user list file exists
if [[ -z "$1" || ! -f "$1" ]]; then
  echo "Error: User list file '$1' does not exist." >&2
  exit 1
fi

Step 4

Create a function to generate user's password.

# Function to generate a random password
generate_password() {
  length=16
  cat /dev/urandom | tr -dc 'A-Za-z0-9!@#$%^&*' | fold -w "$length" | head -n 1
}

Step 5

Create the log and password directories if they do not exist yet. Also, open the log files for writing.

In this example, we will store the passwords in a text file, but it is recommended to use a more secure method for handling passwords.

# If the directory does not exist , create one

if [[ ! -d $(dirname "$log_file") ]]; then
  sudo mkdir -p $(dirname "$log_file")
fi

if [[ ! -d $(dirname "$password_file") ]]; then
  sudo mkdir -p $(dirname "$password_file")
fi

# Redirect standard output and error to log file
exec &>> "$log_file"

Step 6

Here, we create a while loop that reads through each line of the file to perform the following operations:

  • Remove the leading and trailing white spaces from both the username and password.

  • Trigger the generate_password function to create a secure password for each user.

  • Check if a user already exists. If true, write the username and password to the user_passwords.txt file. If the user does not exist, create a primary group for the user, create the user, and add the user to the primary group.

  • Iterate over a list of user groups separated by commas and replace the commas with spaces using the tr command.

  • Create groups if they do not exist and add the user to the groups. If the groups exist, add the user directly to their respective groups.

The useradd -m -g "$username" -s /bin/bash -p $(echo "$password" | openssl passwd -1) "$username" command creates a new user with a home directory, assigns the user to a primary group with the same name as the username, sets the default shell to /bin/bash, and assigns a password that is encrypted using OpenSSL.

# Loop through users in the file
while IFS=';' read -r username groups; do
  # Remove leading/trailing whitespace from username and groups
  username=$(echo "$username" | xargs)
  groups=$(echo "$groups" | xargs | tr -d ' ')

  password=$(generate_password)

  # Check if user already exists
  if id "$username" &> /dev/null; then
    echo "$(date +'%Y-%m-%d %H:%M:%S') WARNING: User '$username' already exists. Skipping..."
  else
    # Create primary group if the primary group does not exist
    if ! getent group "$username" >/dev/null 2>&1; then
      sudo groupadd "$username"
      echo "$(date +'%Y-%m-%d %H:%M:%S') Created primary group '$username' for user."
    fi

    # Create user with extra options
    useradd -m -g "$username" -s /bin/bash -p $(echo "$password" | openssl passwd -1) "$username"
    echo "$(date +'%Y-%m-%d %H:%M:%S') Successfully created user '$username'."

    # Add user to primary group
    sudo usermod -g "$username" "$username"
    echo "$(date +'%Y-%m-%d %H:%M:%S') Added user '$username' to primary group '$username'."
  fi

  # Store username and password in a password file
  echo "$username,$password" >> "$password_file"

  # Add user to additional groups 
  # Check if the group exists
  # If the group exists, add user using gpasswd
  # If the group doesn't exist, create it and add the user to the group

  for group in $(echo "$groups" | tr ',' ' '); do
    if getent group "$group" >/dev/null 2>&1; then
      sudo gpasswd -a "$username" "$group"
      echo "$(date +'%Y-%m-%d %H:%M:%S') Added user '$username' to existing group '$group'."
    else
      sudo groupadd "$group"
      echo "$(date +'%Y-%m-%d %H:%M:%S') Created group '$group' and added user '$username'."
      sudo gpasswd -a "$username" "$group"
    fi
  done

done < "$1"

echo "$(date +'%Y-%m-%d %H:%M:%S') User creation process completed. Check $log_file for details."

Running the Script:

  1. Open a terminal: This is where you will interact with the script using commands.

  2. Navigate to the script location: Use the cd command to change directories. For example, if the script is in your home directory, type cd ~.

  3. Run the script: Type the following command, replacing <user_list_file> with the actual path to your user list file:

./script.sh <user_list_file>

Bash

sudo ./create_users.sh <user_list_file>

Benefits of Using the Script:

Efficiency: Automates user creation and group management, saving time and effort.

Consistency: Ensures all users are created with the same settings and eliminates manual errors.

Documentation: The user list file serves as a record of user accounts and their groups.

Important Note: This script should be used for personal practice as it introduces some security issues.

You can access the full script on my GitHub: GitHub Repository.

This script is intended for basic user management tasks and was inspired by HNG and the HNG Internship.