Part 1 stood up the DC. Part 2 built the OU structure. This part populates the OUs with policies that actually do something.
The policies below are the minimum I run on every domain. Default Domain Policy out-of-the-box is permissive — 7-character passwords, no lockout, no audit. None of those are okay in 2026.
TL;DR — the GPOs to create and where to link them:
| GPO | Linked at | Purpose |
|---|---|---|
| Password Policy | Domain root | Length, complexity, lockout |
| Audit Policy | Domain root | Logon, account changes, privilege use |
| Hardening — Protocols | Domain root | SMBv1 off, LLMNR off, NTLMv1 refused |
| RDP Restrictions | OU=Servers | Allow group, NLA enforced, IP scope |
| BitLocker Enforcement | OU=Workstations and OU=Servers | TPM unlock, recovery to AD |
| Defender Hardening | All workstations | ASR rules, tamper protection |
Each one's a small, focused GPO. Don't make one giant "Hardening" GPO — they get hard to debug and require all-or-nothing rollback.
Password policy
Old default: 7 chars, complexity off, no lockout. Bad on a desktop, suicidal on a domain.
Edit Default Domain Policy (or build a new GPO and override) — Computer Config → Policies → Windows Settings → Security Settings → Account Policies:
Password Policy:
Enforce password history: 24
Maximum password age: 365 days (or 0 = never expire, see below)
Minimum password age: 1 day
Minimum password length: 14
Password must meet complexity: Enabled
Account Lockout Policy:
Account lockout threshold: 5 invalid logon attempts
Account lockout duration: 30 minutes
Reset account lockout counter after: 30 minutes
Why 14 chars and no expiration: NIST recommends long passwords without forced rotation. Forced rotation breeds Spring2024! → Summer2024! patterns. A 14-char password is computationally infeasible to brute force; rotation buys nothing on top of that.
If your auditor still demands 90-day rotation, set 90. Both are defensible — long-no-rotation is just better.
These are forest-wide. If you need per-OU exceptions (e.g. service accounts with stricter rules), use Fine-Grained Password Policies (PSO) via New-ADFineGrainedPasswordPolicy.
Audit policy
Default is "log a few things badly." You want detailed audit on logons and account changes.
Computer Config → Policies → Windows Settings → Security Settings → Advanced Audit Policy Configuration:
Account Logon:
Audit Credential Validation: Success and Failure
Audit Kerberos Authentication Service: Success and Failure
Audit Kerberos Service Ticket Operations: Success and Failure
Account Management:
Audit User Account Management: Success and Failure
Audit Security Group Management: Success and Failure
Logon/Logoff:
Audit Logon: Success and Failure
Audit Logoff: Success
Audit Special Logon: Success
Privilege Use:
Audit Sensitive Privilege Use: Success and Failure
System:
Audit System Integrity: Success and Failure
Audit Security State Change: Success
Plus on the DC, increase Security log size:
Computer Config → Policies → Windows Settings → Security Settings →
Event Log → Security: Maximum size = 1 GB
Default is 20 MB. Fills in a day on an active DC. 1 GB lets you actually look at events from last week. Forward to a SIEM if you have one.
Same audit lines you'd hunt with Get-WinEvent post-incident.
Protocol hardening — SMBv1, LLMNR, NTLMv1
The trio from the standalone post, now via GPO so every machine in the domain inherits.
LLMNR off:
Computer Config → Policies → Administrative Templates → Network → DNS Client →
Turn off multicast name resolution: Enabled
NTLMv1 off:
Computer Config → Policies → Windows Settings → Security Settings → Local Policies →
Security Options →
Network security: LAN Manager authentication level = Send NTLMv2 only. Refuse LM & NTLM
Microsoft network server: Digitally sign communications (always) = Enabled
Network security: Restrict NTLM: Audit Incoming NTLM Traffic = Enable auditing for all accounts
The Restrict NTLM audit setting is reconnaissance — it logs what's still using NTLM so you can identify and replace it. Don't switch directly to "Deny" without auditing first; you will break legitimate things you didn't know existed.
SMBv1: GPO has no native toggle. Push via the registry path that the OS reads:
Computer Config → Preferences → Windows Settings → Registry → New →
Hive: HKLM
Key: SYSTEM\CurrentControlSet\Services\mrxsmb10
Value name: Start
Value type: REG_DWORD
Value data: 4 (Disabled)
Reboot required — schedule.
NBT-NS via Preferences too — adapter setting, push as PowerShell startup script if needed.
RDP — link to OU=Servers
The standalone hardening but pushed via GPO:
Computer Config → Policies → Administrative Templates → Windows Components →
Remote Desktop Services → Remote Desktop Session Host → Security:
Require user authentication for remote connections by using NLA: Enabled
Set client connection encryption level: High Level
Restrict who can RDP in:
Computer Config → Policies → Windows Settings → Security Settings → Local Policies →
User Rights Assignment:
Allow log on through Remote Desktop Services: <your IT-Admins group>
Remove Administrators from this list (counterintuitively) — instead, members of IT-Admins who happen to also be local admins can RDP. Default-deny is the goal.
Restrict from where:
Computer Config → Policies → Windows Settings → Security Settings → Windows Firewall →
Inbound Rules → "Remote Desktop - User Mode (TCP-In)":
Scope → Remote IP: <your trusted ranges>
Link the GPO at OU=Servers,OU=Computers,OU=Corp,DC=.... Workstations get a separate (looser, e.g. LAN-only) RDP policy.
BitLocker enforcement
Computer Config → Policies → Administrative Templates → Windows Components →
BitLocker Drive Encryption → Operating System Drives:
Require additional authentication at startup: Enabled
Allow BitLocker without a compatible TPM: No
Choose how BitLocker-protected operating system drives can be recovered:
Save BitLocker recovery information to AD DS: Enabled
Do not enable BitLocker until recovery information is stored: Enabled
This forces:
- New machines must encrypt the OS drive.
- They must have a TPM (modern hardware does).
- The recovery key auto-saves into the AD object — no more "where did we put the key" panics.
Recovery keys then visible via Get-ADObject -Filter ... -Properties msFVE-RecoveryPassword or in the BitLocker tab of the computer object in ADUC.
Pair with the BitLocker-on-server post for the manual side.
Defender ASR rules
Microsoft Defender Attack Surface Reduction — block specific tactics like "Office macros launch processes":
Computer Config → Policies → Administrative Templates → Windows Components →
Microsoft Defender Antivirus → Microsoft Defender Exploit Guard →
Attack Surface Reduction → Configure Attack Surface Reduction rules: Enabled
Add rule IDs as values, set to "Block":
BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550 ← Block Office from creating child processes
D4F940AB-401B-4EFC-AADC-AD5F3C50688A ← Block Office from creating executable content
9E6C4E1F-7D60-472F-BA1A-A39EF669E4B2 ← Block credential stealing from LSASS
D3E037E1-3EB8-44C8-A917-57927947596D ← Block JS/VBScript launching downloaded content
There are ~15 ASR rules. Start with these four — high signal, low false positive. Add more after a month of audit-mode (Audit instead of Block first).
Linking and inheritance
$domain = "DC=lab,DC=example,DC=com"
# Domain-wide
New-GPLink -Name "Password-Policy" -Target $domain
New-GPLink -Name "Audit-Policy" -Target $domain
New-GPLink -Name "Protocol-Hardening" -Target $domain
# OU-scoped
New-GPLink -Name "RDP-Server-Policy" -Target "OU=Servers,OU=Computers,OU=Corp,$domain"
New-GPLink -Name "BitLocker-Workstations" -Target "OU=Workstations,OU=Computers,OU=Corp,$domain"
New-GPLink -Name "BitLocker-Servers" -Target "OU=Servers,OU=Computers,OU=Corp,$domain"
New-GPLink -Name "Defender-ASR" -Target "OU=Workstations,OU=Computers,OU=Corp,$domain"
GPO inheritance is top-down: domain root → OU → child OU. Settings further down win on conflict (last applied wins). Use Enforced sparingly to override child blocks; use Block Inheritance even more sparingly because it cuts everything.
Test before pushing domain-wide
Critical: test new GPOs on a single machine before linking to the domain.
- Create the GPO unlinked.
- Link to
OU=Testcontaining one VM. gpupdate /forceon the VM, reboot, verify.- Test for at least a day under normal use.
- Move the link to broader scope.
Skip this and your "small password tweak" will lock out the CEO at 9am Monday.
What this combines with
Every other Windows-server post in the cluster:
- SMBv1 / LLMNR / NTLMv1 hardening — the GPO version of those settings.
- BitLocker on Windows Server — manual side; this post automates via GPO.
- RDP hardening — same theme, GPO-driven.
- Windows Server initial setup — what to do on every box before joining the domain.
GPO is the multiplier: do the work once at the domain level, every joined machine inherits.
Gotchas
- GPOs cache for 90 minutes by default. Changes don't apply instantly.
gpupdate /forcetriggers immediately on one machine. Domain-wide is "next refresh". - Don't edit Default Domain Policy and Default Domain Controllers Policy with abandon. They have Microsoft-blessed defaults; create new GPOs with overrides instead. Easier to roll back.
- WMI filters slow GPO processing. Powerful but expensive — use security-group filtering when you can.
- Loopback processing is a niche feature. Ignore until you have a specific need (terminal-server kiosk, etc.). Adding it casually breaks user-policy expectations.
- Audit GPO links after restructures. Moving an OU doesn't move the linked GPOs — the new parent's GPOs apply, not the OU's old ones.
This is the spine. Every additional hardening (vendor-specific antivirus, DLP, EDR baselines) layers on top via more GPOs. With the OU structure from Part 2 and these baseline policies, you have a defensible domain ready for actual workloads.