PingCastle assessment: from AD report to action plan
Run a PingCastle health check on Active Directory, read the four risk scores correctly, triage findings into owners and sprints, and track progress over time.
A PingCastle report is the fastest way to get an honest picture of an Active Directory domain. It is also easy to misuse. Teams run it once, look at a red score, fix the three easiest findings, and never open it again. Others chase the score to zero and spend weeks on low-impact hygiene while an unconstrained delegation server or a writable GPO on the Domain Controllers OU stays open. This guide covers running PingCastle safely, reading its output the way the scoring model intends, and turning the findings into a remediation plan with owners, order and verification.
The wider assessment strategy, including baseline comparison with SCT and CIS and how PingCastle fits next to Purple Knight, is in the assessment, backup and recovery pillar guide. This guide is about getting from one report to an executed plan.
Measure: run the health check
Download PingCastle from its official site onto a management workstation or a privileged access workstation. Verify the file signature, and do not run it from a DC. Run it as a standard domain user. The health check does not need administrative rights, and running it as Domain Admin only exposes a Tier 0 credential on another machine.
# Verify the binary before first use
Get-AuthenticodeSignature .\PingCastle.exe | Select-Object Status, SignerCertificate
# Health check against a specific domain
.\PingCastle.exe --healthcheck --server corp.example.comRunning PingCastle.exe with no arguments opens an interactive menu. Option 1 is the same health check. Each run produces two files named after the domain:
ad_hc_<domain>.html, the report for humans.ad_hc_<domain>.xml, the data for trending and scripting. It contains detailed data about your domain, so store it with the same care as the HTML.
Run it once per domain, including every child domain and any domain you trust. The trusts section shows what the scanned domain exposes, but risks inside a trusted domain only appear when you scan that domain.
Audit: read the report correctly
The four scores
PingCastle groups rules into four categories, each scored from 0 (best) to 100:
| Category | Covers | Typical findings |
|---|---|---|
| Stale Objects | Old operating systems, inactive accounts, obsolete settings | Unsupported OS on computers, accounts with non-expiring passwords, primary group oddities |
| Privileged Accounts | Admin group membership and admin account hygiene | Too many Domain Admins, admins not in Protected Users, Kerberoastable admin accounts, unconstrained delegation |
| Trusts | Inbound and outbound trusts | SID filtering disabled, trusts to domains that no longer exist, SID History |
| Anomalies | Configuration weaknesses that enable attacks | Old krbtgt password, LAPS missing, NTLMv1 or LM allowed, LDAP signing, spooler on DCs, GPP passwords |
The domain risk score is the highest of the four, not the sum. A domain with 15, 10, 0 and 85 scores 85, because one bad category is enough for an attacker. It also means fixing Stale Objects does nothing to the headline score while Anomalies is the worst category.
Maturity levels and rule IDs
Each rule has an ID with a category prefix (S-, P-, T-, A-), a point value and a maturity level from 1 to 5. Level 1 findings are the most critical. The report's maturity section tells you the lowest level at which your domain fails, and that is a better progress metric for management than the raw score. Moving from level 1 to level 3 is a real improvement even if the score barely moves.
Expand each rule in the HTML report. The detail lists the exact objects involved and links to the documentation behind the rule. Always work from the object list, not from the rule title.
Triage: turn findings into a plan
Export the rules from the XML so they can go into a tracker:
[xml]$hc = Get-Content .\ad_hc_corp.example.com.xml
$hc.SelectNodes('//HealthcheckRiskRule') |
Select-Object RiskId, Category, Points, Rationale |
Sort-Object Points -Descending |
Export-Csv .\pingcastle-findings.csv -NoTypeInformationSort every finding into one of four buckets:
- Fix this week (attack path to Tier 0). Anything that gives a non-admin a route to domain dominance. Examples include unconstrained delegation on non-DC servers, dangerous ACEs on privileged objects, non-default principals with DCSync rights, GPP passwords, AD CS templates vulnerable to ESC1, and the spooler service running on DCs. These map directly to DCSync rights, removing unconstrained delegation and auditing certificate templates.
- Projects (need change control). Settings that can break applications: LDAP signing, NTLM restrictions, SMB signing, RC4 removal, LAPS deployment. Give each one an owner, a pilot group and an audit phase before enforcement.
- Hygiene (batch work). Inactive accounts, old computer objects, non-expiring passwords on non-service accounts. Automate these rather than fixing them by hand.
- Accepted risk. A documented exception with a business owner, a compensating control and a review date. PingCastle has no concept of your exceptions, so the register lives in your tracker.
Two rules keep this honest. First, every bucket-1 item gets an owner and a date within days. Second, the Privileged Accounts and Trusts categories are re-checked on every run, because they change fastest and matter most.
Map each finding to the site's method: Measure (the object list from the report), Audit (turn on logging for the setting before changing it), Enforce, Verify (the next PingCastle run). The hardening checklist gives a default order if you need one.
Presenting the results
Leadership does not need the HTML report. They need three things on one page: the current maturity level and its trend, the number of open bucket-1 findings with their age, and the list of accepted risks with named owners. Keep the raw score in an appendix, because it swings with rule changes and invites the wrong conversation.
For each domain, show the category scores side by side. A forest where the root domain is at maturity level 3 but an acquired child domain is at level 1 is a forest at level 1, because trusts inside a forest do not stop an attacker. Say so explicitly, so the weakest domain gets funding rather than the most visible one.
Enforce: schedule and trend
A single report is a snapshot. Schedule the health check so that drift shows up within a week:
$action = New-ScheduledTaskAction -Execute 'C:\Tools\PingCastle\PingCastle.exe' `
-Argument '--healthcheck --server corp.example.com' -WorkingDirectory 'D:\PingCastle\Reports'
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At 6am
Register-ScheduledTask -TaskName 'PingCastle weekly' -Action $action -Trigger $trigger `
-User 'CORP\svc-pingcastle' -Password (Read-Host 'Password')Better still, use a gMSA as the task identity so no password is stored. Keep the XML files, renamed with the date, in a folder only the security team can read. Update PingCastle deliberately, not automatically, and note the version in each report's filename. A rule change should never be confused with a change in your domain.
Verify
After each remediation sprint, re-run and compare rule sets rather than scores:
[xml]$old = Get-Content .\2026-08-31_ad_hc_corp.example.com.xml
[xml]$new = Get-Content .\2026-09-28_ad_hc_corp.example.com.xml
$o = $old.SelectNodes('//HealthcheckRiskRule').RiskId
$n = $new.SelectNodes('//HealthcheckRiskRule').RiskId
Compare-Object $o $n | ForEach-Object {
[pscustomobject]@{ RiskId = $_.InputObject; Change = if ($_.SideIndicator -eq '=>') {'NEW'} else {'FIXED'} }
}Treat every NEW rule in Privileged Accounts or Trusts as an incident until explained. Check who changed what with the group and trust events from the event IDs reference. For fixed items, confirm the object list is empty, not just that the point value dropped below a threshold.
What it breaks
Running PingCastle is read-only, but acting on its report without the audit step breaks things:
- Enforcing protocol findings directly. Requiring LDAP signing, disabling NTLMv1 or removing RC4 because a report said so, without the audit phase, causes outages. Old appliances, scanners and Java applications fail first.
- Mass-disabling inactive accounts. "Inactive" is based on
lastLogonTimestamp, which can lag by up to 14 days, and some service accounts authenticate in ways that do not update it. Disable in batches, move to a quarantine OU, and delete only after a waiting period. - Adding admins to Protected Users. This removes NTLM, DES, RC4 and credential delegation for those accounts. Test each admin's workflow before a bulk change.
- Security tooling alerts. The health check performs broad LDAP queries that Defender for Identity or your honeytokens may flag as reconnaissance. Tell the SOC which account and host run it, and exclude it from decoy rules deliberately.
Related reading: the assessment, backup and recovery area covers the rest of this series, attack path management finds routes to Tier 0 that rule-based scanners miss, and protecting AD backups from ransomware covers the control that PingCastle cannot check for you.
Frequently asked questions
Does PingCastle need Domain Admin rights to run a health check?
No. The health check reads the directory over LDAP and other standard protocols, so an ordinary authenticated domain user is enough for most of it. Running it as a Domain Admin adds little and exposes a Tier 0 credential on whatever machine you run it from. Use a standard account from a management workstation. Some optional scanners that query individual computers need local administrator rights on those targets, but the core health check does not.
Why did our PingCastle score get worse when we did not change anything?
Three common causes. New PingCastle versions add rules and re-weight existing ones, so the same domain can score differently after an upgrade. Time-based rules trigger as dates pass, such as the krbtgt password age or accounts becoming inactive. And the overall domain score is the highest of the four category scores, so a single new finding in one category can move the headline number. Compare rule lists between reports, not just scores.
Is PingCastle free to use?
The basic edition is free for an organisation to assess its own Active Directory, which covers most internal use. Using it to audit other companies' environments, for example as a consultant or managed service provider, requires a commercial licence, as do the enterprise features for consolidated dashboards across many domains. Check the licence text shipped with the version you download, because terms have changed over time.
PingCastle assessment: from AD report to action plan