Automating User and Group Management with Bash

Overview

As a SysOps engineer, managing user accounts and their associated groups can be a repetitive and time-consuming task. With many developers joining a team, manually creating user accounts and assigning them to appropriate groups is inefficient. We can streamline this process using a Bash script to automate user and group creation based on a provided input file. The goal is to automate this process by reading a text file that contains usernames and group names, creating the users and groups, setting up home directories, and logging all actions. This article will walk you through the script I developed to achieve this and explain each step in detail.

Script Overview

  1. Input File: The script takes a text file as an argument. Each line in the file is formatted as user;groups, where commas separate multiple groups.

  2. Logging: All actions performed by the script are logged to /var/log/user_management.log.

  3. Password Storage: Generated passwords are stored securely in /var/secure/user_passwords.csv.

Prerequisites

  • A linux or unix-like environment

  • Bash shell

  • OpenSSL installed

Script Outline

Here is the complete script saved as "create_users.sh";

#!/bin/bash

# Check if the script is run with a file argument
if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <filename>"
    exit 1
fi

echo "Script started with argument: $1"

# Variables
FILE=$1
LOG_FILE="./user_management.log"
PASSWORD_FILE="./user_passwords.csv"

echo "Using log file: $LOG_FILE"
echo "Using password file: $PASSWORD_FILE"

# Ensure the log file exists
touch $LOG_FILE
echo "Log file created at $LOG_FILE"

# Ensure the password file exists and set permissions
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE
echo "Password file created at $PASSWORD_FILE with permissions set to 600"

# Log function
log() {
    echo "$(date +"%Y-%m-%d %T") - $1" | tee -a $LOG_FILE
}

# Create users and groups (simulated)
while IFS=';' read -r username groups; do
    # Remove whitespace
    username=$(echo "$username" | xargs)
    groups=$(echo "$groups" | xargs)

    echo "Processing user: $username with groups: $groups"

    # Simulate user and group creation
    log "Simulated creation of user $username with groups $groups"

    # Generate random password
    password=$(openssl rand -base64 12)
    echo "Generated password for $username: $password"

    # Store username and password
    echo "$username,$password" >> $PASSWORD_FILE
    echo "Stored password for $username in $PASSWORD_FILE"

done < "$FILE"

# Final log message
log "User creation script completed successfully (simulated)"
echo "User creation script completed successfully (simulated)"

exit 0

Step-By-Step Breakdown

#!/bin/bash

This line tells the computer to use the Bash shell to run the script.

# Check if the script is run with a file argument
if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <filename>"
    exit 1
fi

Here, the script checks if you provided exactly one argument (a filename) when running the script. If not, it prints a message telling you how to use the script and then stops running. For example, you can run the script using `./create_users,sh users.txt `. If you run it without adding the filename at the back, you will get a message on how to use it.

echo "Script started with argument: $1"

This line prints a message to the console indicating that the script has started and shows the filename you provided.

# Variables
FILE=$1
LOG_FILE="./user_management.log"
PASSWORD_FILE="./user_passwords.csv"

These lines set up three variables:

  • FILE is the name of the input file you provided.

  • LOG_FILE is the name of the file where we will log what happens.

  • PASSWORD_FILE is the name of the file where we will save the generated passwords.

echo "Using log file: $LOG_FILE"
echo "Using password file: $PASSWORD_FILE"

These lines print messages to the console showing which log and password files will be used.

# Ensure the log file exists
touch $LOG_FILE
echo "Log file created at $LOG_FILE"

The touch command creates the log file if it doesn't already exist. Then a message is printed to the console to confirm the log file's creation.

# Ensure the password file exists and set permissions
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE
echo "Password file created at $PASSWORD_FILE with permissions set to 600"

Similarly, the touch command creates the password file if it doesn't exist. The chmod 600 command changes the permissions of the password file so that only the file's owner can read and write it. A message is printed to confirm the file's creation and permission setting.

# Log function
log() {
    echo "$(date +"%Y-%m-%d %T") - $1" | tee -a $LOG_FILE
}

This defines a function called log. A function is like a mini-script within the script. This function takes one argument (a message), adds a timestamp to it, and writes it to both the log file and the console.

# Create users and groups (simulated)
while IFS=';' read -r username groups; do

This starts a loop that reads each line of the input file. The IFS=';' part tells the script to use ; as the delimiter (separator) between the username and groups. The read -r username groups part reads each line into two variables: username and groups.

# Remove whitespace
    username=$(echo "$username" | xargs)
    groups=$(echo "$groups" | xargs)

These lines remove any extra spaces from the username and groups variables using the xargs command.

 echo "Processing user: $username with groups: $groups"

This prints a message to the console showing which user and groups are being processed.

 # Simulate user and group creation
    log "Simulated creation of user $username with groups $groups"

This calls the log function to write a message to the log file (and the console) indicating that the user and groups are being "created" (simulated in this example).

# Generate random password
    password=$(openssl rand -base64 12)
    echo "Generated password for $username: $password"

This generates a random password for the user using the openssl rand -base64 12 command and stores it in the password variable. A message is printed to the console showing the generated password.

    # Store username and password
    echo "$username,$password" >> $PASSWORD_FILE
    echo "Stored password for $username in $PASSWORD_FILE"

This writes the username and password to the password file. The >> operator appends the information to the file. A message is printed to the console confirming that the password was stored.

done < "$FILE"

This ends the loop. The loop runs for each line in the input file until all lines have been processed.

# Final log message
log "User creation script completed successfully (simulated)"
echo "User creation script completed successfully (simulated)"

These lines call the log function to write a final message to the log file (and the console) indicating that the script has finished running successfully. The same message is also printed directly to the console.

exit 0

This line ends the script, indicating that it completed successfully.

How to run the script

  1. Prepare the input file: create a file that will contain usernames and groupnames

  2. Run the script: open your terminal, navigate to the directory that contains the "create_users.sh" file and the file you created. Then run;

     ./create_users.sh users.txt
    
  3. Check the console output: You should see messages indicating the progress of the script. messages like;

     Script started with argument: users.txt
     Using log file: ./user_management.log
     Using password file: ./user_passwords.csv
     Log file created at ./user_management.log
     Password file created at ./user_passwords.csv with permissions set to 600
     Processing user: light with groups: sudo,dev,www-data
     Generated password for light: <password>
     Stored password for light in ./user_passwords.csv
     Processing user: idimma with groups: sudo
     Generated password for idimma: <password>
     Stored password for idimma in ./user_passwords.csv
     Processing user: mayowa with groups: dev,www-data
     Generated password for mayowa: <password>
     Stored password for mayowa in ./user_passwords.csv
     User creation script completed successfully (simulated)
    
    1. Verify the log file: Open the user_management.log file to see a detailed log of actions:

       cat user_management.log
      

      The file should contain entries like:

       2024-07-03 11:33:33 - Simulated creation of user light with groups sudo,dev,www-data
       2024-07-03 11:33:34 - Simulated creation of user idimma with groups sudo
       2024-07-03 11:33:35 - Simulated creation of user mayowa with groups dev,www-data
       2024-07-03 11:33:36 - User creation script completed successfully (simulated)
      
      1. Verify the Password File: Open the user_passwords.csv file to see the generated passwords:

          cat user_passwords.csv
        

        The file should contain entries like:

         light,Os1VX3SAZtb7gaYx
         idimma,5Feq3GbF+Y8DvG6V
         mayowa,DzD2YIDp7xocMAJq
        

Conclusion

This script automates the process of user and group management, ensuring consistency and security. By logging actions and securely storing passwords, it provides an efficient and reliable solution for SysOps engineers.

For more information on how to navigate your tech journey, you can check out HNG internship and HNG hire