Users, Groups and Computers
Managing the objects in Active Directory: user and computer accounts, group types and scopes, nesting with AGDLP, service accounts and managed service accounts, and PowerShell for bulk work.
User accounts in Active Directory
A domain user account is an object in the directory with a few hundred possible attributes. A handful matter every day, because they decide how a person signs in and how Windows recognizes them:
| Attribute | Example | What it is for |
|---|---|---|
sAMAccountName |
lromero |
The pre-Windows 2000 logon name, used as
AD\lromero; at most 20 characters and unique in
the domain.
|
userPrincipalName |
lucia.romero@example.com |
The user principal name (UPN), an email-style sign-in name. The suffix can differ from the domain name, so it can match the email address and the cloud sign-in name. |
objectSid |
S-1-5-21-…-1107 |
The security identifier (SID) that access control lists and tokens actually use. |
objectGUID |
a8f3… |
A globally unique identifier that never changes, also not when the account is renamed or moved; sync tools use it to match objects. |
distinguishedName |
CN=Lucia Romero,OU=Billing,DC=ad,DC=example,DC=com
|
Where the object sits in the tree; it changes when the account moves to another OU (see Directory Services and LDAP). |
userAccountControl |
512 |
A set of flags: disabled, password never expires, smart card required, and more (512 means a normal, enabled account). |
SIDs and why names do not matter
A domain account's SID is the domain's SID followed by a relative
identifier (RID), a number handed out by the DC from a pool it got
from the RID master (see
Active Directory Fundamentals). When a user signs in, the DC puts the user's SID and the SIDs of
all their groups into an access token; every permission check
compares those SIDs with the access control lists on files, shares
and objects. You can see your own token with
whoami /groups, as shown on
Users and Permissions.
The consequence is practical. If someone deletes
lromero and creates a new account with the same name,
the new account has a new RID, and none of the old permissions,
mailbox links or group memberships apply. That is why leavers are
disabled first and only deleted after a retention
period, and why the AD Recycle Bin is worth enabling: it restores a
deleted object with its original SID and attributes. The full
joiner-mover-leaver process is on
Identity Lifecycle.
Computer accounts and the secure channel
A computer account is the
directory object that represents a domain-joined machine, with its
own SID and its own password, so that the computer itself can
authenticate to domain controllers. Its
sAMAccountName ends with a dollar sign: the laptop
PC-BIL-014 is PC-BIL-014$ in AD. Group
Policy, Kerberos tickets for services and the
DNS registration
of a member all rely on the computer being able to prove who it is.
The machine password is random and changed automatically by the computer, by default every 30 days. The computer keeps the current and the previous password; the DC keeps the same. The authenticated connection a member sets up with a DC using that password is called the secure channel. When the two sides disagree, for example after a virtual machine is reverted to a snapshot from two months ago, or a PC was off the network for a long time and then reimaged with an old image, users see:
The trust relationship between this workstation and the primary domain failed.
The fix is to reset the machine password rather than to delete and
recreate the computer account (which would lose its group
memberships and delegated permissions). Sign in with a local
administrator account, then run
Test-ComputerSecureChannel in Windows PowerShell 5.1
(the cmdlet is not part of PowerShell 7; there, start
powershell.exe or use netdom resetpwd):
Test-ComputerSecureChannel -Verbose # is the channel broken?
Test-ComputerSecureChannel -Repair -Credential (Get-Credential AD\helpdesk-admin)
VERBOSE: Performing the operation "Test-ComputerSecureChannel" on target "PC-BIL-014". VERBOSE: The secure channel between the local computer and the domain ad.example.com is broken. False True
Groups: type and scope
Every AD group has two independent properties: a type (what the group is for) and a scope (who can be a member and where it can be used).
Security groups and distribution groups
A security group has a SID, ends up in members' access tokens and can therefore be given permissions. A distribution group is a group without a security identity, used only as an email distribution list; it never appears in a token and cannot be used to grant access. A security group can also have an email address, so a mail-enabled security group does both jobs. A team that asks for "a group for the billing share" needs a security group, however much it looks like an email list in the address book.
Group scopes
A group scope is the property of an Active Directory group that decides which accounts and groups can be its members and in which domains it can be given permissions. In a forest with a single domain the differences seem academic; they matter as soon as there is a second domain or a trust with another forest.
| Scope | Can contain | Can be given permissions in | Typical use |
|---|---|---|---|
| Domain local | Accounts and global groups from any trusted domain; universal groups from the same forest; domain local groups from its own domain | Its own domain only | Access to one resource (a share, a printer, an application) |
| Global | Accounts and global groups from its own domain only | Any domain in the forest and any trusting domain | People with the same role or department |
| Universal | Accounts, global and universal groups from any domain in the forest | Any domain in the forest (and in trusting forests) | Roles that span domains |
Universal group memberships are stored in the global catalog, so every change replicates to every global catalog server in the forest. That is one reason to put global groups, not individual users, into universal groups: the membership of the universal group then rarely changes.
When a membership change takes effect
Group SIDs are collected into the token when the user signs in (and into the Kerberos ticket the user receives). Adding Lucía to a group therefore does nothing for a session that is already open: she has to sign out and in again, and a server that she already has a session with may keep the old view until that session ends. This is one of the most common "I added her but it still says access denied" tickets. For computer accounts the same applies: a computer added to a group sees the change after a restart.
Nesting groups with AGDLP
AGDLP is Microsoft's long-standing pattern for nesting groups: put user Accounts in Global groups that describe a role, put those global groups in Domain Local groups that describe access to one resource, and grant the Permissions only to the domain local groups. Each layer answers one question:
Why bother with two layers? Because roles and resources change for
different reasons. When a new service desk analyst starts, only
GG-Service-Desk changes, and the analyst gets every
resource the role needs at once. When the billing share must also be
readable by auditors, only DL-BillingShare-Read
changes. Access lists on servers stay small and stable, and an
access review can ask the clear question "should the service desk
have read access to billing?" instead of reading a list of fifty
names. This is
role-based access control
built from AD groups; the models behind it are on
Authorization Models.
AGUDLP adds a Universal group between the global and the domain local layer when a role has members in several domains of a forest: global groups from each domain go into one universal group, which goes into the domain local groups. In a single-domain forest, AGDLP is enough.
Effective access through nested groups
To answer "why can this person open that share?", a tool has to follow nesting in both directions and must not loop forever when two groups contain each other, which AD allows. This sketch resolves every group a user is in, directly or indirectly, with a breadth-first search that remembers which groups it has seen, then collects the permissions the share's access list grants to any of them.
# Effective permissions through nested AD groups (AGDLP), safe against loops.
from collections import deque
# Group -> direct members (user accounts or other groups).
MEMBERS = {
# Global groups: people with the same role.
"GG-Billing-Clerks": ["lucia"],
"GG-Billing-Managers": ["femke"],
"GG-Service-Desk": ["amara", "mei"],
# Domain local groups: one per resource and access level.
"DL-BillingShare-Read": ["GG-Service-Desk", "GG-Billing-Managers"],
"DL-BillingShare-Modify": ["GG-Billing-Clerks", "GG-Billing-Managers"],
# A mistake from years ago: two groups that contain each other.
"GG-Finance-All": ["GG-Billing-Managers", "GG-Finance-Legacy"],
"GG-Finance-Legacy": ["GG-Finance-All"],
}
# The share's access list names domain local groups only.
SHARE_ACL = {
"DL-BillingShare-Read": {"read"},
"DL-BillingShare-Modify": {"read", "write"},
}
def groups_of(principal):
"""Every group that contains principal, directly or through nesting."""
found = set()
queue = deque([principal])
while queue:
current = queue.popleft()
for group, members in MEMBERS.items():
if current in members and group not in found:
found.add(group) # seen once, never queued again: loops end
queue.append(group)
return found
for user in ["amara", "femke", "lucia", "ravi"]:
groups = groups_of(user)
rights = set()
for group in groups:
rights |= SHARE_ACL.get(group, set())
print(f"{user:<6} {', '.join(sorted(rights)) or 'no access'}")
for group in sorted(groups):
print(f" member of {group}")
amara read
member of DL-BillingShare-Read
member of GG-Service-Desk
femke read, write
member of DL-BillingShare-Modify
member of DL-BillingShare-Read
member of GG-Billing-Managers
member of GG-Finance-All
member of GG-Finance-Legacy
lucia read, write
member of DL-BillingShare-Modify
member of GG-Billing-Clerks
ravi no access
The two finance groups that contain each other are visited once each
and the search ends. Without the found check, the loop
would run until memory ran out. Real tools do the same: PowerShell's
Get-ADGroupMember -Recursive (below) and the "effective
access" tab in a folder's advanced security settings.
Service accounts and managed service accounts
Many Windows services, scheduled tasks and applications need a
domain identity to reach a database or a file share. The classic
answer is a
service account: an ordinary user account, such as svc-portal, whose
password is typed into the service configuration. In practice those
accounts collect risks:
- The password is set by hand, is known to several people and is set to "never expires", because changing it means updating every server that uses it.
- The account often has far more rights than it needs, sometimes Domain Admin, "because the installer asked for it".
- If it has a service principal name (SPN), any domain user can request a Kerberos service ticket for it and try to crack the password offline: Kerberoasting (MITRE ATT&CK T1558.003), explained with its defenses on Attacks on Identity and Kerberos and NTLM. A long random password defeats it; a human-chosen one often does not.
Group Managed Service Accounts
A group Managed Service Account (gMSA) is an AD account type for services whose long, random password is generated and rotated automatically by the domain controllers, and which only the computers you list may retrieve. Nobody knows or types the password, it changes every 30 days by default, and the same account can run a service on several servers (a web farm, for example). gMSAs arrived with Windows Server 2012; the older standalone managed service account worked on one computer only.
# Once per forest: the KDS root key the DCs derive gMSA passwords from
Add-KdsRootKey -EffectiveImmediately
# The account, and which servers may fetch its password
New-ADServiceAccount -Name svc-portal -DNSHostName svc-portal.ad.example.com `
-PrincipalsAllowedToRetrieveManagedPassword GG-Portal-Servers
# On each portal server (a member of GG-Portal-Servers):
Install-ADServiceAccount -Identity svc-portal
Test-ADServiceAccount -Identity svc-portal
The service is then configured to run as
AD\svc-portal$ with an empty password field; Windows
fetches the current password itself.
Add-KdsRootKey -EffectiveImmediately still waits for AD
replication before the key can be used, so in a lab with several DCs
the first gMSA may fail for a while.
Delegated Managed Service Accounts (Windows Server 2025)
Windows Server 2025 adds the delegated Managed Service Account (dMSA). It is designed to replace an existing classic service account: the dMSA takes over its role, is bound to specific machines and uses random keys, and the old account's password is disabled, which removes the Kerberoasting target. Unlike a gMSA, a dMSA is tied to the machine identity. Migration works from a classic service account only, not from an MSA or gMSA.
For workloads in the cloud the same idea, an identity without a password anyone handles, is called a managed identity; see Identity for Applications and Machines.
The Protected Users group
The Protected Users group is a built-in global security group whose members automatically get stricter authentication protections that cannot be switched off per account. With a domain functional level of Windows Server 2012 R2 or higher, members:
- cannot authenticate with NTLM, only with Kerberos;
- cannot use DES or RC4 in Kerberos preauthentication;
- cannot be delegated (constrained or unconstrained);
- get Kerberos ticket-granting tickets limited to 4 hours, with no renewal beyond that.
Their credentials are also not cached on the computers they sign in to, which means a member cannot sign in to a laptop that is offline. That makes Protected Users a strong fit for administrator accounts, which should never sign in offline or be delegated anyway, and a poor fit for ordinary mobile users. Do not add service or computer accounts: services that depend on NTLM or delegation break. Add a few admin accounts first, test the tools they use, then widen. Privileged accounts are covered further on Privileged Access Management.
PowerShell for bulk work
Active Directory Users and Computers (dsa.msc) is fine
for one account. For fifty, or for a question such as "who in
Billing has not signed in for 90 days?", use the ActiveDirectory
module for
PowerShell
(part of the Remote Server Administration Tools). Commands are
illustrative; there is no domain controller behind this page.
Get-ADUser -Filter "Department -eq 'Billing' -and Enabled -eq 'True'" `
-Properties Department, LastLogonDate |
Sort-Object LastLogonDate |
Select-Object SamAccountName, UserPrincipalName, LastLogonDate
SamAccountName UserPrincipalName LastLogonDate -------------- ----------------- ------------- fjansen-old femke.jansen2@example.com 3/14/2026 8:02:11 AM lromero lucia.romero@example.com 9/30/2026 7:58:40 AM fjansen femke.jansen@example.com 10/1/2026 8:15:03 AM
-Filter is evaluated on the DC, so only matching users
cross the network; avoid Get-ADUser -Filter * followed
by Where-Object in a large domain. The old duplicate
account at the top of this list is exactly what such a query is for.
Creating accounts from an HR export and adding them to their role
group:
Import-Csv .\new-starters.csv | ForEach-Object {
New-ADUser -Name $_.DisplayName -GivenName $_.GivenName -Surname $_.Surname `
-SamAccountName $_.SamAccountName `
-UserPrincipalName "$($_.Alias)@example.com" `
-Department $_.Department `
-Path "OU=Users,OU=Billing,DC=ad,DC=example,DC=com" `
-Enabled $false # enabled on day one, with a one-time sign-in method
Add-ADGroupMember -Identity GG-Billing-Clerks -Members $_.SamAccountName
}
The accounts are created disabled and without a password in the
file: a CSV with initial passwords is a credential leak waiting to
happen. Most *-AD* commands that change something
accept -WhatIf; run a bulk script with it first. To see
who really ends up in a group through nesting:
Get-ADGroupMember -Identity DL-BillingShare-Modify -Recursive |
Select-Object Name, SamAccountName, objectClass
Name SamAccountName objectClass ---- -------------- ----------- Lucía Romero lromero user Femke Jansen fjansen user
Accounts in Microsoft Entra ID, the cloud directory, are managed
with the Microsoft Graph PowerShell SDK
(Connect-MgGraph,
Get-MgUser, New-MgGroupMember); the older
MSOnline and AzureAD modules have been retired and no longer work
(2025). See
Microsoft Entra ID.
Common mistakes
-
Nesting nobody understands. Five levels of
groups, some created for a project that ended years ago, and loops
between them. Keep to two layers (role and resource), use a naming
convention that shows the scope and purpose (
GG-,DL-), and fill in the description and the "managed by" field of every group. - Distribution groups for access. They have no SID in the token, so the permission silently does nothing.
- Delete and recreate. A new account with the same name is a different SID; disable instead, and use the Recycle Bin for mistakes.
-
Accounts left in the default containers. The
built-in
CN=UsersandCN=Computerscontainers are not OUs, so OU-linked Group Policy does not reach them; see Group Policy. - Service accounts with interactive rights. A service account that can sign in to desktops is a target and an audit headache. Deny interactive sign-in, and move it to a gMSA.