Why account management is a security control
Every user account is a way in — a login that can be phished, guessed, reused from a breach elsewhere, or simply forgotten about. The guiding rule is least privilege: an account should have exactly the access its job requires, and nothing more. In practice that means adding people to only the groups they actually need, disabling or removing accounts the moment someone leaves or a service is retired, and periodically auditing who currently holds administrator rights — that list only grows unless someone actively prunes it. This is a different layer from the [Linux File Permissions](/reference/cybersecurity/file-permissions) sheet. Account management decides whether an account exists and what groups it's in; file permissions decide what that account can do once it's logged in. A former employee's account left active, or an account quietly added to the admin group, is a live attack surface with a real, working password.
The core idea: least privilege
Grant the narrowest access that still lets the work happen, and take it away the moment it's no longer needed. Stale accounts and over-broad group membership are two of the most common findings in a real security audit.
Linux: seeing who has access
Before changing anything, learn to look — every command below is read-only and safe to run on any account you can log into.
| Command | What it does | Example |
|---|---|---|
| whoami | Print the username you are currently logged in as. | whoami |
| id | Print your own numeric UID/GID and every group you belong to. | id |
| id <user> | Print the same identity information for another account. | id jsmith |
| groups <user> | List just the group names an account belongs to. | groups jsmith |
| getent passwd | List every account entry the system knows about (works even when accounts come from a directory service, not just /etc/passwd). | getent passwd jsmith |
| getent group sudo | List the members of a specific group — here, everyone with sudo rights. | getent group sudo |
| File | Who can read it | What it holds |
|---|---|---|
| `/etc/passwd` | Everyone | username, UID, GID, comment field, home directory, login shell |
| `/etc/shadow` | root only | the password hash plus aging data (last changed, min/max age, warning period) |
| `/etc/group` | Everyone | group name, GID, and a comma-separated list of members |
Linux: adding an account
Creating an account is two steps: make the account, then set a password. An account with no password set is either unusable or, if the system is misconfigured, an open door — never skip the second step.
| Command | What it does | Example |
|---|---|---|
| sudo useradd -m -s /bin/bash <user> | Create the account. -m creates a home directory (skip it and there is no home folder); -s sets the login shell. | sudo useradd -m -s /bin/bash jsmith |
| sudo passwd <user> | Set (or reset) the account's password interactively. | sudo passwd jsmith |
On Debian and Ubuntu, adduser <user> is a friendlier interactive wrapper around useradd — it creates the home directory, picks a default shell, and walks you through setting a password and optional details (full name, room number, phone) in one guided flow. useradd is the lower-level command underneath, and it's the one available on every distribution.
Linux: editing an account
Most edits go through usermod. Password aging is its own tool, chage, and removing a user from a group cleanly needs gpasswd.
| Command | What it does | Example |
|---|---|---|
| sudo usermod -aG <group> <user> | Append the account to a supplementary group without touching its other memberships. | sudo usermod -aG sudo jsmith |
| sudo usermod -l <newname> <oldname> | Rename the login itself (the username). | sudo usermod -l jane jsmith |
| sudo usermod -s <shell> <user> | Change the account's login shell. | sudo usermod -s /usr/sbin/nologin jsmith |
usermod -G replaces — it does not add
usermod -G <group> <user> without the -a flag sets the account's supplementary groups to exactly the list you give it, dropping every other group it was in. Almost every real task wants usermod -aG (append). Losing the -a by accident is a classic, silent way to strip someone's sudo, docker, or VPN group access.
chage (change age) manages password aging — how often a password must be changed and when an account expires.
Password aging with chage:
| Flag | Sets | Example |
|---|---|---|
| -l | List the account's current aging settings (no changes made). | sudo chage -l jsmith |
| -m | Minimum number of days between password changes. | sudo chage -m 1 jsmith |
| -M | Maximum number of days a password stays valid before it must change. | sudo chage -M 90 jsmith |
| -W | Days of warning shown to the user before the password expires. | sudo chage -W 7 jsmith |
| -E | Account expiration date (YYYY-MM-DD) — after this date the account itself is disabled. | sudo chage -E 2026-12-31 jsmith |
| -I | Days after a password expires before the account is locked for inactivity. | sudo chage -I 14 jsmith |
Locking, unlocking, and leaving a group:
| Command | What it does | Example |
|---|---|---|
| sudo passwd -l <user> | Lock the account by disabling its password hash — the account still exists, but cannot log in with a password. | sudo passwd -l jsmith |
| sudo passwd -u <user> | Unlock an account locked with passwd -l. | sudo passwd -u jsmith |
| sudo usermod -L <user> | The usermod equivalent of passwd -l. | sudo usermod -L jsmith |
| sudo usermod -U <user> | The usermod equivalent of passwd -u. | sudo usermod -U jsmith |
| sudo gpasswd -d <user> <group> | Remove an account from a group — the one everyday job usermod doesn't do cleanly on its own. | sudo gpasswd -d jsmith docker |
Linux: removing an account
Removing an account is one-way. Check whether anything is still running as that user before you pull the account out from under it.
| Command | What it does | Example |
|---|---|---|
| pgrep -u <user> | List the process IDs of everything currently running as that user — run this before deleting an account. | pgrep -u jsmith |
| sudo userdel <user> | Delete the account entry. Leaves the home directory and mail spool in place. | sudo userdel jsmith |
| sudo userdel -r <user> | Delete the account AND remove its home directory and mail spool. | sudo userdel -r jsmith |
| sudo groupadd <name> | Create a new group. | sudo groupadd interns |
| sudo groupdel <name> | Delete a group. Fails if it is still some account's primary group. | sudo groupdel interns |
Administrator rights on Linux come from group membership, not a special flag on the account — on Debian and Ubuntu that group is sudo; on RHEL, Fedora, and CentOS it's wheel. Removing an account from that group (or deleting the account outright) is how admin rights get revoked.
Disable before you delete
Locking an account (passwd -l / usermod -L on Linux, net user <name> /active:no or Disable-LocalUser on Windows) stops a login immediately while leaving the account, its files, and its history intact for review. Deletion is one-way. When you're not certain you'll never need the account's data or an audit trail, lock it first and delete it only once you're sure.
Windows: net user and net localgroup
Windows has two command-line surfaces for account management: the older net user / net localgroup commands, and the newer PowerShell cmdlets (next section). Both need an elevated prompt — right-click Command Prompt or PowerShell and choose "Run as administrator" — because managing accounts is itself an administrative action.
| Command | What it does | Example |
|---|---|---|
| net user | List every local user account on the machine. | net user |
| net user <name> /add | Create a new local user account. | net user jsmith /add |
| net user <name> * | Set or reset that user's password. The * makes Windows prompt for it, instead of typing it in plain text on the command line. | net user jsmith * |
| net user <name> /active:no | Disable the account without deleting it. | net user jsmith /active:no |
| net user <name> /delete | Delete the account entirely. | net user jsmith /delete |
| net localgroup Administrators | List every member of the local Administrators group. | net localgroup Administrators |
| net localgroup Administrators <name> /add | Grant local administrator rights by adding the account to the group. | net localgroup Administrators jsmith /add |
| net localgroup Administrators <name> /delete | Remove local administrator rights. | net localgroup Administrators jsmith /delete |
Windows: PowerShell
PowerShell's LocalAccounts module (built into Windows 10/11 and Windows Server 2016+) does the same job with cmdlets instead of flags. Run PowerShell as Administrator the same way you would Command Prompt. This session box uses a $ prompt like the rest of the sheet, but the commands below are PowerShell, not bash.
| Command | What it does | Example |
|---|---|---|
| Get-LocalUser | List every local user account, with its Enabled status. | Get-LocalUser |
| New-LocalUser | Create a new local user. -Password takes a SecureString, so pass Read-Host -AsSecureString rather than a plain-text string. | New-LocalUser -Name jsmith -Password (Read-Host -AsSecureString "Enter password") -FullName "John Smith" -Description "Cybersecurity student account" |
| Set-LocalUser | Change a property on an existing account, such as its description or full name. | Set-LocalUser -Name jsmith -Description "Updated 2026-09" |
| Disable-LocalUser | Disable an account without deleting it. | Disable-LocalUser -Name jsmith |
| Enable-LocalUser | Re-enable a disabled account. | Enable-LocalUser -Name jsmith |
| Remove-LocalUser | Delete a local user account. | Remove-LocalUser -Name jsmith |
| Get-LocalGroupMember Administrators | List every member of the local Administrators group. | Get-LocalGroupMember Administrators |
| Add-LocalGroupMember | Add an account to a local group, granting whatever rights that group carries. | Add-LocalGroupMember -Group Administrators -Member jsmith |
| Remove-LocalGroupMember | Remove an account from a local group. | Remove-LocalGroupMember -Group Administrators -Member jsmith |
Auditing who has administrator rights
Because any account with admin/root-equivalent rights is a high-value target, checking who currently holds that access is a routine security task — and a very common ask in labs, capture-the-flag challenges, and real audits ("find the account that shouldn't be an administrator"). It's the same commands from this sheet, just aimed at the admin group:
- Linux (Debian/Ubuntu): getent group sudo
- Linux (RHEL/Fedora/CentOS): getent group wheel
- Windows: net localgroup Administrators or Get-LocalGroupMember Administrators
Compare the real membership against the list of people who are supposed to have admin rights. Anything extra is a finding worth investigating.
A common lab and competition task
Being handed a machine and asked to find the unauthorized administrator account shows up constantly in cybersecurity labs and CTFs. The technique is always the same: list the admin group's actual membership, then compare it to what's expected.
Never lock yourself out
Never remove your own admin rights, and never remove or disable the last administrator account on a machine — on Linux that means the last member of sudo/wheel; on Windows the last member of Administrators. Once nobody with elevated rights can log in, there's no in-band way to fix it — you'd need physical or recovery access (a live USB, single-user mode, or a password-reset disk) to regain control.
Try it yourself
Lab systems only
Practice ONLY on a virtual machine or a lab system you own or are explicitly authorized to administer — never on a school computer or any shared machine you don't personally manage. Creating, locking, or deleting an account you aren't authorized to touch can be a policy violation even if it's a mistake.
On a Linux VM:
1. Create a new account with a home directory: sudo useradd -m -s /bin/bash labtest, then set its password with sudo passwd labtest.
2. Add it to a group: sudo groupadd testers (if the group doesn't exist yet), then sudo usermod -aG testers labtest.
3. Verify the membership with id labtest — confirm testers shows up in the groups list.
4. Lock the account: sudo passwd -l labtest.
5. Confirm it's locked: sudo passwd -S labtest and look for the L status.
6. Delete the account and its home directory together: sudo userdel -r labtest.
On a Windows VM, the same sequence:
1. Create the account: net user labtest /add, or in PowerShell New-LocalUser -Name labtest -Password (Read-Host -AsSecureString "Enter password").
2. Create a group and add it: net localgroup Testers /add then net localgroup Testers labtest /add, or New-LocalGroup -Name Testers then Add-LocalGroupMember -Group Testers -Member labtest.
3. Verify with net user labtest or Get-LocalUser labtest, and confirm the group shows up with Get-LocalGroupMember Testers.
4. Disable it: net user labtest /active:no, or Disable-LocalUser -Name labtest.
5. Confirm it's disabled: net user labtest shows Account active No, or Get-LocalUser labtest shows Enabled : False.
6. Delete it: net user labtest /delete, or Remove-LocalUser -Name labtest.
passwd-excerpt.txtDownload passwd-excerpt.txt: https://restedteacher.com/practice-files/cybersecurity/passwd-excerpt.txt
A sample /etc/passwd file — the same fields getent passwd prints — to practice auditing accounts without needing a live Linux box.
group-excerpt.txtDownload group-excerpt.txt: https://restedteacher.com/practice-files/cybersecurity/group-excerpt.txt
The matching sample /etc/group file, so you can cross-reference which accounts hold which group memberships.
Get both files into a labs folder
Move both downloads into a labs folder and go there, using commands from the [Terminal Basics](/reference/cybersecurity/terminal-basics) sheet:
mkdir -p ~/labs/accounts && mv ~/Downloads/passwd-excerpt.txt ~/Downloads/group-excerpt.txt ~/labs/accounts/ && cd ~/labs/accounts
Then run cat passwd-excerpt.txt and cat group-excerpt.txt to see both files.
Using passwd-excerpt.txt and group-excerpt.txt, answer each question with a real command (awk -F: ..., grep, cut):
1. Every account should have a unique UID except root's own aliases. Exactly one other account in passwd-excerpt.txt shares UID 0 with root, meaning it is really a root-equivalent account despite its ordinary-sounding name. Which account is it?
2. How many accounts in passwd-excerpt.txt have /usr/sbin/nologin as their shell (accounts that cannot start an interactive login session)?
3. According to group-excerpt.txt, which two accounts are members of the sudo group?
4. Which single group in group-excerpt.txt has the highest GID number?