User and groups creation automation in linux
Published: 2024-07-02 22:53:48

**Hey there! Ever wondered how tech teams smoothly integrate new members into their systems? Scripting has become the unsung hero! Imagine effortlessly setting up user accounts, creating personalized groups, and ensuring security—all with a few lines of code. In this article, we'll explore how automation through scripting not only simplifies complex tasks but also minimizes errors and maximizes efficiency.**

**In this article, we will be creating a Bash script that helps create users and groups on the fly. This is part of a task assigned during the [HNG Internship](https://hng.tech/internship). The internship also provides a [premium](https://hng.tech/premium) service at a stipend, exposing you to many more opportunities.**

**Anyways, let's get to the party.**

**Tools needed:**

1. Unix (Linux, macOS, WSL)
2. Editor (Vim, Vi, Nano, VSCode). I will be using Vim as the editor of choice; here is a link to learn more about [Vim](https://www.vim.org/).

## Scripting

First, create a file that will contain the script using `touch create_users.sh`. You can also create and open the file simultaneously using Vim.

```bash
touch create_users.sh
vim create_users.sh
```

At the start of the script, we need to ensure that only privileged users with root privileges can execute the script.

```bash
#!/bin/bash

# Check if running as root
if [[ $UID -ne 0 ]]; then
   echo "This script must be run as root" 
   exit 1
fi
```

The script checks if the user and group file exists. This is important for error handling and preventing repetition.

```bash
# Check if the file with users and their corresponding groups exists
USER_FILE=$1
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"

# Create the log and password files if they do not exist
mkdir -p /var/secure /var/log
touch $PASSWORD_FILE
touch $LOG_FILE
# make password file secure (read and write permissions for file owner only)
chmod 600 $PASSWORD_FILE
```
Next, we define a function to log activities into the log file.

```bash
# function to log actions to log file
log_action() {
    echo "$(date) - $1" >> $LOG_FILE
}
```

We create a function to handle user creation. This function will also manage group assignments and password generation.

```bash
# Function to create a user
create_user() {
    local user=$1         # Username passed as parameter
    local groups=$2       # Groups passed as parameter
    local password        # Variable to store generated password

    # Check if user already exists
   if id "$user" &>/dev/null; then
        log "User $user already exists."
        return
    else

    # Create personal group for the user
    groupadd "$user"

    # Create the user with specified groups and assign a home directory

     useradd -m -s /bin/bash -g "$user" "$user"
    if [ $? -eq 0 ]; then
        log "User $user created with primary group: $user"
    else
        log "Failed to create user $user."
        return
    fi

 # Generate a random password for the user
    password=$(openssl rand -base64 15)

  # Set user's password using chpasswd
    echo "$user:$password" | chpasswd
    
    # Store the password securely in the password file
    echo "$user:$password" >> $PASSWORD_FILE

    # Set permissions for the user's home directory
    if [ ! -d "/home/$user" ]; then
        mkdir -p "/home/$user"
        chown -R "$user:$user" "/home/$user"
        chmod 700 "/home/$user"
        log "Created home directory for $user"
    fi

   log "Password for user $user created and stored securely."
fi

    # Check and create required groups if they don't exist
    IFS=' ' read -ra group_list <<< "$groups"

    # Log the group array
    log "User $user will be added to groups: ${group_array[*]}"

    for group in "${group_array[@]}"; do
        group=$(echo "$group" | xargs)  # Trim whitespace
        if ! getent group "$group" &>/dev/null; then
            groupadd "$group"
            log "Group $group created."
        fi
    done

    # Add the user to additional groups
    for group in "${group_array[@]}"; do
        usermod -aG "$group" "$user"
    done
    log "User $user added to groups: ${group_array[*]}"

```
This checks the list of names and groups in the provided file
```
# check if user list file is provided
if [ $# -ne 1 ]; then
    echo "Usage: $0 <user_list_file>"
    exit 1
fi

filename="$1"

if [ ! -f "$filename" ]; then
    echo "Users list file $filename not found."
    exit 1
fi
```
Next, the script reads the user file and processes each entry to create the users.

```bash
# read user list file and create users
while IFS=';' read -r user groups; do
    user=$(echo "$user" | xargs)
    groups=$(echo "$groups" | xargs | tr -d ' ')

    # Replace commas with spaces for usermod group format
    groups=$(echo "$groups" | tr ',' ' ')
    create_user "$user" "$groups"
done < "$filename"

echo "Done. Check /var/log/user_management.log for details."
```

**Testing**

Make the script executable:

```bash
chmod +x create_users.sh
```

Now, to test the script, create a simple CSV file:

```bash
vim user_data.csv
```

Add the following content to `user_data.csv`:

```
light; sudo,dev,www-data
idimma; sudo
mayowa; dev,www-data
emeka; admin,dev
sarah; www-data
john; admin,sudo,dev
```

Check the log file to get the output:

```bash
sudo cat /var/log/user_management.log
```

And check the password file to see the generated passwords:

```bash
sudo cat /var/secure/user_passwords.txt
```

## Outro

If you got to this point, and your script was able to create the users and group, then **Congratulations**

You can check out my Github for the [link](https://github.com/Celestina-OG/auto-user-creation.git) to the full script that you can clone and run directly in your terminal.

![cheers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ngi9sm4snoj8nv9mrd5r.jpeg)