How To Automate The Creation Of Users And Groups In Linux Using Bash Script.
Tags: linux, aws, devops, cloudcomputing
Published: 2024-07-02 23:00:16

---

**INTRODUCTION**
Imagine you work in very big firm, and your company recruited about 100 new staffs and you are saddle with the responsibility of creating user accounts for them as well as adding them to different groups in a Linux system.

Performing this tasks manually can be very tiring and also error prone. In this post, I will walk you through the process of automating this process using a simple BASH script. 

**REQUIREMENTS**
- Linux machine
- Basic knowledge of scripting 
- A .txt file that contain names of the employees(users) and their groups
N/B: The usernames and groups should be separated by ';', and in a situation where a user belongs to more than one group, the groups should be separated with a comma(','). check example below;

_employees.txt_
```
Onyeka;electronics,devOps
Charles;admin
Bukola;marketing
```


**Step 1**
Open your terminal and create a script named create_users.sh, you can use nano or vim

`nano create_users.sh`


**Step 2**
Let's create directories for storing the generated users and their passwords, also the log files. We'll make sure shebang (#!/bin/bash) is added on top of the script before every other thing.

```bash
#!/bin/bash

#create main directory to save files
mkdir var
cd var #move inside the created dir

#create log folder and user_mgt.log inside the folder
mkdir log && touch log/user_management.log

#create secure folder and user_passwd file inside the folder
mkdir secure && touch secure/user_passwords.txt
#Read and Write permission for the owner only
chmod 700 secure
# go back to the home dir
cd ..
```
As shown above, the script will create a dir named var, inside the var dir, two more folders are created named log and secure with user_management.log and user_passwords.txt inside them respectively. Then restrict access to secure folder using #chmod.


**Step 3**
Here, we'll create functions for generating random password, creating new user, new group and adding created users to different groups.

```bash
#function to generate password
generate_password() {
  local password=$(openssl rand -base64 12)
  echo "$password"
}

#Create users, groups and generate password
#for them, then  assign groups to the created users

#function to create users
createUser(){
  local user="$1"
  id "$user" &>/dev/null
  if [ $? -eq 1 ]; then #check if user is existing
     sudo useradd -m "$user"
     echo "user $user created"
  else
     echo "$user already created"
  fi
}

#function to create group
createGroup(){
  local group="$1"
  getent group "$group" &>/dev/null
  if [ $? -eq 2 ]; then #check if group has been created
     sudo groupadd "$group"
     echo "group $group created"
  else
     echo "$group already created"
  fi
}

#function to add users to group
addUser_to_group(){
  local user="$1"
  local group="$2"

  sudo usermod -aG "$group" "$user"
  echo "$user added to group: $group"
}
```
**Step 4**
This is the 'MAIN' entry point of the script. Firstly, we use the code below to check the argument (.txt file that contains users and their groups) provided for validation purposes, then save the file in a variable (user_file).

```bash
if [[ $# -ne 1 ]]; then
  echo "error: check the file provided"
  exit 1
fi

# user details
user_file="$1"
```
After that, we read the file line by line, validate it, create users, create group and generate passwords for the users as shown in the code snippet below.

```bash
# Check if the file exists
if [[ ! -f "$user_file" ]]; then
  echo "user file not found!"
  exit 1
fi

# Read the file line by line
while IFS=";" read -r user groups; do
  user=$(echo $user | xargs)
 # Check to know if user and group
 # contains strings for validation
 if [[ -z "$user" && -z "$groups" ]];
 then
    echo "Empty entry!!"
 else
    #create group and user if they don't exist
    createUser "$user"
    createGroup "$user"
    #create group with the same name as the user
    sudo usermod -aG "$user" "$user"

    #extract the groups one by one
    IFS=',' read -ra group_array <<< "$groups"
    for group in "${group_array[@]}"; do
        group=$(echo $group | xargs)
        createGroup "$group"
        addUser_to_group "$user" "$group"
    done

    password=$(generate_password)
    echo "$user:$password" | sudo chpasswd
    echo "password assigned to $user"
    echo "$user,$password" >> ./var/secure/user_passwords.txt #PASSWD_PATH
 fi

done < "$user_file"


```
**Complete Code**

```bash
#!/bin/bash

#create main directory to save files
mkdir var
cd var #move inside the created dir

#create log folder and user_mgt.log inside the folder
mkdir log && touch log/user_management.log

#create secure folder and user_passwd file inside the folder
mkdir secure && touch secure/user_passwords.txt
#Read and Write permission for the owner only
chmod 700 secure
# go back to the home dir
cd ..

#LOG_FILE_PATH=./var/log/user_management.log
#PASSWD_PATH=./var/secure/user_password.txt

#function to generate password
generate_password() {
  local password=$(openssl rand -base64 12)
  echo "$password"
}

#Create users, groups and generate password
#for them, then  assign groups to the created users

#function to create users
createUser(){
  local user="$1"
  id "$user" &>/dev/null
  if [ $? -eq 1 ]; then #check if user is existing
     sudo useradd -m "$user"
     echo "user $user created"
  else
     echo "$user already created"
  fi
}

#function to create group
createGroup(){
  local group="$1"
  getent group "$group" &>/dev/null
  if [ $? -eq 2 ]; then #check if group has been created
     sudo groupadd "$group"
     echo "group $group created"
  else
     echo "$group already created"
  fi
}

#function to add users to group
addUser_to_group(){
  local user="$1"
  local group="$2"

  sudo usermod -aG "$group" "$user"
  echo "$user added to group: $group"
}
########## MAIN ENTRY POINT OF THE SCRIPT ##############
#Read and validate .txt file containing
#employees username and groups

# Check if the correct number of arguments is provided
(
if [[ $# -ne 1 ]]; then
  echo "error: check the file provided"
  exit 1
fi

# user details
user_file="$1"

# Check if the file exists
if [[ ! -f "$user_file" ]]; then
  echo "user file not found!"
  exit 1
fi

# Read the file line by line
while IFS=";" read -r user groups; do
  user=$(echo $user | xargs)
 # Check to know if user and group
 # contains strings for validation
 if [[ -z "$user" && -z "$groups" ]];
 then
    echo "Empty entry!!"
 else
    #create group and user if they don't exist
    createUser "$user"
    createGroup "$user"
    #create group with the same name as the user
    sudo usermod -aG "$user" "$user"

    #extract the groups one by one
    IFS=',' read -ra group_array <<< "$groups"
    for group in "${group_array[@]}"; do
        group=$(echo $group | xargs)
        createGroup "$group"
        addUser_to_group "$user" "$group"
    done

    password=$(generate_password)
    echo "$user:$password" | sudo chpasswd
    echo "password assigned to $user"
    echo "$user,$password" >> ./var/secure/user_passwords.txt #Log the generated user and password to user_passwords.txt
 fi

done < "$user_file"

) | tee -a ./var/log/user_management.log #Log all actions to user_management.txt

```


finally, make sure the script is executable by running the following command.

`chmod +x create_users.sh`

**How To Use The Script**

```
 ./create_users.sh employee.txt #where employee.txt contains user;group(s)
```


**This is my HNG Internship task**
HNG Internship is a competitive online bootcamp for coders, designers and other technical talent. It is designed for people who want to rapidly upskill themselves, learn new technologies and build products in a collaborative and fun environment.
https://hng.tech/internship
https://hng.tech/premium