the admin café

Menu / Tools

ADHardenKit: Hardening AD Without Breaking It

LDAP signing, SMB signing, NTLM, Kerberos with AES only. Every hardening checklist has them. I wrote a tool that turns them on in an order that doesn't break the domain.

Lukas·Oct 7, 2026·5 min · Cappuccino 5 min · Cappuccino· Intermediate · Medium

Every AD hardening checklist has the same items on it: require LDAP signing, require SMB signing, restrict NTLM, use Kerberos with AES only. In theory you just turn them on. In practice almost every one of them can break something that used to work, and the error shows up somewhere else. Require LDAP signing and a print server can't find the directory anymore. Enforce SMB signing and a NAS drops out at 3 a.m. Restrict NTLM, and a business application stops with an error message that tells you nothing.

So checklists often get applied halfway, or applied on a Friday and rolled back on Monday.

I wanted a tool that does it in the right order: watch first, see what would break, and only then enforce. So I built one. It's called ADHardenKit. It covers the layer below ADTierKit: signing, credential protection, legacy authentication and audit logging.

What it is

One PowerShell script, no module, no configuration file. Copy it onto a domain controller or a management host with RSAT and run it. Without parameters you get a menu for mode, profile and scope, and at the end it shows you the command line it's going to run, so next time you can use that one.

PowerShell
# Read-only: where does the domain stand?
.\ADHardenKit.ps1 -NoMenu

# Turn on logging first. Nothing in this group can refuse a logon.
.\ADHardenKit.ps1 -Mode Deploy -Area Logging -Apply -MemberServerOu 'OU=Servers,DC=example,DC=com'

# Weeks later: scan again, then go through the rest topic by topic
.\ADHardenKit.ps1
.\ADHardenKit.ps1 -Mode Deploy -Interactive -Apply -MemberServerOu 'OU=Servers,DC=example,DC=com'

Like ADTierKit, deploy mode only plans. You need -Apply before it writes anything.

The order

1. Logging  ->  2. Scan  ->  3. Wait  ->  4. Audit level  ->  5. Enforce

Logging first. Audit subcategories, PowerShell logging, NTLM auditing, the LDAP interface diagnostics. This group only writes events, so it can't break anything, and it gives every later scan something to read.

Then scan. The scan reads the event logs on the domain controllers and tells you by name which clients would break: event 2889 for every unsigned LDAP bind, 8001 and 8004 for NTLM, and the accounts that still depend on RC4.

On a domain that nobody has watched before, the first scan reports that it can't see much. That's expected. The diagnostics that produce the evidence are off by default. With the LDAP diagnostic off, Windows never writes event 2889, so an empty result only tells you that the log is empty. In my opinion that's the most dangerous result you can get, because it looks green and you might enforce LDAP signing because of it. So the scan reports it as a finding.

Then wait for a few weeks. The client that binds without signing only at month-end is the one you'd miss after three days.

Then the observing form, then enforce, one group at a time. If something breaks, you want to know which group caused it.

Nine settings that can break things

The tool deploys a bit over 90 settings. Most of them carry little or no compatibility risk, that's the Baseline profile. Nine of them can break something, and each of those comes in two forms, one that watches and one that requires.

SettingObservingWhere you see what would break
LDAP server signingnegotiateDirectory Service log, event 2889
LDAP channel bindingwhen supportedevents 3039, 3074, 3075
Outgoing NTLMauditNTLM operational log, event 8001
Kerberos encryption typesAES, RC4 still allowedaccounts that still depend on RC4
Strong certificate bindingcompatibilitySystem log, events 39, 40, 41

Three of the nine have no watching form: SMB signing on the server, SMB signing on the client, and denying incoming NTLM. SMB signing in the registry is either required or it isn't, and writing a zero there would switch off signing that a domain controller requires by default. So at -Level Audit the tool leaves those three out, and a guard refuses to write a zero for any of the staged settings, even if someone edits the table later. For SMB you watch in a different place:

PowerShell
Set-SmbServerConfiguration -AuditClientDoesNotSupportSigning $true
Set-SmbClientConfiguration -AuditServerDoesNotSupportSigning $true

With -Interactive you go through every topic on its own. For each one you see the current value on the domain controller next to the target, what it does, what it can break, and the KB number to look it up.

Small GPOs on purpose

Each group gets two GPOs, one for domain controllers and one for member servers: Signing, LegacyAuth, CredentialProtection, Protocols, PolicyIntegrity, Logging, Services. If SMB signing turns out to be holding up a NAS, you unlink ADHardenKit-Member-Signing and everything else stays in place. With one big GPO you'd have to roll back everything at once, and under pressure that's what people do.

There's also an opt-in group, LOLBins. It blocks outbound network access for binaries that attackers like to use as download tools, like certutil, mshta, bitsadmin and the script hosts, as firewall rules inside the GPO. The list for domain controllers is short on purpose. certutil fetches CRLs on a DC, and blocking that ends up as an authentication outage that doesn't look like a firewall problem.

One warning

Unlinking a GPO doesn't take all of its settings back. I measured this in the lab, and the result is less convenient than "unlink and you're done".

Values under a Policies branch in the registry disappear at the next refresh. The security template (GptTmpl.inf) sets values and leaves them in place when the policy stops applying. That covers most of the baseline, every security option, including LSA protection and the Netlogon settings.

Unlinking is still the right first move when something breaks, because it stops any further enforcement. For a real revert you write the old values back, and the README lists the commands for that. Take a system state backup of a domain controller before the first enforced run.

Where it stands

The current version is 1.3.1. I tested it end to end in a lab with a Server 2025 domain, not in production yet. It runs on Server 2016 and later. A few settings only work on newer builds. The tool marks those, so you know they do nothing on an older server. Every run writes a log and a JSON and HTML report.

Like with NTLM-Analyzer, Claude wrote most of the code in a pair-programming workflow. I defined what it should do, reviewed it and tested it. Please review it before you run it in production, like any code you didn't write yourself.

It doesn't do tiering, LAPS, AppLocker, BitLocker or Defender. ADTierKit covers the tier boundary.

The README has everything else: all settings per group, what runs on which Windows version, troubleshooting and the full rollback:

github.com/Nobrac/ADHardenKit

GPLv3 licensed. If you run it against a real directory, I'd like to hear which staged setting broke something, and what it was.

Licensed under CC BY-NC-SA 4.0.

Still sipping? Another one?

pairs well with this one

the admin café

Open whenever the shell is. Right now, apparently.

Tip jar. Costs nothing, cheers me up anyway.

© 2023–2026 Lukas. Servus.

Esc

Fresh today

Type to search all articles. ↑ ↓ and Enter to open a result.