<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oluwasegun Oni (Drxy_Shantel)</title>
    <description>The latest articles on DEV Community by Oluwasegun Oni (Drxy_Shantel) (@tim_shantel).</description>
    <link>https://dev.to/tim_shantel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1722560%2Fbfb26d47-3b1f-4980-8305-7cc253ed236b.jpg</url>
      <title>DEV Community: Oluwasegun Oni (Drxy_Shantel)</title>
      <link>https://dev.to/tim_shantel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tim_shantel"/>
    <language>en</language>
    <item>
      <title>Automating user and group management with Bash</title>
      <dc:creator>Oluwasegun Oni (Drxy_Shantel)</dc:creator>
      <pubDate>Fri, 05 Jul 2024 16:18:32 +0000</pubDate>
      <link>https://dev.to/tim_shantel/automating-user-and-group-management-with-bash-ooc</link>
      <guid>https://dev.to/tim_shantel/automating-user-and-group-management-with-bash-ooc</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;As a SysOps engineer, managing users and groups on a server is one of your routine tasks. This process can be quite time-consuming and susceptible to errors, particularly when handling numerous users. Automating these tasks is crucial for achieving efficiency and reliability. This article will guide you through a Bash script that automates the creation of users and groups, sets up home directories with correct permissions, generates random passwords, and logs all actions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bash
&lt;/h3&gt;

&lt;p&gt;Bash which stands for "Bourne Again Shell" is a command language interpreter and scripting language commonly used in Unix-like operating systems, such as linux and macOS. It's the default shell for most linux distributions and is widely used for automation tasks, managing system operations, and write scrips.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is Bash script?
&lt;/h4&gt;

&lt;p&gt;A Bash script is a file typically ending with the extension .sh that contain a logical series of related commands to be executed&lt;/p&gt;

&lt;p&gt;This project was inspired by HNG internship 11 &lt;a href="https://hng.tech/hire"&gt;https://hng.tech/hire&lt;/a&gt;, DevOps track of stage one.&lt;br&gt;
visit  &lt;a href="https://hng.tech/internship"&gt;https://hng.tech/internship&lt;/a&gt; to learn more about the program&lt;/p&gt;
&lt;h3&gt;
  
  
  Prerequisite
&lt;/h3&gt;

&lt;p&gt;Before we start, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access to a linux server with root privileges&lt;/li&gt;
&lt;li&gt;Basic knowledge of Bash scripting&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Script Overview
&lt;/h3&gt;

&lt;p&gt;The script we'll create will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create users and groups&lt;/li&gt;
&lt;li&gt;set up home directories with the correct permissions&lt;/li&gt;
&lt;li&gt;Generate random passwords for users&lt;/li&gt;
&lt;li&gt;Log all actions to a specified log file&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  User Management Automation project
&lt;/h3&gt;

&lt;p&gt;Let's dive into an extensive project that will show us a step by step guide on how to create user and group management with Bash script.&lt;/p&gt;

&lt;p&gt;Here is a step by step guide on how to create user and groups management:&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating the script file
&lt;/h2&gt;

&lt;p&gt;First and foremost, Create a new Bash script file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch create_user.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the file in your preferred text editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vim create_user.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create an employee file where users and group would be located&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch employeefile.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;edit your user_data.txt file with a text editor and enter the following user and group below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vim employeefile.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example Input File
&lt;/h3&gt;

&lt;p&gt;light; sudo,dev, www-data&lt;br&gt;
idimma;sudo&lt;br&gt;
mayowa;dev,www-data&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Insert the following script below into your 'create_users.sh' file&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The Script
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

# Define log and password files
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"

# Create log and password files if they don't exist
touch $LOG_FILE
mkdir -p /var/secure
touch $PASSWORD_FILE

# Function to log messages
log_message() {
    echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}

# Function to generate random password
generate_password() {
    tr -dc A-Za-z0-9 &amp;lt;/dev/urandom | head -c 12 ; echo ''
}

# Check if the input file is provided
if [ $# -ne 1 ]; then
    echo "Usage: $0 &amp;lt;input_file&amp;gt;"
    exit 1
fi

# Read the input file
INPUT_FILE=$1

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

while IFS=';' read -r username groups; do
    # Remove leading and trailing whitespaces
    username=$(echo $username | xargs)
    groups=$(echo $groups | xargs)

    if id "$username" &amp;amp;&amp;gt;/dev/null; then
        log_message "User $username already exists. Skipping..."
        continue
    fi

    # Create a personal group for the user
    groupadd $username
    if [ $? -ne 0 ]; then
        log_message "Failed to create group $username."
        continue
    fi
    log_message "Group $username created successfully."

    # Create user and add to personal group
    useradd -m -g $username -s /bin/bash $username
    if [ $? -ne 0 ]; then
        log_message "Failed to create user $username."
        continue
    fi
    log_message "User $username created successfully."

    # Create additional groups if they don't exist and add user to groups
    IFS=',' read -ra group_array &amp;lt;&amp;lt;&amp;lt; "$groups"
    for group in "${group_array[@]}"; do
        group=$(echo $group | xargs)
        if [ -z "$group" ]; then
            continue
        fi
        if ! getent group $group &amp;gt;/dev/null; then
            groupadd $group
            if [ $? -ne 0 ]; then
                log_message "Failed to create group $group."
                continue
            fi
            log_message "Group $group created successfully."
        fi
        usermod -aG $group $username
        log_message "User $username added to group $group."
    done

    # Set up home directory permissions
    chmod 700 /home/$username
    chown $username:$username /home/$username
    log_message "Permissions set for home directory of $username."

    # Generate random password and store it
    password=$(generate_password)
    echo "$username:$password" | chpasswd
    echo "$username:$password" &amp;gt;&amp;gt; $PASSWORD_FILE
    log_message "Password set for user $username."

done &amp;lt; "$INPUT_FILE"

log_message "User and group creation process completed."

exit 0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Make the script executable&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod +x create_user.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Execute the script&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo bash ./create_users.sh employeefile.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Defining the Script
&lt;/h2&gt;

&lt;p&gt;Start by defining the script header and setting some initial variables:&lt;br&gt;
 &lt;strong&gt;Define Log and Password Files&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

# Define log and password files
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These lines set the paths for the log file and the file where passwords will be stored.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create Log and Password Files if They Don't Exist&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Create log and password files if they don't exist
touch $LOG_FILE
mkdir -p /var/secure
touch $PASSWORD_FILE

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;touch $LOG_FILE creates the log file if it doesn't already exist.&lt;/li&gt;
&lt;li&gt;mkdir -p /var/secure creates the directory /var/secure if it doesn't exist.&lt;/li&gt;
&lt;li&gt;touch $PASSWORD_FILE creates the password file if it doesn't exist.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Function to Log Messages&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Function to log messages
log_message() {
    echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function logs messages with a timestamp. tee -a $LOG_FILE appends the log message to the log file while also displaying it on the console.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Function to Generate Random Password&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Function to generate random password
generate_password() {
    tr -dc A-Za-z0-9 &amp;lt;/dev/urandom | head -c 12 ; echo ''
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function generates a random 12-character password using characters from A-Z, a-z, and 0-9.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check if the Input File is Provided&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Check if the input file is provided
if [ $# -ne 1 ]; then
    echo "Usage: $0 &amp;lt;input_file&amp;gt;"
    exit 1
fi

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This part ensures that the script is called with exactly one argument (the input file). If not, it displays a usage message and exits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read the Input File&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Read the input file
INPUT_FILE=$1

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This assigns the first argument (input file) to the variable INPUT_FILE.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check if the Input File Exists&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Check if the input file exists
if [ ! -f $INPUT_FILE ]; then
    echo "Input file not found!"
    exit 1
fi

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This checks if the input file exists. If not, it prints an error message and exits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Process Each Line of the Input File&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;while IFS=';' read -r username groups; do
    # Remove leading and trailing whitespaces
    username=$(echo $username | xargs)
    groups=$(echo $groups | xargs)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;IFS=';' read -r username groups reads each line of the input file, splitting the line into username and groups using ; as a delimiter.&lt;/li&gt;
&lt;li&gt;xargs is used to trim leading and trailing whitespaces from username and groups.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Check if the User Already Exists&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    if id "$username" &amp;amp;&amp;gt;/dev/null; then
        log_message "User $username already exists. Skipping..."
        continue
    fi

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This checks if the user already exists. If the user exists, it logs a message and skips to the next iteration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a Personal Group for the User&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    # Create a personal group for the user
    groupadd $username
    if [ $? -ne 0 ]; then
        log_message "Failed to create group $username."
        continue
    fi
    log_message "Group $username created successfully."

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;groupadd $username creates a new group with the same name as the user.&lt;/li&gt;
&lt;li&gt;$? checks the exit status of the groupadd command. If it's not zero (indicating an error), it logs a failure message and skips to the next iteration.&lt;/li&gt;
&lt;li&gt;If the group is created successfully, it logs a success message.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create the User and Add to Personal Group&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    # Create user and add to personal group
    useradd -m -g $username -s /bin/bash $username
    if [ $? -ne 0 ]; then
        log_message "Failed to create user $username."
        continue
    fi
    log_message "User $username created successfully."

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;useradd -m -g $username -s /bin/bash $username creates the user with a home directory and assigns the personal group.&lt;/li&gt;
&lt;li&gt;The exit status is checked, and appropriate messages are logged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Create Additional Groups and Add User to Them&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    # Create additional groups if they don't exist and add user to groups
    IFS=',' read -ra group_array &amp;lt;&amp;lt;&amp;lt; "$groups"
    for group in "${group_array[@]}"; do
        group=$(echo $group | xargs)
        if [ -z "$group" ]; then
            continue
        fi
        if ! getent group $group &amp;gt;/dev/null; then
            groupadd $group
            if [ $? -ne 0 ]; then
                log_message "Failed to create group $group."
                continue
            fi
            log_message "Group $group created successfully."
        fi
        usermod -aG $group $username
        log_message "User $username added to group $group."
    done

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;IFS=',' read -ra group_array &amp;lt;&amp;lt;&amp;lt; "$groups" splits the groups string into an array.&lt;/li&gt;
&lt;li&gt;The script iterates over the array, trims whitespaces, checks if the group is empty, and continues to the next iteration if it is.&lt;/li&gt;
&lt;li&gt;It checks if each group exists using getent group $group. If the group does not exist, it creates it.&lt;/li&gt;
&lt;li&gt;The user is added to the group using usermod -aG $group $username.
Appropriate messages are logged throughout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Set Up Home Directory Permissions&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    # Set up home directory permissions
    chmod 700 /home/$username
    chown $username:$username /home/$username
    log_message "Permissions set for home directory of $username."

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;chmod 700 /home/$username sets the permissions of the user's home directory.&lt;/li&gt;
&lt;li&gt;chown $username:$username /home/$username changes the ownership of the home directory to the user.&lt;/li&gt;
&lt;li&gt;A log message is recorded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Generate Random Password and Store It&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    # Generate random password and store it
    password=$(generate_password)
    echo "$username:$password" | chpasswd
    echo "$username:$password" &amp;gt;&amp;gt; $PASSWORD_FILE
    log_message "Password set for user $username."

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;password=$(generate_password) generates a random password.&lt;/li&gt;
&lt;li&gt;echo "$username:$password" | chpasswd sets the user's password.&lt;/li&gt;
&lt;li&gt;The password is stored in the password file.&lt;/li&gt;
&lt;li&gt;A log message is recorded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Complete the Process&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;done &amp;lt; "$INPUT_FILE"

log_message "User and group creation process completed."

exit 0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The done statement ends the while loop.&lt;/li&gt;
&lt;li&gt;A log message indicates that the process is complete.&lt;/li&gt;
&lt;li&gt;exit 0 exits the script successfully.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This detailed breakdown should help you understand each part of the script and its function as you run it in your terminal.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
