Scripting Wizardry: Automating User and Group Creation Like a Pro
Tags: linux, devops, bash, scripting
Published: 2024-07-03 15:56:48

#Introduction
In the world of system administration, managing users and groups is a crucial task. As organizations grow, manually creating and maintaining user accounts and group memberships can become a tedious and error-prone process. Fortunately, Bash scripting provides a powerful solution to automate this process, saving time and ensuring consistency.

In this blog post, we will go through a bash script that streamlines user and group creation, and password generation. We'll break down the script section by section, explaining its functionality and the rationale behind the design choices.

#The Script Breakdown

### Shebang and Log/Password Paths 
`#!/bin/bash` indicates that the script, named create_users.sh, should be run using bash.

The script starts by defining the paths for the log and password files. It then creates the necessary directories and files if they don't exist, setting appropriate permissions to ensure secure access.
```
#!/bin/bash

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

#Ensure the necessary directories exist and set permissions
sudo mkdir -p /var/log
sudo mkdir -p /var/secure

# Create the log and password files if they do not exist and set permissions
sudo touch $LOG_FILE
sudo chmod 600 $LOG_FILE
sudo touch $PASSWORD_FILE
sudo chmod 600 $PASSWORD_FILE
```

### Input Validation
Before proceeding, the script checks if an input file containing user data is provided as an argument. If no file is provided, it exits with an error message, ensuring proper usage.

```
# Check if the input file is provided
if [ -z "$1" ]; then
    echo "Error: Please provide a text file containing user data as an argument."
    exit 1
fi
```

### Processing User Data
The script reads the input file line by line, where each line represents a user entry. It skips empty lines and extracts the usernames and groups from each line using a delimiter (in this case, a semicolon).

```
# Read the input file line by line
while IFS= read -r line; do
    # Skip empty lines
    [ -z "$line" ] && continue
```

### User and Group Creation
For each user, the script first checks if the user's personal group exists. If not, it creates the group. Then, it checks if the user already exists. If not, it creates the user account and assigns the personal group as the primary group.

```
 # Extract username and groups
    IFS=';' read -r username groups <<< "$line"
    username=$(echo $username | xargs) # Trim whitespace
    groups=$(echo $groups | xargs)     # Trim whitespace

    # Create the user's personal group if it doesn't exist
    if ! getent group "$username" > /dev/null; then
        groupadd "$username"
        echo "$(date): Created group $username" >> $LOG_FILE
    fi

    # Create the user if it doesn't exist
    if ! id -u "$username" > /dev/null 2>&1; then
        useradd -m -g "$username" "$username"
        echo "$(date): Created user $username" >> $LOG_FILE
    fi
```

### Group Membership Management
The script parses the list of groups for each user, separated by commas. It checks if each group exists and creates it if necessary. Then, it adds the user to the specified groups using the `usermod` command.

```
# Add the user to the specified groups
    IFS=',' read -ra group_array <<< "$groups"
    for group in "${group_array[@]}"; do
        group=$(echo $group | xargs) # Trim whitespace
        if ! getent group "$group" > /dev/null; then
            groupadd "$group"
            echo "$(date): Created group $group" >> $LOG_FILE
        fi
        usermod -aG "$group" "$username"
        echo "$(date): Added $username to group $group" >> $LOG_FILE
    done
```
### Password Generation 
For each user, the script generates a random password using the `openssl` command. It appends the username and password to the password file and sets the user's password using the `chpasswd` command.

```
 # Generate a random password
    password=$(openssl rand -base64 12)
    echo "$username,$password" >> $PASSWORD_FILE

    # Set the user's password
    echo "$username:$password" | chpasswd
    echo "$(date): Set password for $username" >> $LOG_FILE
```

### Home Directory Configuration and Logging
Finally, the script sets the appropriate permissions and ownership for the user's home directory, ensuring secure access.

Throughout the process, the script logs all operations performed, including user and group creation, password setting, and permission changes, along with timestamps. This logging mechanism provides a detailed audit trail and aids in troubleshooting.

```
 # Set permissions and ownership for the home directory
    chown -R "$username:$username" "/home/$username"
    chmod 700 "/home/$username"
    echo "$(date): Set permissions for /home/$username" >> $LOG_FILE
```

# How to Run the Script
* Create the users file with:
```nano users.txt``` 
Add your users and their groups in this format: user; groups

```
bammy; sudo,dev,www-data
john; sudo
doe; dev,www-data
jane; www-data
```
Save and exit the file with ctrl+o, followed by enter to save; then ctrl+x to exit.

* Make the script and file executable
```
chmod +x create_users.sh
chmod +x users.txt
```
* Run the script and pass the user file as an argument
```
sudo ./create_users.sh users.txt
```

#Conclusion
Automating user and group creation with Bash scripts can significantly streamline system administration tasks, reducing manual effort and ensuring consistency. The provided script offers a comprehensive solution for creating users and groups, generating passwords, and configuring home directories. By understanding the script's functionality and following best practices, you can leverage its power while maintaining a secure and efficient user management process.

This article is Task 2 in the DevOps track of the HNG Internship. To learn more about HNG, visit https://hng.tech/internship.