<?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: Francis Morkeh Mensah</title>
    <description>The latest articles on DEV Community by Francis Morkeh Mensah (@francis_morkehmensah_24c).</description>
    <link>https://dev.to/francis_morkehmensah_24c</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%2F1711539%2Fbb5c59e0-9f47-45c9-9517-a4e1f2f03f4e.png</url>
      <title>DEV Community: Francis Morkeh Mensah</title>
      <link>https://dev.to/francis_morkehmensah_24c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/francis_morkehmensah_24c"/>
    <language>en</language>
    <item>
      <title>Automating Linux User Creation with a Bash Script</title>
      <dc:creator>Francis Morkeh Mensah</dc:creator>
      <pubDate>Mon, 01 Jul 2024 13:48:44 +0000</pubDate>
      <link>https://dev.to/francis_morkehmensah_24c/automating-linux-user-creation-with-a-bash-script-2428</link>
      <guid>https://dev.to/francis_morkehmensah_24c/automating-linux-user-creation-with-a-bash-script-2428</guid>
      <description>&lt;h2&gt;
  
  
  Automating Linux User Creation with a Bash Script
&lt;/h2&gt;

&lt;p&gt;In a growing IT company, managing user accounts and groups manually can be time-consuming and error-prone. To streamline this process, we can use a bash script to automate the creation of users, groups, and their respective permissions. In this article, we'll walk through a bash script that reads a text file containing usernames and group names, creates the users and groups as specified, sets up home directories with appropriate permissions, generates random passwords, and logs all actions. Additionally, we'll securely store the generated passwords.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Script
&lt;/h2&gt;

&lt;p&gt;Here's the bash script, &lt;code&gt;create_users.sh&lt;/code&gt;, which accomplishes the above tasks:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="c"&gt;# Check if the user has provided a file name&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$# &lt;/span&gt;&lt;span class="nt"&gt;-eq&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Usage: &lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;name-of-text-file&amp;gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nv"&gt;input_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;

&lt;span class="c"&gt;# Ensure the input file exists&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;$input_file&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"File &lt;/span&gt;&lt;span class="nv"&gt;$input_file&lt;/span&gt;&lt;span class="s2"&gt; does not exist."&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Log and password file paths&lt;/span&gt;
&lt;span class="nv"&gt;log_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/var/log/user_management.log"&lt;/span&gt;
&lt;span class="nv"&gt;password_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/var/secure/user_passwords.csv"&lt;/span&gt;

&lt;span class="c"&gt;# Ensure /var/secure directory exists&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /var/secure
&lt;span class="nb"&gt;chmod &lt;/span&gt;700 /var/secure

&lt;span class="c"&gt;# Ensure the log file exists&lt;/span&gt;
&lt;span class="nb"&gt;touch&lt;/span&gt; &lt;span class="nv"&gt;$log_file&lt;/span&gt;

&lt;span class="c"&gt;# Start logging&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"User creation process started at &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$log_file&lt;/span&gt;

&lt;span class="c"&gt;# Ensure the password file exists and is empty&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"username,password"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$password_file&lt;/span&gt;

&lt;span class="c"&gt;# Process each line of the input file&lt;/span&gt;
&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;';'&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; username &lt;span class="nb"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c"&gt;# Remove whitespace&lt;/span&gt;
    &lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$username&lt;/span&gt; | xargs&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$groups&lt;/span&gt; | xargs&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# Check if user already exists&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &amp;amp;&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"User &lt;/span&gt;&lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="s2"&gt; already exists. Skipping..."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$log_file&lt;/span&gt;
        &lt;span class="k"&gt;continue
    fi&lt;/span&gt;

    &lt;span class="c"&gt;# Create user and user's primary group&lt;/span&gt;
    useradd &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /bin/bash &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Created user &lt;/span&gt;&lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$log_file&lt;/span&gt;

    &lt;span class="c"&gt;# Create and assign secondary groups&lt;/span&gt;
    &lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-ra&lt;/span&gt; group_list &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$groups&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;group &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;group_list&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
        &lt;/span&gt;&lt;span class="nv"&gt;group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$group&lt;/span&gt; | xargs&lt;span class="si"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; getent group &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$group&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &amp;amp;&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
            &lt;/span&gt;groupadd &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$group&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Created group &lt;/span&gt;&lt;span class="nv"&gt;$group&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$log_file&lt;/span&gt;
        &lt;span class="k"&gt;fi
        &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$group&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Added user &lt;/span&gt;&lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="s2"&gt; to group &lt;/span&gt;&lt;span class="nv"&gt;$group&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$log_file&lt;/span&gt;
    &lt;span class="k"&gt;done&lt;/span&gt;

    &lt;span class="c"&gt;# Generate a random password&lt;/span&gt;
    &lt;span class="nv"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;openssl rand &lt;span class="nt"&gt;-base64&lt;/span&gt; 12&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$password&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | chpasswd
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$password&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$password_file&lt;/span&gt;

    &lt;span class="c"&gt;# Set permissions for user's home directory&lt;/span&gt;
    &lt;span class="nb"&gt;chmod &lt;/span&gt;700 /home/&lt;span class="nv"&gt;$username&lt;/span&gt;
    &lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nv"&gt;$username&lt;/span&gt;:&lt;span class="nv"&gt;$username&lt;/span&gt; /home/&lt;span class="nv"&gt;$username&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Set permissions for /home/&lt;/span&gt;&lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$log_file&lt;/span&gt;

&lt;span class="k"&gt;done&lt;/span&gt; &amp;lt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input_file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Secure the password file&lt;/span&gt;
&lt;span class="nb"&gt;chmod &lt;/span&gt;600 &lt;span class="nv"&gt;$password_file&lt;/span&gt;
&lt;span class="nb"&gt;chown &lt;/span&gt;root:root &lt;span class="nv"&gt;$password_file&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"User creation process completed at &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$log_file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Input Validation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The script begins by checking if a filename is provided as an argument. If not, it exits with a usage message.&lt;/li&gt;
&lt;li&gt;It then verifies if the provided file exists. If the file is missing, it exits with an error message.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Setting Up Log and Password Files&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The script defines paths for the log file (&lt;code&gt;/var/log/user_management.log&lt;/code&gt;) and the password file (&lt;code&gt;/var/secure/user_passwords.csv&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;It ensures the &lt;code&gt;/var/secure&lt;/code&gt; directory exists and has the correct permissions.&lt;/li&gt;
&lt;li&gt;It ensures the log file exists and initializes the password file with a header.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Processing Each User&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For each line in the input file, the script reads the username and groups, removing any extra whitespace.&lt;/li&gt;
&lt;li&gt;It checks if the user already exists and logs a message if so, skipping further actions for that user.&lt;/li&gt;
&lt;li&gt;If the user doesn't exist, the script creates the user and their primary group.&lt;/li&gt;
&lt;li&gt;It then processes any additional groups, creating them if they don't exist, and adds the user to these groups.&lt;/li&gt;
&lt;li&gt;A random password is generated, assigned to the user, and stored in the password file.&lt;/li&gt;
&lt;li&gt;The script sets appropriate permissions for the user's home directory.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Securing the Password File&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After processing all users, the script sets strict permissions on the password file to ensure only the root user can read it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Here’s an example of what the input file (&lt;code&gt;user_list.txt&lt;/code&gt;) might look like for an IT company:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alice; sudo,developers,sysadmins
bob; developers,qa
charlie; sysadmins,network,backup
david; qa,testers
eve; developers,security
frank; security,network
grace; backup,storage
heidi; testers,qa
ivan; developers,network
judy; sysadmins,security
karen; storage,backup
leo; testers,developers
mike; qa,developers
nancy; security,sysadmins
oliver; network,backup
peggy; developers,sysadmins
quentin; qa,security
rachel; testers,backup
steve; developers,network
trudy; security,sysadmins
ursula; storage,backup
victor; qa,testers
wendy; developers,network
xander; sysadmins,security
yvonne; backup,storage
zach; developers,qa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running the Script
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Clone the Repository&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Francismensah/HNG-11-Internship--DevOps-Track.git
&lt;span class="nb"&gt;cd&lt;/span&gt; /HNG-11-Internship--DevOps-Track/Stage-1-Task
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ensure the Script is Executable&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x create_users.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Run the Script with the Input File&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;bash create_users.sh user_list.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Logging and Output
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Log File&lt;/strong&gt;: &lt;code&gt;/var/log/user_management.log&lt;/code&gt; contains a log of all actions performed by the script.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password File&lt;/strong&gt;: &lt;code&gt;/var/secure/user_passwords.csv&lt;/code&gt; contains a list of all users and their passwords, delimited by commas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Automating user and group creation in Linux can significantly reduce the administrative overhead and minimize errors. This bash script simplifies the process, ensuring that users and groups are created with the correct permissions and that actions are securely logged.&lt;/p&gt;

&lt;p&gt;For more detailed information on how to manage users and groups in Linux, you can refer to the &lt;a href="https://hng.tech/internship"&gt;HNG Internship&lt;/a&gt; and &lt;a href="https://hng.tech/hire"&gt;HNG Hire&lt;/a&gt; websites.&lt;/p&gt;

&lt;p&gt;If you have any questions or feedback, feel free to leave a comment below. Happy scripting!&lt;/p&gt;




&lt;h3&gt;
  
  
  Additional Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://hng.tech/internship"&gt;HNG Internship&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hng.tech/hire"&gt;HNG Hire&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hng.tech/premium"&gt;HNG Premium&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>linux</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
