Skip to content

Domain Accounts and Groups

On a domain controller, accounts and groups live in Active Directory instead of the local SAM. Everything in the Accounts group still applies: compare to the README, remove what isn't authorized, fix what is. The tools change.

Tools

Task Tool
Users, groups, OUs Active Directory Users and Computers (dsa.msc)
Domain-wide policy Group Policy Management (gpmc.msc)
Command line net user /domain, net group /domain, and the ActiveDirectory PowerShell module (installed with the DC role; on a member, Install-WindowsFeature RSAT-AD-PowerShell)

List domain accounts and admins

net user /domain
net group "Domain Admins" /domain
net group "Enterprise Admins" /domain
net group "Schema Admins" /domain

PowerShell gives you the columns that matter:

Get-ADUser -Filter * -Properties Enabled, PasswordNeverExpires, PasswordNotRequired, LastLogonDate, AdminCount |
  Select SamAccountName, Enabled, PasswordNeverExpires, PasswordNotRequired, LastLogonDate, AdminCount | Sort SamAccountName

Compare the list to the README's authorized users, then look at the flags. PasswordNotRequired True means the account can have a blank password. PasswordNeverExpires True exempts it from the domain policy. AdminCount 1 means the account is, or once was, in a protected group.

Privileged groups

Membership in any of these is domain-wide control. The README lists who the domain administrators are; everyone else comes out.

Group Grants
Domain Admins Administrator on every machine in the domain
Enterprise Admins Everything, across every domain in the forest. Usually empty.
Schema Admins Can change the AD schema. Usually empty.
Administrators (on the DC) Administrator on domain controllers. Domain Admins and Enterprise Admins are members through nesting. Only the people responsible for the DC belong here (STIG WN22-DC-000010).
Account Operators Create and modify most accounts and groups
Server Operators Log on to DCs, manage services, back up and restore
Backup Operators Read anything on the DC, including the AD database, which holds every password hash
Group Policy Creator Owners Create GPOs, which run on every machine they're linked to
DnsAdmins Can load a DLL into the DNS service, which runs as SYSTEM on the DC
foreach ($g in 'Domain Admins','Enterprise Admins','Schema Admins','Administrators','Account Operators','Server Operators','Backup Operators','Group Policy Creator Owners','DnsAdmins') {
  "== $g"; Get-ADGroupMember $g -Recursive | Select -Expand SamAccountName
}

-Recursive matters: a user put into a group that's inside Domain Admins is a domain admin.

Remove:

Remove-ADGroupMember "Domain Admins" -Members hacker -Confirm:$false

Disable, remove, create

Disable-ADAccount hacker
Remove-ADUser hacker -Confirm:$false
New-ADUser carol -AccountPassword (Read-Host -AsSecureString) -Enabled $true -ChangePasswordAtLogon $true
Set-ADUser bob -PasswordNeverExpires $false -PasswordNotRequired $false

Domain account flags can also be bulk-fixed:

Get-ADUser -Filter {PasswordNotRequired -eq $true} | Set-ADUser -PasswordNotRequired $false
Get-ADUser -Filter {PasswordNeverExpires -eq $true} | Set-ADUser -PasswordNeverExpires $false

Leave krbtgt alone; it's disabled by design and the domain doesn't work without it.

The built-in domain accounts

Administrator (the domain one, not a local one) can't be deleted. Rename it and give it a long password, the same as on a standalone machine. Guest is disabled by default; make sure it still is (Get-ADUser Guest | Select Enabled). krbtgt signs every Kerberos ticket; its password should have been reset within the last 180 days (STIG WN22-DC-000430). Check with:

Get-ADUser krbtgt -Properties PasswordLastSet | Select PasswordLastSet

If it's old, reset it twice, waiting a few minutes between (each reset invalidates tickets signed with the old key, and two resets clear the history): Set-ADAccountPassword krbtgt -Reset -NewPassword (Read-Host -AsSecureString). On a one-DC competition domain this is safe; on a real multi-DC domain you'd wait for replication in between.

Inactive and never-used accounts

The domain remembers last logon. Accounts unused for 35 days should be disabled (the same rule as the STIG on a standalone machine):

Search-ADAccount -AccountInactive -TimeSpan 35 -UsersOnly | Select SamAccountName, LastLogonDate
Search-ADAccount -AccountInactive -TimeSpan 35 -UsersOnly | Disable-ADAccount

Check the README first: a listed user who hasn't logged in yet is authorized, not inactive.

Local accounts on domain machines

On a domain-joined workstation or member server, people should have domain accounts, not local ones (STIG WN11-00-000085). A local account is outside the domain's password policy, auditing, and disablement, and if its password is the same on two machines it's a lateral-movement path. On each member, net user should show only the built-in accounts and any local administrator the organization uses for emergencies, and that one should be managed by LAPS (Member Servers in a Domain).

Verify

Get-ADGroupMember "Domain Admins" -Recursive | Select -Expand SamAccountName
Get-ADUser -Filter {Enabled -eq $true} | Select -Expand SamAccountName
Get-ADUser -Filter {PasswordNotRequired -eq $true -or PasswordNeverExpires -eq $true} | Select SamAccountName

The first two match the README; the third is empty.

Example

net group "Domain Admins" /domain lists Administrator, alice, svc_backup, guest2. README: alice is the only domain admin. Remove svc_backup and guest2 from the group, then check whether either account should exist at all. Get-ADGroupMember Administrators -Recursive also turns up helpdesk, nested through a group called IT; the README doesn't give helpdesk administrator rights on the DC, so IT comes out of Administrators.

Next

Domain Policies