Linux User Creation Automation with Bash Script
Published: 2024-07-03 21:27:55

## Introduction
Manually creating users and adding them to groups is a tedious and error-prone task, consuming valuable time and energy that could be better spent on more productive activities. Automating this process eliminates these issues, offering a more consistent, efficient, and time-saving solution. In this article, we'll walk through a bash script designed to read user details from a text file, create users and their specific groups, and log all activities.

## Script Overview
The full script is available in a GitHub repository at [here](https://github.com/ella-adeka/hngstage1_linuxusercreation.git).

Let's walk through the steps in the script of automating user management (creation):

**1. Verify the input file**
Check that an input file has been specified. It ensures that the number of arguments provided is exactly one. If not, it outputs an error message with usage instructions and exits the script.
 ```bash
# Verify that an input file has been specified
# checks the number of arguments ($#) is not equal to 1 (-ne)
if [[ $# -ne 1 ]]; then
    echo "Error: No input file specified."
    echo "usage: $(basename "$0") <input_file>"
    exit 1
fi
```

**2. Set the files as variables**
Define variables for the log file and the password file. 
`LOG_FILE` is used to record all actions taken by the script, and `PASSWORD_FILE` is where the generated passwords will be stored securely.
```bash
# Log file to log all actions
LOG_FILE="/var/log/user_management.log"
# store generated passwords in user_passwords.txt
PASSWORD_FILE="/var/secure/user_passwords.txt"
``` 
 
**3. Ensure both files exist**
Ensure that the log file and the password file exist. This section of the script creates the files if they don't already exist and sets the appropriate permissions on the password file to ensure only the owner can read it.
```bash
# Ensure both files exist
touch $LOG_FILE
mkdir -p /var/secure
touch $PASSWORD_FILE

# Set permissions for password file
chmod 600 $PASSWORD_FILE
```

**4. Install password generator package**
This script is designed specifically for Ubuntu. If you're using a different Linux distribution, you'll need to adapt the package installation commands accordingly. For Ubuntu, you can install the `pwgen` utility, which generates random passwords, with the following commands:
```bash
# install pwgen to generate random password
sudo apt-get update
sudo apt-get install -y pwgen

# verify installation
if ! pwgen --version &>/dev/null; then
    echo "Error: pwgen installation failed." | tee -a $LOG_FILE
    exit 1
fi
```

**5. Create function to generate password using the installed package**
The `generate_password` function utilises the `pwgen` utility to generate secure, random passwords. By default, it creates a 12-character password, but you can specify a different length by passing a parameter to the function. The `-s` option ensures the password is completely random.
```bash
generate_password() {
    local password_length=${1:-12}
    pwgen -s $password_length 1
}
```

**6. Create function to create user**
```bash
create_user() {
    # Create user group with same name as user
    # check iff user exists
    # create user with group
    # set permissions
    # generate random password and set it
    # store password securely
    # add user to group

    local user=$1
    shift
    local groups=$@

    # Check if user already exists
    if id "$user" &>/dev/null; then
        echo "User $user already exists." | tee -a $LOG_FILE
        return 0
    fi

   
    if ! sudo groupadd "$user" 2>>$LOG_FILE; then
        echo "Failed to create group $user." | tee -a $LOG_FILE
        return 1
    fi

    # Create user and set their primary group
    if ! sudo useradd -m -g "$user" "$user" 2>>$LOG_FILE; then
        echo "Failed to create user $user." | tee -a $LOG_FILE
        return 1
    fi

    # Create additional groups if specified and add the user to them
    if [[ -n "$groups" ]]; then
        for group in $groups; do
            if ! getent group "$group" &>/dev/null; then
                if ! sudo groupadd "$group" 2>>$LOG_FILE; then
                    echo "Failed to create group $group." | tee -a $LOG_FILE
                    return 1
                fi
            fi
            if ! sudo usermod -aG "$group" "$user" 2>>$LOG_FILE; then
                echo "Failed to add user $user to group $group." | tee -a $LOG_FILE
                return 1
            fi
        done
    fi

    # Generate random password
    local password
    password=$(generate_password)
    if ! echo "$user:$password" | sudo chpasswd; then
        echo "Failed to set password for user $user." | tee -a $LOG_FILE
        return 1
    fi

    # Store password securely
    echo "$user:$password" >>$PASSWORD_FILE

    # Set permissions for user's home directory
    if ! sudo chmod 700 "/home/$user"; then
        echo "Failed to set permissions for home directory of user $user." | tee -a $LOG_FILE
        return 1
    fi

    # Log the user creation
    echo "Created user $user with groups: $groups" | tee -a $LOG_FILE
}
```

**7. Read the file and create users**
This section of the script reads the user information from the specified file. It processes each line to extract the username and groups, removing any leading or trailing whitespace. The groups are converted from a comma-separated list to a space-separated list. Finally, it calls the create_user function to create the user and assign the specified groups.
```bash
while IFS=";" read - r user groups; do
    # remove whitespaces before and after username
    user=$(echo $user | xargs) 
    # remove whitespaces before and after group name
    groups=$(echo $groups | xargs | tr ',' ' ')
    create_user $user $groups
done < "$1" 
```

**8. Output once script has run successfully**
Output a message indicating that the user has been created successfully. The message is also appended to the log file to keep a record of the script's actions.
```bash
echo "User created successfully." | tee -a $LOG_FILE
```

## Conclusion
Automating user management with a bash script streamlines administrative tasks, ensuring consistency and security. By following the steps in this script, you can efficiently manage user accounts and groups in a Linux environment.

## Learn more
Learn more about HNG internships and opportunities below: 
[HNG internship](https://hng.tech/internship)
[HNG Premium](https://hng.tech/premium)