My Exciting Journey with HNG STAGE ONE: Automating User Management with Bash Script
Tags: beginners, devops, aws, hng
Published: 2024-07-03 18:05:47

I  am on an interesting journey with the [HNG](https://hng.tech/) Internship.  Being on the DevOps track, my  first project is creating a Bash script to automate user management on a Linux server. Let's dive into the details and see how this script simplifies the task of creating and managing users and groups efficiently.

**Prerequisites:**
You need access to a Linux environment (e.g., Ubuntu).
Basic understanding of how to run scripts and manage files in a Linux terminal.
Ensure you have permissions to create users, groups, and files.

**Requirements:**
Input File Format:
The script will read a text file where each line is formatted as `username;groups`.
Example:

```bash
Esther; admin,dev
Felix; dev,tester
Peter; admin,tester
```

Script Actions:
Create users (Esther, Felix, Peter) and their personal groups (Esther, Felix, Peter).
Assign users to specified additional groups (admin, dev, tester).
Set up home directories for each user with appropriate permissions.
Generate random passwords for each user.
Log all actions to /var/log/user_management.log.
Store passwords securely in /var/secure/user_passwords.txt.
Handle errors gracefully, such as existing users or groups.

**Step 1:**
** Script Initialization and Setup**
 Set up the initial environment for the script, including defining file locations and creating necessary directories.

Define File Locations: Initializes paths for logging and password storage.
Define variables for log and password file paths (LOG_FILE, PASSWORD_FILE).
Create Directories:Ensures necessary directories exist.
Ensure the directories /var/log and /var/secure exist.
Set File Permissions:Sets secure permissions for sensitive files.
Create and set permissions (600 for password file, 644 for log file) for the log and password files.

```bash
#!/bin/bash
# Ensure the log file exists
touch $LOG_FILE
chmod 644 $LOG_FILE
# Define log and password file locations
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"
# Create directories if they don't exist
mkdir -p /var/log
mkdir -p /var/secure
# Ensure the password file is secure
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE
```



**Step 2:**
**Logging Function Creation**
Create a function to log actions performed by the script with timestamps.
Define Logging Function: log_action ensures all script activities are logged with timestamps while timestamps helps track when each action occurred for auditing and debugging purposes.
Create a function log_action that appends messages with timestamps to the log file.



```bash
# Function to log messages with timestamps
log_action() {
  echo "$(date '+%Y-%m-%d %H:%M:%S') : $1" >> $LOG_FILE
}

```

**Step 3:**
**Argument Checking****
Verify that the script is provided with the correct number of arguments.

Argument Check: Ensures script execution is correctly formatted and file existence check confirms the existence of the specified user list file for further processing.

Ensure the script is executed with one argument (the user list file).
Exit with an error message if the argument count is incorrect.

```bash
# Check if correct number of arguments provided
if [ $# -ne 1 ]; then
  log_action "Usage: $0 <user-list-file>. Exiting."
  exit 1
fi

USER_LIST_FILE=$1

# Check if user list file exists
if [ ! -f $USER_LIST_FILE ]; then
  log_action "File $USER_LIST_FILE does not exist! Exiting."
  exit 1
fi
```


**Step 4:**
**Reading and Processing User List**
Read each line from the user list file, extracting usernames and associated groups.
Read File Content: Uses while loop to read and process each line in the user list file and utilizes xargs to remove leading and trailing whitespace from extracted data.

Iterate through each line in the user list file.
Extract username and associated groups from each line.

```bash
# Process each line in the user list file
while IFS=';' read -r username groups; do
  username=$(echo $username | xargs)
  groups=$(echo $groups | xargs)

  # Further actions based on extracted data will be performed in subsequent steps.
done < $USER_LIST_FILE
```


 **Step 5:**
**User Existence Checking and Creation**
 Verify if each user already exists; if not, create the user.
Check User Existence:Determines if the user already exists.  Skips creation if the user exists; otherwise, creates the user and logs the outcome.
Use id -u command to check if the user already has an assigned ID.
Skip user creation if the ID exists, log the action.

```bash
# Check if the user already exists
if id -u $username >/dev/null 2>&1; then
  log_action "User $username already exists. Skipping."
  continue
fi

# Create the user if they do not exist
useradd -m $username
if [ $? -eq 0 ]; then
  log_action "User $username created successfully."
else
  log_action "Failed to create user $username."
  continue
fi
```

**Step 6:**
**Group Handling**
 Create required groups for each user and assign them appropriately.

Process Group List: Iterates through each group associated with the user, creating any new groups as needed. Then user modification Uses usermod to assign the user to each specified group and logs the action.
Split the groups variable to handle each group associated with the user.
Create any new groups if they do not exist.

```bash
# Assign user to specified additional groups
IFS=',' read -ra USER_GROUPS <<< "$groups"
for group in "${USER_GROUPS[@]}"; do
  group=$(echo $group | xargs)
  if ! getent group $group >/dev/null; then
    groupadd $group
    if [ $? -eq 0 ]; then
      log_action "Group $group created successfully."
    else
      log_action "Failed to create group $group."
      continue
    fi
  fi
  usermod -aG $group $username
  log_action "User $username added to group $group."
done
```

**Step 7:**
**Home Directory Setup**
Ensure each user has a home directory set up with appropriate permissions.

Directory Permissions: Adjusts permissions and ownership for the user's home directory to provide appropriate access rights.

Set permissions (chmod, chown) for the user's home directory (/home/$username).

```bash
# Set up home directory permissions
chmod 755 /home/$username
chown $username:$username /home/$username

```
**Step 8:**
**Password Generation and Storage**
Generate a secure password for each user and store it securely.

Password Generation: For password security, utilize a secure method (date +%s | sha256sum | base64) to generate a random password and for storage append username and password to the password file and logs the successful password creation.
Create a randomly generated password for each user.

```bash
# Generate and store password securely
password=$(date +%s | sha256sum | base64 | head -c 12 ; echo)
echo "$username,$password" >> $PASSWORD_FILE
log_action "Password for user $username set successfully."
```


**Step 9:**
**Script Completion and Finalization**
Conclude the script execution, logging the completion of all actions.
Script Conclusion: Logs a final message confirming successful script execution, providing a clear end to the script's operations.
Add a final log entry to indicate the completion of script execution.

```bash
# Final log entry
log_action "Script execution completed."
```

 Now let's put it all together

```bash

#!/bin/bash

# Step 1: Define File Locations
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"

# Step 2: Create Directories
mkdir -p /var/log
mkdir -p /var/secure

# Step 3: Set File Permissions
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE
touch $LOG_FILE
chmod 644 $LOG_FILE

# Step 4: Define Logging Function
log_action() {
  echo "$(date '+%Y-%m-%d %H:%M:%S') : $1" >> $LOG_FILE
}

# Step 5: Argument Checking
if [ $# -ne 1 ]; then
  log_action "Usage: $0 <user-list-file>. Exiting."
  exit 1
fi

USER_LIST_FILE=$1

if [ ! -f $USER_LIST_FILE ]; then
  log_action "File $USER_LIST_FILE does not exist! Exiting."
  exit 1
fi

# Step 6: Reading and Processing User List
while IFS=';' read -r username groups; do
  username=$(echo $username | xargs)
  groups=$(echo $groups | xargs)

  # Step 7: User Existence Checking and Creation
  if id -u $username >/dev/null 2>&1; then
    log_action "User $username already exists. Skipping."
    continue
  fi

  useradd -m $username
  if [ $? -eq 0 ]; then
    log_action "User $username created successfully."
  else
    log_action "Failed to create user $username."
    continue
  fi

  # Step 8: Group Handling
  IFS=',' read -ra USER_GROUPS <<< "$groups"
  for group in "${USER_GROUPS[@]}"; do
    group=$(echo $group | xargs)
    if ! getent group $group >/dev/null; then
      groupadd $group
      if [ $? -eq 0 ]; then
        log_action "Group $group created successfully."
      else
        log_action "Failed to create group $group."
        continue
      fi
    fi
    usermod -aG $group $username
    log_action "User $username added to group $group."
  done

  # Step 9: Home Directory Setup
  chmod 755 /home/$username
  chown $username:$username /home/$username
  log_action "Home directory permissions set for user $username."

  # Step 10: Password Generation and Storage
  password=$(date +%s | sha256sum | base64 | head -c 12 ; echo)
  echo "$username,$password" >> $PASSWORD_FILE
  log_action "Password for user $username set successfully."

done < $USER_LIST_FILE

# Step 11: Script Completion and Finalization
log_action "Script execution completed."
```

Now let’s get to the interesting part.

 Save the file (create_user.sh) to  github repository.
 Clone to Linux server.



![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wky0fj1unc0t5z32fvdw.png)



Ensure create_users.sh has executable permissions: 
`chmod +x create_users.sh`


![output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pa0wgz0z0hafe2wczhcp.png)


Create a file named user_list.txt with entries formatted as:

```bash
`username1;group1,group2 
username2;group3`

```



![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rgprs23dskd3xxcjfxci.png)


Run the script providing the user list file as an argument:


`./create_users.sh user_list.txt`


View logs of script actions 
`nano /var/log/user_management.log`


![result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kv7705vfrkggxmmcooba.png)


Yeaaa!!!!!!!
We have successfully created a Bash script (create_users.sh) that automates the creation of users, management of groups, and secure handling of passwords.



visit HNG Internship today at [HNG](https://hng.tech/premium) to be part of this wonderful experience.