Automated User Management Script for Linux Systems

RMAG news

Nowadays managing user accounts properly is extremely important for DevOps professionals working in dynamic IT setups.
The pro of user provisioning is that it saves time, ensures consistency , security across systems and improve efficiency since much of the process can be automated.

In this article, we will discuss about bash script and how to create a bash script that can be used for creating and managing accounts of users on Linux servers.

In this article we will be writing a script which that reads a text file containing the employee’s usernames and group names, where each line is formatted as “user;groups”.

This script will create users and groups as specified, set up home directories with appropriate permissions and ownership, generate random passwords for the users, and log all actions to var/log/user_management.log

Additionally, it will store the generated passwords securely in /var/secure/user_passwords.txt.
we will ensure error handling for scenarios like existing users by the script.

Each User will have a personal group with the same group name as the username, this group name will not be written in the text file

A user can have multiple groups, each group delimited by comma “,”

Usernames and user groups are separated by semicolon “;”
For example;

light; sudo,dev,www-data
idimma; sudo
mayowa; dev,www-data

Where light is username and groups are sudo, dev, www-data
Firstly,

#!/bin/bash
# Check if script is run as root
if [ “$EUID” -ne 0 ]; then
echo “Please run as root”
exit 1
fi

The #!/bin/bash is the shebang symbol which tells the OS which interpreter to use and in our case its will use the bash shell.

if [ “$EUID” -ne 0 ]; this will check if script is run as “root” as this ensure that we have administrative access to perform task that requires super privileges which value of ID is assigned zero (0).
EUID means the effective user ID and -ne ( a numeric comparison which means not equal)

Next;

# Check if the input file is provided
if [ -z “$1” ]; then
echo “Usage: bash create_users.sh <name-of-text-file>”
exit 1
fi

We will ensure that a positional argument is passed to the script and if not passed, it will exit (1) and echo the message “Usage: bash create_user.sh “, to enable the user pass appropriate argument.

The -z is a string value which means value has a length of zero and “$1” indicate the first parameter after the script name($0) which is assigned a variable name INPUT_FILE. So it checks if the first positional parameter is empty.

Next;

INPUT_FILE=”$1″
LOG_FILE=”/var/log/user_management.log”
PASSWORD_FILE=”/var/secure/user_passwords.txt”

# Ensure log and password files exist and have the correct permissions
touch $LOG_FILE
chmod 644 $LOG_FILE

mkdir -p /var/secure
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE

So we will create a directory_ /var/secure and create a file _user_password.txt in it where we are going to store user password in a secure way using permission “600” grant read , write permission (rw) to only the owner and create file management.log in the /var/log directory to log all event.

The first positional parameter($1) is assigned INPUT_FILE as variable

Next;

# Function to generate random password
generate_password() {
openssl rand -base64 12
}

We will be using OpenSSL command rand to generate a cryptographic password which is base64 encoded (strong and resistant as it contain letters, number and characters).
This function is going to generate the password and we are going to call it in the script.

Next;

# Process the input file
while IFS=’;’ read -r username groups; do
# Create personal group for the user
if ! getent group “$username” &>/dev/null; then
groupadd “$username”
echo “Created group $username” | tee -a $LOG_FILE
fi

Let’s process the input file;

IFS means Internal Field Separator; this is an environment variable which define a list of characters the Bash shell uses as field separators. These include space, tab, newline.

Use the while condition to read the username and group taking note of the separators by the IFS.

We will create a personal group for the user but before then we will check the system group database (/etc/group) using the getent command to ensure the group is not present.

We will add a negate operator (!) which will negate the expression and makes it True, if the $group does not exist thereby causing it to create the group if it doesn’t exist using the groupadd command.

# Check if user already exists
if id “$username” &>/dev/null; then
echo “User $username already exists. Skipping…” | tee -a $LOG_FILE
continue
fi

If user already exist then our shell script will throw an error message indicating that user exist but we want to redirect such output( standard error or output) to the /dev/null and the tee reads the output and save it silently in the $LOG_FILE.

We then use the continue to create user if user does not exist.

# Create user and personal group
useradd -m -s /bin/bash -g “$username” “$username”
if [ $? -eq 0 ]; then
echo “Created user $username with a personal group $username” | tee -a $LOG_FILE
else
echo “Failed to create user $username” | tee -a $LOG_FILE
continue
fi

Let’s add create user and add to the personal group using the popular command useradd and use the -m(to add a home directory for the user, -s (to set the shell to /bin/bash).

If the user is created and added to the personal group successfully this make the exit status ($?) equal zero (0) and it print the success message “Created user $username with a personal group $username” to the $LOG_FILE and if not it execute the else statement.

Next;

# Generate password and set it for the user
password=$(generate_password)
echo “$username:$password” | chpasswd
if [ $? -eq 0 ]; then
echo “$username,$password” >> $PASSWORD_FILE
echo “Set password for $username” | tee -a $LOG_FILE
else
echo “Failed to set password for $username” | tee -a $LOG_FILE
fi

Let’s call the function to generate the password and set password for the user using chpasswd (change password) , write the username,password into the $PASSWORD_FILE and log it.

chpasswd is designed to process multiple username and password pairs from standard input (usually via a pipe | or a redirection <)
.

Next,

# Create additional groups if specified
if [ -n “$groups” ]; then
IFS=’,’ read -ra group_array <<< “$groups”
for group in “${group_array[@]}”; do
# Create group if it doesn’t exist
if ! getent group “$group” &>/dev/null; then
groupadd “$group”
echo “Created group $group” | tee -a $LOG_FILE
fi
fi

we will be creating other group which user will be by passing the $groups as an array and iterate over it by “${group_array[@]}” where “@” insinuate every character.

The character -n is also similar to the -z only that it describe value which length is greater than zero

We will check the system group database (/etc/group) using the getent command but will add a negate operator (!) which will negate the expression and makes it True, if the $group does not exist thereby causing it to create the group if it doesn’t exist using the groupadd command as previously discussed.

Next;

usermod -aG “$group” “$username”
if [ $? -eq 0 ]; then
echo “Added $username to group $group” | tee -a $LOG_FILE
else
echo “Failed to add $username to group $group” | tee -a $LOG_FILE
fi
done
fi

we then add the user to group using the usermod -aG command
Finally,

done < “$INPUT_FILE”
echo “User creation process completed.” | tee -a $LOG_FILE

we will close our while loop condition and pass the $INPUT_FILE to read lines from it.
Create a directory, touch a file named create.sh (shell script) in the directory and make the file executable;

sudo mkdir -p ~/bash-script
sudo chmod +x ~/bash-script/create_users.sh

open the create and paste this script;

#!/bin/bash
#check if 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 “Usage: bash create_users.sh <name-of-text-file>”
exit 1
fi

INPUT_FILE=”$1″
LOG_FILE=”/var/log/user_management.log”
PASSWORD_FILE=”/var/secure/user_passwords.txt”

# Ensure log and password files exist and have the correct permissions
touch $LOG_FILE
chmod 644 $LOG_FILE

mkdir -p /var/secure
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE

# Function to generate random password
generate_password() {
openssl rand -base64 12
}

# Process the input file
while IFS=’;’ read -r username groups; do
# Create personal group for the user
if ! getent group “$username” &>/dev/null; then
groupadd “$username”
echo “Created group $username” | tee -a $LOG_FILE
fi

# Check if user already exists
if id “$username” &>/dev/null; then
echo “User $username already exists. Skipping…” | tee -a $LOG_FILE
continue
fi

# Create user and personal group
useradd -m -s /bin/bash -g “$username” “$username”
if [ $? -eq 0 ]; then
echo “Created user $username with a personal group $username” | tee -a $LOG_FILE
else
echo “Failed to create user $username” | tee -a $LOG_FILE
continue
fi

# Generate password and set it for the user
password=$(generate_password)
echo “$username:$password” | chpasswd
if [ $? -eq 0 ]; then
echo “$username,$password” >> $PASSWORD_FILE
echo “Set password for $username” | tee -a $LOG_FILE
else
echo “Failed to set password for $username” | tee -a $LOG_FILE
fi

# Create additional groups if specified
if [ -n “$groups” ]; then
IFS=’,’ read -ra group_array <<< “$groups”
for group in “${group_array[@]}”; do
# Create group if it doesn’t exist
if ! getent group “$group” &>/dev/null; then
groupadd “$group”
echo “Created group $group” | tee -a $LOG_FILE
fi

usermod -aG “$group” “$username”
if [ $? -eq 0 ]; then
echo “Added $username to group $group” | tee -a $LOG_FILE
else
echo “Failed to add $username to group $group” | tee -a $LOG_FILE
fi
done
fi
done < “$INPUT_FILE”

echo “User creation process completed.” | tee -a $LOG_FILE

Create a file (input_file.txt) containing username;groups

light; sudo,dev,www-data
idimma; sudo
mayowa; dev,www-data

Run the script and pass the input_file.txt as argument.

Thank you for reading, to learn more kindly join the HNG internship programme to get your tech skill upgraded and land you dream job.
Follow this link
https://hng.tech/internship,
https://hng.tech/hire

hsh