Skip to content
Zoos GlobalZoos GlobalZoos EngineeringHub

datadog-adfs-integration

README documentation for datadog-adfs-integration

stableRepositoryPythonprivate
12 min readUpdated Jul 24, 2026@observability-teamObservability
Edit source

Source: ZoosGlobal/datadog-adfs-integration Visibility: Private This page is automatically synchronized from the repository README. Do not edit this generated file directly.




Zoos Global      Datadog Premier Partner

Version Platform PowerShell Datadog Partner License Status


PowerShell → Windows ADFS Server → DogStatsD → Datadog Metrics → Dashboards & Alerts

Monitors SSO certificate expiry across all Relying Party Trusts, ADFS service health,
Windows Internal Database, and service account lockout — via a single lightweight
PowerShell script submitted every 5 minutes to Datadog.


Metrics Certs RPTs Coverage


Microsoft Active Directory Federation Services (ADFS) underpins Single Sign-On (SSO) access to business-critical applications, cloud services, and federated identity providers — but its health was scattered across Windows Services, IIS, Active Directory, certificates, and event logs with no centralized way to monitor it:

  • No unified visibility — ADFS health depends on multiple independent subsystems (the adfssrv service, IIS application pools, Windows Internal Database, AD service accounts, and a web of federation trust certificates), and none of these were monitored together in one place.
  • Certificate expiry is a silent, high-impact failure mode — Token-signing, token-decrypting, service communication, and SSL/HTTPS binding certificates — plus every Relying Party Trust’s own encryption and request-signing certificates — can expire without warning, breaking authentication for every application relying on that trust the moment it happens.
  • Service account lockouts halt token issuance instantly — A locked, disabled, or expired-password service account can stop ADFS from issuing tokens fleet-wide, but without active monitoring this was only discovered after authentication started failing.
  • Dependency failures are easy to miss — IIS ADFSAppPool crashes or Windows Internal Database outages can quietly disrupt authentication without an obvious top-level signal pointing back to the root cause.
  • Reactive, not proactive, troubleshooting — Without consolidated monitoring, authentication incidents were typically discovered only after users started reporting login failures — by which point the business impact had already occurred.
  • Scale of the trust relationships involved — With 100+ certificate objects across dozens of Relying Party and Claims Provider Trusts, manually tracking expiry dates and trust health was operationally infeasible.

We built a lightweight, self-contained PowerShell monitoring framework that runs directly on the ADFS server and submits service health, certificate, trust, and account security metrics to Datadog via DogStatsD every 5 minutes — giving identity, infrastructure, and security teams a single pane of glass over the entire ADFS ecosystem.

ADFS Server (adfssrv, IIS, WID, AD, certificate stores, RPTs/CPTs)
Invoke-ADFSMonitor.ps1 (runs every 5 minutes)
DogStatsD (UDP 127.0.0.1:8125)
Datadog Agent
Datadog Metrics (adfs.service.*, adfs.cert.scan.*, adfs.rpt.*, adfs.cpt.*, adfs.account.*)
Dashboards & Monitors
Decision Rationale
Single script covering service, certs, trusts, and accounts ADFS health is multi-dimensional by nature; consolidating all KPIs into one collector gives one consistent execution cadence and one place to maintain monitoring logic
DogStatsD over UDP, not a custom Agent check Keeps the integration entirely self-contained in a single PowerShell script — no separate check package to build, version, or deploy
Full certificate scan across every cert type and trust Token-signing, token-decrypting, service-communication, HTTPS binding, and every Relying Party/Claims Provider Trust’s encryption and request-signing certs are scanned in one pass, so no certificate category is left blind
Per-cert tagging instead of one metric per cert trust_name, cert_label, cert_status, thumbprint, and expiry_date are carried as tags on a small set of metrics, keeping custom-metric cardinality manageable even with 100+ certs in scope
Dedicated summary counters (expired_count, critical_count, warning_count) Gives an at-a-glance fleet-wide certificate health number, separate from the per-cert detail used for drill-down
AD service account lockout detection with event-source tracing Surfaces not just that an account is locked, but contributing signals (bad logon count, password age) and the lockout event source, so the root cause can be chased down immediately
Graceful skip on missing dependencies (-1 values) Backend ADFS nodes without IIS, or deployments using SQL Server instead of WID, report -1 rather than a false failure — avoiding noisy, incorrect alerts
One-click setup.ps1 with dry-run validation Installs prerequisites, validates the Datadog Agent and ADFS service, runs a dry-run before sending live data, and registers the 5-minute scheduled task — turning a multi-step setup into a single guided run
Pre-built monitors for the highest-impact failure modes Service down, certificate expiry (warning/critical), account lockout, bad logon spikes, and password age are all alertable out of the box, not left for someone to configure later
  • ADFS service health, certificate lifecycle, trust inventory, and service account security are all visible in Datadog as a single, correlated view — no more switching between Windows Services, IIS Manager, AD Users & Computers, and the certificate store.
  • Certificate expiry — previously discovered only after authentication broke — is now flagged 30 days and 14 days out, giving teams time to renew before impact.
  • Service account lockouts trigger an immediate alert instead of being discovered through a wave of failed logins.
  • The entire integration runs on the existing ADFS server with no new infrastructure, completing a full health/cert/account scan every 5 minutes (288 runs/day).
C:\Scripts\ADFSMonitor\
└── Invoke-ADFSMonitor.ps1 # Main metric collection & DogStatsD submission script
setup.ps1 # One-click setup: copies script + creates scheduled task
README.md # This file

Tags: env, role:adfs-server, host

Metric Description
adfs.service.is_running ADFS service running status 1=up 0=down
adfs.service.start_auto StartType is Automatic 1=yes 0=no
adfs.service.uptime_hours Hours since adfssrv last started
adfs.service.wid_running Windows Internal Database running 1=up 0=down -1=N/A
adfs.service.apppool_running IIS ADFSAppPool running 1=up 0=down -1=N/A

Tags: trust_name, trust_type, cert_label, cert_status, thumbprint, subject_cn, issuer_cn, expiry_date

Metric Description
adfs.cert.scan.days_remaining Days until expiry — negative = already expired 🔴
adfs.cert.scan.expiry_epoch Expiry as Unix epoch timestamp
adfs.cert.scan.is_valid Certificate valid flag 1=valid 0=expired
adfs.cert.scan.total_count Total cert objects scanned per run
adfs.cert.scan.expired_count Total expired certs right now 🔴
adfs.cert.scan.critical_count Certs expiring within 14 days ⚠️
adfs.cert.scan.warning_count Certs expiring within 30 days ⚠️
adfs.cert.auto_rollover_enabled Auto certificate rollover enabled 1=yes 0=no

cert_label values:

Label Source
token-signing ADFS token-signing certificate
token-decrypting ADFS token-decrypting certificate
service-communications ADFS service communication certificate
https-binding SSL certificate on ADFS HTTPS binding
encryption Relying Party Trust encryption certificate
request-signing Relying Party Trust request-signing certificate

Tags: env, role, host, rpt_name

Metric Description
adfs.rpt.total_count Total Relying Party Trusts configured
adfs.rpt.is_enabled RPT enabled flag per trust 1=enabled 0=disabled

Metric Description
adfs.cpt.total_count Total Claims Provider Trusts configured

adfs.account.* — Service Account Lockout

Section titled “adfs.account.* — Service Account Lockout”

Tags: env, role, host, account

Metric Description
adfs.account.is_locked Account locked status 1=locked 0=ok 🔴
adfs.account.is_enabled Account enabled status 1=enabled 0=disabled
adfs.account.bad_logon_count Bad logon attempts — high = stale credentials ⚠️
adfs.account.password_age_days Days since password was last changed
adfs.account.password_expired Password expired flag 1=expired 0=ok
adfs.account.lockout_event Lockout event detected 1=lockout found (with source tag)

Requirement Version
Windows Server 2016 / 2019 / 2022 / 2025
ADFS Role Installed & Running (adfssrv)
Datadog Agent v7+ (DogStatsD on 127.0.0.1:8125)
PowerShell 5.1+
RSAT — AD Module For account lockout metrics
Privileges Administrator / SYSTEM

Terminal window
# Download installer
Invoke-WebRequest `
-Uri "https://s3.amazonaws.com/ddagent-windows-stable/datadog-agent-7-latest.amd64.msi" `
-OutFile "C:\ddagent.msi"
# Install with your API key
Start-Process -Wait msiexec `
-ArgumentList '/qn /i C:\ddagent.msi APIKEY="<your_api_key>"'

Verify Agent is running:

Terminal window
Get-Service -Name "datadogagent"
# Expected: Status = Running

Verify DogStatsD is listening:

Terminal window
netstat -an | findstr 8125
# Expected: UDP 127.0.0.1:8125 *:*

Run as Administrator from the folder containing both files.

Terminal window
PowerShell.exe -ExecutionPolicy Bypass -File .\setup.ps1

With custom parameters:

Terminal window
# Custom service account and interval
PowerShell.exe -ExecutionPolicy Bypass -File .\setup.ps1 `
-Account "YourServiceAccount" `
-Interval 5
# Custom DogStatsD host
PowerShell.exe -ExecutionPolicy Bypass -File .\setup.ps1 `
-DDHost "10.0.0.1" `
-DDPort 8125

setup.ps1 performs 10 steps automatically:

[1/10] Validate Datadog Agent is running
[2/10] Verify DogStatsD on UDP :8125
[3/10] Validate ADFS service (adfssrv)
[4/10] Validate ActiveDirectory RSAT module
[5/10] Create C:\Scripts\ADFSMonitor directory
[6/10] Copy Invoke-ADFSMonitor.ps1 to destination
[7/10] Unblock scripts (remove Zone.Identifier)
[8/10] Dry-run validation (no metrics sent)
[9/10] Live run — push metrics to Datadog now
[10/10] Create Windows Scheduled Task (every 5 min, SYSTEM)

Always test manually before scheduling.

Terminal window
# Dry run — prints metrics without sending
PowerShell.exe -ExecutionPolicy Bypass -File `
"C:\Scripts\ADFSMonitor\Invoke-ADFSMonitor.ps1" -DryRun
# Live run — sends metrics to Datadog
PowerShell.exe -ExecutionPolicy Bypass -File `
"C:\Scripts\ADFSMonitor\Invoke-ADFSMonitor.ps1" `
-Account "EXLAdminsvc"

Expected output:

╔══════════════════════════════════════════════════════════╗
║ KPI 0 — ADFS Service Health ║
╚══════════════════════════════════════════════════════════╝
adfssrv Status : Running
adfssrv StartType : Automatic
adfssrv Uptime : 239h (since 2026-04-04 17:17)
WID (ADFS DB) : Running
╔══════════════════════════════════════════════════════════╗
║ KPI 1 — Full ADFS Certificate Scan ║
╚══════════════════════════════════════════════════════════╝
[server] [ADFS-Server] [token-signing ] 345d OK exp:2027-03-25
[ssl ] [ADFS-SSL ] [https-binding ] 184d OK exp:2026-10-16
[rpt ] [Druva-Phoenix] [request-signing ] -2887d EXPIRED exp:2018-05-20
...
│ Total certs scanned : 101 │
│ Expired : 33 │
│ Critical (< 14 days): 0 │
│ Warning (< 30 days): 0 │
╔══════════════════════════════════════════════════════════╗
║ KPI 2 — Service Account Lockout ║
╚══════════════════════════════════════════════════════════╝
Locked : False
Enabled : True
Bad Logons : 1
Password Age : 324d
Pwd Expired : False
Done.

Verify in Datadog:
Metrics → Explorer → search adfs.service.is_running


Click to expand — PowerShell method
Terminal window
$action = New-ScheduledTaskAction `
-Execute 'PowerShell.exe' `
-Argument '-NonInteractive -ExecutionPolicy Bypass -File "C:\Scripts\ADFSMonitor\Invoke-ADFSMonitor.ps1" -Account "EXLAdminsvc"'
$trigger = New-ScheduledTaskTrigger `
-Once `
-At (Get-Date) `
-RepetitionInterval (New-TimeSpan -Minutes 5) `
-RepetitionDuration (New-TimeSpan -Days 3650)
$settings = New-ScheduledTaskSettingsSet `
-ExecutionTimeLimit (New-TimeSpan -Minutes 4) `
-MultipleInstances IgnoreNew `
-StartWhenAvailable
$principal = New-ScheduledTaskPrincipal `
-UserId 'NT AUTHORITY\SYSTEM' `
-RunLevel Highest `
-LogonType ServiceAccount
Register-ScheduledTask `
-TaskName 'ZoosGlobal-ADFS-Monitor' `
-Action $action `
-Trigger $trigger `
-Settings $settings `
-Principal $principal `
-Force

00:00 → Invoke-ADFSMonitor.ps1 runs
├── KPI 0 — Service Health
│ ├── adfssrv status + uptime → 3 metrics
│ ├── WID database status → 1 metric
│ └── IIS ADFSAppPool status → 1 metric
├── KPI 1 — Certificate Scan
│ ├── ADFS server certs (3 certs) → 9 metrics
│ ├── SSL / HTTPS cert → 3 metrics
│ ├── All RPT certs (139 trusts) → ~270 metrics
│ └── Summary counters → 4 metrics
└── KPI 2 — Account Lockout
└── EXLAdminsvc AD check → 5 metrics
00:05 → Repeats
00:10 → Repeats
...
288 runs/day

Query : max(last_2m):max:adfs.service.is_running{*} by {host} < 1
Alert : < 1
Message : 🔴 adfssrv is DOWN on {{host.name}} — SSO logins will FAIL immediately.

⚠️ Certificate Expiry — Warning / Critical

Section titled “⚠️ Certificate Expiry — Warning / Critical”
Query : min(last_5m):min:adfs.cert.scan.days_remaining{*} by {trust_name,cert_label,expiry_date,host} < 30
Warning : < 30 days
Critical : < 14 days
Message : ⚠️ Cert expiring: {{trust_name.name}} / {{cert_label.name}} — {{value}} days left (exp: {{expiry_date.name}})
Query : max(last_1m):max:adfs.account.is_locked{*} by {account,host} > 0
Alert : > 0
Message : 🔴 Service account {{account.name}} is LOCKED on {{host.name}} — token issuance will fail.
Query : max(last_5m):max:adfs.account.bad_logon_count{*} by {account,host} > 10
Alert : > 10
Message : ⚠️ High bad logon count on {{account.name}} — check for stale credentials in scheduled tasks or services.
Query : max(last_1h):max:adfs.account.password_age_days{*} by {account} > 90
Alert : > 90 days
Message : ⚠️ Service account {{account.name}} password is {{value}} days old — rotation recommended.

Widget Query
ADFS service up/down avg:adfs.service.is_running{*} by {host}
Service uptime (hours) avg:adfs.service.uptime_hours{*} by {host}
Total expired certs avg:adfs.cert.scan.expired_count{*}
Total certs scanned avg:adfs.cert.scan.total_count{*}
Days remaining per cert min:adfs.cert.scan.days_remaining{*} by {trust_name,cert_label}
Expired certs table min:adfs.cert.scan.days_remaining{cert_status:expired} by {trust_name,cert_label,expiry_date}
RPT total count avg:adfs.rpt.total_count{*}
Account locked max:adfs.account.is_locked{*} by {account}
Bad logon count max:adfs.account.bad_logon_count{*} by {account}
Password age (days) max:adfs.account.password_age_days{*} by {account}

Feature Status
ADFS server cert scan (token-signing, token-decrypting, service-comms)
SSL / HTTPS binding cert scan
Full Relying Party Trust cert scan (encryption + request-signing)
Claims Provider Trust cert scan
Auto certificate rollover status
Per-cert tags (trust_name, label, status, thumbprint, expiry_date)
ADFS service uptime via WMI Win32_Process
Windows Internal Database (WID) check
IIS ADFSAppPool check
AD service account lockout detection
Event ID 4740 lockout source tracing
Bad logon count + password age tracking
Dry-run mode (-DryRun)
SYSTEM scheduler compatible
DogStatsD UDP submission
Graceful skip when ADFS / AD unavailable

  • Datadog Agent installed and running
  • DogStatsD listening on 127.0.0.1:8125
  • setup.ps1 run as Administrator
  • Dry-run output validated
  • Live metrics visible in Datadog Metrics Explorer
  • adfs.service.is_running = 1
  • adfs.cert.scan.expired_count value reviewed with team
  • adfs.account.is_locked = 0
  • Scheduled Task ZoosGlobal-ADFS-Monitor created and running
  • Monitor created for service down
  • Monitor created for cert expiry
  • Monitor created for account lockout

Issue Fix
Metrics not appearing in Datadog Run netstat -an | findstr 8125 — verify DogStatsD is listening
[SKIP] Cert scan failed Confirm adfssrv is running and user is ADFS Admin
[SKIP] AD unavailable Install RSAT: Add-WindowsFeature RSAT-AD-PowerShell
ADFSAppPool showing -1 IIS not on this ADFS server — expected for backend nodes
WID showing -1 ADFS is using SQL Server backend — expected
Same cert scanned twice RPT has both singular and plural signing cert properties — both scanned by design
ExecutionPolicy error Run: Set-ExecutionPolicy -Scope LocalMachine RemoteSigned
Scheduled task not running Check: schtasks /query /tn "ZoosGlobal-ADFS-Monitor" /fo LIST /v

Name Shivam Anand
Title Sr. DevOps Engineer | Engineering
Organisation Zoos Global
Email [email protected]
Web www.zoosglobal.com
Address Violena, Pali Hill, Bandra West, Mumbai - 400050

Zoos Global    Datadog Premier Partner



Version 1.0.0 · Last Updated: April 14, 2026

© 2026 Zoos Global · MIT License

Zoos Global is a Datadog Premium Partner