Automating User and Group Management with a Bash Script
Published: 2024-07-02 07:55:42

## Overview
For system administrators, maintaining user accounts and groups can be a tedious chore. Automating this process can save time and the possibility of human error. Our script, create_users.sh, makes this procedure simpler, which reads user and group data from a file and runs the required system commands.

## Script Breakdown
Let's break down the script to understand how it works.
### Script Initialization
```bash
#!/bin/bash
```
The shebang `#!/bin/bash` tells the system to execute the script using the Bash shell.

### Defining Color Codes
```
# Color codes
RED="\e[31m"
BLUE="\e[34m"
YELLOW="\e[33m"
YELLOW_ITALIC="\e[3;33m"
RESET="\e[0m"
```
We define color codes using ANSI escape sequences to make our script's output more readable. These colors will highlight different types of messages, such as errors, successes, and prompts.

### Logging Function
```
# Function to log actions with timestamps and color coding
log() {
    local COLOR="$2"
    local TEXT="$(date +"%Y-%m-%d %T") - $1"
    
    echo -e "${COLOR}${TEXT}${RESET}" | tee -a $LOG_FILE
}
```
Timestamped messages are formatted and logged by the log function. It appends these log entries to a log file and shows them on the terminal, using the designated color to distinguish between different log entry types.

### Password Generation Function
```
# Function to generate a random password
generate_password() {
    tr -dc A-Za-z0-9 </dev/urandom | head -c 12
}
```
This function generates a random 12-character password using the `/dev/urandom` pseudo-random number generator.

### Root User Check
```
# Check if the script is run as root
if [[ $EUID -ne 0 ]]; then
    echo -e "${RED}This script must be run as root or with sudo${RESET}"
    exit 1
fi
```
This block checks if the script is being run as the root user or with the sudo command. 

### Setting Up Log and Password Files
```
# Default log and password files
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"

# Ensure the log and password files exist with secure permissions
mkdir -p /var/secure
touch $LOG_FILE
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE
```
We define the paths for our log file and password file. The `mkdir -p /var/secure` command creates the secure directory if it doesn't exist.

### Input File Check
```
# Check if an input file is provided, otherwise prompt the user
if [[ "$#" -ne 1 ]]; then
    echo -e "${YELLOW}Enter the filename containing the user information: ${RESET}"
    read INPUT_FILE
else
    INPUT_FILE=$1
fi

# Validate the input file
if [[ ! -f $INPUT_FILE ]]; then
    log "Input file does not exist: $INPUT_FILE" "${RED}"  # Red color for errors
    exit 1
fi
```
This part checks if the script was given an input file as an argument. If not, it prompts the user to enter the filename. The script then checks if the file exists. If not, it logs an error and exits.

### Processing Each Line of the Input File
```
while IFS=';' read -r username groups; do
    # Remove leading and trailing whitespace
    username=$(echo $username | xargs)
    groups=$(echo $groups | xargs)

    # Check if the username is empty
    if [[ -z "$username" ]]; then
        log "Empty username. Skipping..." "${YELLOW_ITALIC}"  # Yellow color for skipped (italic)
        continue
    fi

    # Check if the user already exists
    if id "$username" &>/dev/null; then
        log "User $username already exists. Skipping..." "${YELLOW_ITALIC}"  # Yellow color for skipped (italic)
        continue
    fi

    # Create the user with a home directory
    useradd -m -s /bin/bash "$username"
    if [[ $? -ne 0 ]]; then
        log "Failed to create user $username. Skipping..." "${RED}"  # Red color for errors
        continue
    fi
    log "Created user $username with home directory /home/$username" "${BLUE}"  # Blue color for success

    # Set home directory permissions
    chown "$username:$username" "/home/$username"
    chmod 700 "/home/$username"
    log "Set permissions for /home/$username" "${BLUE}"  # Blue color for success

    # Create and add the user to additional groups
    IFS=',' read -ra group_array <<< "$groups"
    for group in "${group_array[@]}"; do
        group=$(echo $group | xargs)  # Remove whitespace
        if [[ ! $(getent group $group) ]]; then
            groupadd $group
            if [[ $? -eq 0 ]]; then
                log "Created group $group" "${BLUE}"  # Blue color for success
            else
                log "Failed to create group $group. Skipping group assignment for $username." "${RED}"  # Red color for errors
                continue
            fi
        fi
        usermod -aG "$group" "$username"
        log "Added user $username to group $group" "${BLUE}"  # Blue color for success
    done

    # Generate and set a random password for the user
    password=$(generate_password)
    echo "$username,$password" >> $PASSWORD_FILE
    echo "$username:$password" | chpasswd
    log "Set password for user $username" "${BLUE}"  # Blue color for success

done < "$INPUT_FILE"
```
This is the core part of the script. It processes each line of the input file, which is expected to have the format `username;group1,group2,....`
- **Whitespace Removal:** We remove leading and trailing whitespaces from usernames and groups.
- **Empty Username Check:** If a username is empty, it logs a message and skips to the next line.
- **User Existence Check:** If the user already exists, it logs a message and skips to the next user.
- **User Creation:** If the user doesn't exist, it creates the user with a home directory and logs the action.
- **Set Permissions:** It sets appropriate permissions for the user's home directory.
- **Group Management:** The script ensures each group exists and adds the user to the specified groups.
- **Password Management:** It generates a random password, sets it for the user, and securely logs it.

### Final Log and Script Exit
```
log "User creation process completed." "${BLUE}"  # Blue color for success

exit 0
```
The script logs that the user creation process is complete and exits with a status code of 0, indicating success.

### How to Run the Script

To execute the script, follow these steps:

1. **Ensure the script has executable permissions**:
   ```
   bash
   chmod +x create_users.sh
  ```
2. **Prepare the input file as shown below;**
 ```
Lagos;sudo,dev,www-data
Abuja;sudo
Lokoja;dev,www-data
```
3. **Run the script with the input file as an argument:**
    ```
sudo bash create_users.sh file.txt 
```
Find the complete code [Here.](https://github.com/Afeez-AA/HNG1.git) 

### CONCLUSION
Administrative operations can be greatly streamlined by using Bash scripts to automate user and group management. This script shows how to create users, manage groups, handle passwords safely, and read user information from a file.

You are welcome to alter this script to meet your own requirements; just keep in mind that scripts should always be tested in a secure setting before being used in production.

For more insights and opportunities to grow as a developer, check out the [HNG Internship](https://hng.tech/internship) and explore how to [hire talented developers](https://hng.tech/hire) through the HNG platform.