Automating User Managment system with Bash: in a linux environment.
Published: 2024-07-03 07:41:28

Onboarding several new workers can make managing users on a Linux system a repetitious chore. This procedure may be automated to save time and lower the possibility of human mistake. This tutorial will walk you through creating a bash script that creates users, assigns them to groups, configures their home directories, and generates passwords based on information retrieved from a text file. We'll also make sure that passwords are safely saved and that all activities are recorded.


**Basic requirements**

1. a Linux system having root (administrative) rights.

2. basic familiarity with bash scripting.

3.A text editor for creating and editing files (such as vim or nano)

**How to Use the Script**
Follow these steps to use the create_users.sh script:

**Clone the Repository**: Start by cloning the GitHub repository to your local machine or server.

```
git clone https://github.com/Maurice-Makafui/STAGE_1_HNG_11.git
cd STAGE_1_HNG_11
```

**Prepare the Input File**: Create a text file with the desired usernames and groups. Each line should be formatted as username;group1,group2,group3. Here’s an example:

plaintext

```
Maurice1;staging,development,deployment
Gwenny;prayergroup
Felix;fitness,gymgroup
```
**Run the Script**: Execute the script with the input file as an argument.

```
sudo bash ./create_users.sh users.txt
```


**Verify the Results**:

Check the Passwords:

```
cat /var/secure/user_passwords.csv
```

**Check the Log File**:

```
cat /var/log/user_management.log
```

**List Users and Groups**:

```
cat /etc/passwd
cat /etc/group

```

**Verify Home Directories**:

```
cd /home && ls
```

**Check Group Membership**:

```
getent group dev
```





**Here is what the Bash Script looks like**

```
#!/bin/bash

# Log file location
LOGFILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"

# Ensure the script is run as root
if [[ "$EUID" -ne 0 ]]; then
  echo "Please run as root"
  exit 1
fi

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

# Create log and password files
mkdir -p /var/secure
touch "$LOGFILE" "$PASSWORD_FILE"
chmod 600 "$PASSWORD_FILE"

# Function to generate a random password
generate_random_password() {
    local length=${1:-12} # Default length is 12 if no argument is provided
    LC_ALL=C tr -dc 'A-Za-z0-9!?%+=' < /dev/urandom | head -c $length
}

# Function to create a user
create_user() {
  local username=$1
  local groups=$2

  if getent passwd "$username" > /dev/null; then
    echo "User $username already exists" | tee -a "$LOGFILE"
  else
    useradd -m -g "$username" -s /bin/bash "$username"
    echo "Created user $username" | tee -a "$LOGFILE"
  fi

  # Create the user's personal group
  if ! getent group "$username" > /dev/null; then
    groupadd "$username"
    echo "Created group $username" | tee -a "$LOGFILE"
  fi

  # Add user to specified groups
  IFS=',' read -r -a groups_array <<< "$groups"
  for group in "${groups_array[@]}"; do
    if ! getent group "$group" >/dev/null; then
      groupadd "$group"
      echo "Created group $group" | tee -a "$LOGFILE"
    fi
    usermod -aG "$group" "$username"
    echo "Added user $username to group $group" | tee -a "$LOGFILE"
  done

  # Set up home directory permissions
  chmod 700 /home/"$username"
  chown "$username:$username" /home/"$username"
  echo "Set up home directory for user $username" | tee -a "$LOGFILE"

  # Generate a random password
  password=$(generate_random_password)
  echo "$username:$password" | chpasswd
  echo "$username,$password" >> "$PASSWORD_FILE"
  echo "Set password for user $username" | tee -a "$LOGFILE"
}

# Read the input file and create users
while IFS=';' read -r username groups; do
  # Skip empty lines
  if [[ -z "$username" ]]; then
    continue
  fi
  create_user "$username" "$groups"
done < "$1"

echo "User creation process completed." | tee -a "$LOGFILE"
```


**Heres the breakdown**

 
 1. Shebang and Variable Definitions

```
#!/bin/bash

# Log file location
LOGFILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"

```



#!/bin/bash: Specifies that the script should be run with the Bash shell.

LOGFILE: Path to the log file where script actions will be recorded.

PASSWORD_FILE: Path to the file where usernames and passwords will be saved.

2. Check for Root Privileges

```
# Ensure the script is run as root
if [[ "$EUID" -ne 0 ]]; then
  echo "Please run as root"
  exit 1
fi
```

This section checks if the script is run as the root user. EUID is the effective user ID, and 0 corresponds to the root user. If not root, the script prints an error message and exits.


3. Check for Input File Argument

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

Checks if a filename argument is provided when running the script. If not, it prints an error message and shows the correct usage.

4. Create Log and Password Files

```
# Create log and password files
mkdir -p /var/secure
touch "$LOGFILE" "$PASSWORD_FILE"
chmod 600 "$PASSWORD_FILE"
```

Creates the directory /var/secure if it does not exist.
Creates the log file and password file.
Sets the permissions of PASSWORD_FILE to 600 (read and write only for the owner).


5. Generate Random Password Function

```
# Function to generate a random password
generate_random_password() {
    local length=${1:-12} # Default length is 12 if no argument is provided
    LC_ALL=C tr -dc 'A-Za-z0-9!?%+=' < /dev/urandom | head -c $length
}
```
generate_random_password(): A function that generates a random password of a specified length (default is 12 characters).
tr -dc 'A-Za-z0-9!?%+=' < /dev/urandom: Filters out characters from /dev/urandom.
head -c $length: Limits the output to the desired length.


6. Create User Function

```
# Function to create a user
create_user() {
  local username=$1
  local groups=$2

  if getent passwd "$username" > /dev/null; then
    echo "User $username already exists" | tee -a "$LOGFILE"
  else
    useradd -m -g "$username" -s /bin/bash "$username"
    echo "Created user $username" | tee -a "$LOGFILE"
  fi

  # Create the user's personal group
  if ! getent group "$username" > /dev/null; then
    groupadd "$username"
    echo "Created group $username" | tee -a "$LOGFILE"
  fi

  # Add user to specified groups
  IFS=',' read -r -a groups_array <<< "$groups"
  for group in "${groups_array[@]}"; do
    if ! getent group "$group" >/dev/null; then
      groupadd "$group"
      echo "Created group $group" | tee -a "$LOGFILE"
    fi
    usermod -aG "$group" "$username"
    echo "Added user $username to group $group" | tee -a "$LOGFILE"
  done

  # Set up home directory permissions
  chmod 700 /home/"$username"
  chown "$username:$username" /home/"$username"
  echo "Set up home directory for user $username" | tee -a "$LOGFILE"

  # Generate a random password
  password=$(generate_random_password)
  echo "$username:$password" | chpasswd
  echo "$username,$password" >> "$PASSWORD_FILE"
  echo "Set password for user $username" | tee -a "$LOGFILE"
}
```

create_user(): A function to add a new user with specific groups and set up the home directory.
Check if User Exists: Checks if the user already exists. If not, creates the user.
Create Personal Group: Checks if a group named after the user exists. If not, creates it.
Add User to Groups: Parses the groups from the input and adds the user to these groups.
Home Directory Setup: Sets the correct permissions and ownership for the user’s home directory.
Generate and Set Password: Generates a password, updates the user’s password, and logs it.



7. Read Input File and Create Users

```
# Read the input file and create users
while IFS=';' read -r username groups; do
  # Skip empty lines
  if [[ -z "$username" ]]; then
    continue
  fi
  create_user "$username" "$groups"
done < "$1"
```

Reads the input file line by line.
Each line should contain a username and groups, separated by a semicolon.
Calls create_user for each valid line.


8. Final Message

```
echo "User creation process completed." | tee -a "$LOGFILE"
```

Prints a message indicating that the user creation process is complete and logs it.




**How Everything Works**
1.Configuration: The directories for the password and log files are specified by the script.

2.User File Check: It determines whether the user file is attached and is there.

3.Setup: Makes the required files and folders with the right permissions.
4.Compiling Every User: reads every line in the file, handles the groups and username, and then carries out the following operations

5.Finalization: Documents the accomplishment of the user creation procedure.


**Conclusion**
On a Linux system, you may automate the process of generating users and grouping them by using this method. During the user creation process, this script helps to maintain consistency, saves time, and lowers the possibility of mistakes. Please feel free to make any changes to the script to suit your needs.

**Acknowledgments**

I would want to express my appreciation to [HNG Hire](https://hng.tech/hire) for giving me the chance and means to create this solution.
Explore resources and programs such as the [HNG Internship](https://hng.tech/internship) and [HNG Premium](https://hng.tech/premium) for more advanced subjects and automation tips.