Automate User and Group Management with a Bash Script
Tags: devops, linux, bash, automation
Published: 2024-07-06 01:02:40


Managing users and groups on a Linux system can be a daunting task, especially when you have to handle a large number of users. Automation is the key to simplifying these repetitive tasks, ensuring consistency, and reducing the likelihood of errors. In this article, we'll explore a bash script that automates the creation of users and groups, sets up home directories, generates random passwords, and logs all actions. 

We'll walk through each step of the script, explaining the rationale behind the code, and provide links to the HNG Internship program, a great opportunity for budding developers to enhance their skills.

**Why Automate User Management?**
Before diving into the script, let's understand why automating user management is beneficial:

1. **Consistency**: Automation ensures that users are created with the same settings, reducing the risk of configuration errors.
2. **Efficiency**: Batch processing user accounts saves time compared to manual entry.
3. **Security**: Automatically setting secure passwords and proper permissions enhances security.
4. **Logging**: Keeping a log of all actions aids in auditing and troubleshooting.

**The Script**
Below is the bash script that performs all the tasks mentioned. It reads a text file containing usernames and group names, creates users and groups, sets up home directories, generates random passwords, and logs actions.

```bash
#!/bin/bash

# Script to create users and groups from a given text file
# Usage: bash create_users.sh <name-of-text-file>
# Example: bash create_users.sh users.txt

# Log file
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"

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

INPUT_FILE=$1

# Ensure the log and password files exist
touch $LOG_FILE
mkdir -p /var/secure
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE

log_action() {
  echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
}

create_user() {
  local username=$1
  local groups=$2

  # Create the user's personal group
  if ! getent group $username > /dev/null 2>&1; then
    groupadd $username
    log_action "Created group $username"
  else
    log_action "Group $username already exists"
  fi

  # Create user
  if ! id -u $username > /dev/null 2>&1; then
    useradd -m -g $username -s /bin/bash $username
    log_action "Created user $username"
  else
    log_action "User $username already exists"
    return
  fi

  # Assign additional groups to the user
  IFS=',' read -ra group_array <<< "$groups"
  for group in "${group_array[@]}"; do
    group=$(echo $group | xargs) # Remove leading/trailing whitespaces
    if ! getent group $group > /dev/null 2>&1; then
      groupadd $group
      log_action "Created group $group"
    fi
    usermod -aG $group $username
    log_action "Added user $username to group $group"
  done

  # Generate a random password for the user
  local password=$(openssl rand -base64 12)
  echo "$username:$password" | chpasswd
  log_action "Set password for user $username"

  # Store the password securely
  echo "$username,$password" >> $PASSWORD_FILE
}

while IFS=';' read -r username groups; do
  username=$(echo $username | xargs) # Remove leading/trailing whitespaces
  groups=$(echo $groups | xargs)     # Remove leading/trailing whitespaces
  create_user $username "$groups"
done < $INPUT_FILE

log_action "User creation script completed"
```

## Breaking Down the Script

### Script Header and Usage

The script starts with a shebang (`#!/bin/bash`), indicating it should be run in a bash shell. A usage message is provided if the script is not run with the correct arguments, ensuring users know how to execute it properly.

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

### Log and Password Files

We define `LOG_FILE` and `PASSWORD_FILE` for logging actions and storing passwords securely. The script ensures these files and directories are created with appropriate permissions.

```bash
# Log file
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"

# Ensure the log and password files exist
touch $LOG_FILE
mkdir -p /var/secure
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE
```

### Logging Function

The `log_action()` function logs messages with timestamps to the log file, providing a record of actions performed by the script.

```bash
log_action() {
  echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
}
```

### User Creation Function

The `create_user()` function handles the creation of users and their personal groups. It checks if a group or user already exists and creates them if they don't. It assigns users to additional groups specified in the input file and generates a random password for each user.

```bash
create_user() {
  local username=$1
  local groups=$2

  # Create the user's personal group
  if ! getent group $username > /dev/null 2>&1; then
    groupadd $username
    log_action "Created group $username"
  else
    log_action "Group $username already exists"
  fi

  # Create user
  if ! id -u $username > /dev/null 2>&1; then
    useradd -m -g $username -s /bin/bash $username
    log_action "Created user $username"
  else
    log_action "User $username already exists"
    return
  fi

  # Assign additional groups to the user
  IFS=',' read -ra group_array <<< "$groups"
  for group in "${group_array[@]}"; do
    group=$(echo $group | xargs) # Remove leading/trailing whitespaces
    if ! getent group $group > /dev/null 2>&1; then
      groupadd $group
      log_action "Created group $group"
    fi
    usermod -aG $group $username
    log_action "Added user $username to group $group"
  done

  # Generate a random password for the user
  local password=$(openssl rand -base64 12)
  echo "$username:$password" | chpasswd
  log_action "Set password for user $username"

  # Store the password securely
  echo "$username,$password" >> $PASSWORD_FILE
}
```

### Main Loop

The script reads the input file line by line, trims any leading/trailing whitespaces from usernames and groups, and calls `create_user()` for each line in the input file.

```bash
while IFS=';' read -r username groups; do
  username=$(echo $username | xargs) # Remove leading/trailing whitespaces
  groups=$(echo $groups | xargs)     # Remove leading/trailing whitespaces
  create_user $username "$groups"
done < $INPUT_FILE
```

### Execution and Logging

After processing the input file, a completion message is logged, indicating the script has finished executing.

```bash
log_action "User creation script completed"
```

**Conclusion**

Automating user and group management with a bash script not only simplifies administrative tasks but also enhances consistency and security. By following this guide, you can efficiently manage user accounts and groups on your system.

For more information on internship opportunities and to learn how you can hire talent from the HNG Internship program, visit the [HNG Internship website](https://hng.tech/internship) and explore how you can [hire top talent](https://hng.tech/hire).