← Tech Guides

Active Directory
& IAM

Identity Governance for the Imperial Domain

I

Quick Reference

Essential AD and IAM commands at your fingertips. Copy, paste, conquer.

PowerShell AD Module

Find a User

Get-ADUser -Identity jsmith -Properties *

Retrieve all properties for a specific user by sAMAccountName.

Search Users by Filter

Get-ADUser -Filter {Department -eq "Engineering"} `
  -Properties Department, Title, Mail

Query users matching a department filter with select properties.

List Group Members

Get-ADGroupMember -Identity "Domain Admins" `
  -Recursive | Select Name, SamAccountName

Recursively enumerate all members of a security group.

Find a Computer

Get-ADComputer -Identity "WS-PC042" `
  -Properties OperatingSystem, LastLogonDate

Look up a computer object with OS and last-logon metadata.

Create a New User

New-ADUser -Name "Jane Doe" `
  -SamAccountName jdoe `
  -UserPrincipalName jdoe@corp.contoso.com `
  -Path "OU=Users,DC=corp,DC=contoso,DC=com" `
  -AccountPassword (Read-Host -AsSecureString) `
  -Enabled $true

Provision a new user account in a specific OU with an interactive password prompt.

Modify User Attributes

Set-ADUser -Identity jdoe `
  -Title "Senior Engineer" `
  -Department "Platform" `
  -Manager "CN=John Smith,OU=Users,DC=corp,DC=contoso,DC=com"

Update title, department, and manager for an existing user.

Remove Group Member

Remove-ADGroupMember -Identity "VPN-Users" `
  -Members jdoe -Confirm:$false

Silently remove a user from a security group.

Domain & Forest Info

# Domain details
Get-ADDomain | Select DNSRoot, DomainMode, PDCEmulator

# Forest details
Get-ADForest | Select Name, ForestMode, RootDomain

Quick overview of domain and forest functional levels.

LDAP Queries

User Lookup

ldapsearch -H ldap://dc01.corp.contoso.com \
  -b "DC=corp,DC=contoso,DC=com" \
  -D "CN=svc-ldap,OU=Service,DC=corp,DC=contoso,DC=com" \
  -W "(sAMAccountName=jsmith)" \
  cn mail memberOf

Search for a user by sAMAccountName and return name, email, and group memberships.

Group Membership

ldapsearch -H ldap://dc01.corp.contoso.com \
  -b "DC=corp,DC=contoso,DC=com" \
  -W "(&(objectClass=group)(cn=Domain Admins))" \
  member

List all members of a specific group using an LDAP filter.

Computer Objects

ldapsearch -H ldap://dc01.corp.contoso.com \
  -b "OU=Workstations,DC=corp,DC=contoso,DC=com" \
  "(objectClass=computer)" \
  cn operatingSystem lastLogonTimestamp

Enumerate computer objects within a specific OU with OS details.

Disabled Accounts

ldapsearch -H ldap://dc01.corp.contoso.com \
  -b "DC=corp,DC=contoso,DC=com" \
  "(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))" \
  cn sAMAccountName

Find all disabled user accounts using the UAC bitmask filter.

Diagnostic Commands

DC Health Check

dcdiag /v /c /d /e /s:DC01

Run a comprehensive diagnostic against DC01 with verbose output across all tests.

Replication Status

repadmin /showrepl DC01
repadmin /replsummary

Show inbound replication partners and a site-wide summary of replication health.

DC Locator

nltest /dsgetdc:corp.contoso.com /force
nltest /sc_verify:corp.contoso.com

Force-locate a domain controller and verify the secure channel trust.

Group Policy Results

# Current user/computer policy
gpresult /r

# Force policy refresh
gpupdate /force /boot /logoff

Display applied GPOs and force an immediate policy update cycle.

Azure CLI (Entra ID)

List Users

az ad user list \
  --query "[].{Name:displayName, UPN:userPrincipalName, ID:id}" \
  --output table

Retrieve all Entra ID users in a formatted table with name, UPN, and object ID.

Create a Group

az ad group create \
  --display-name "SG-Platform-Engineers" \
  --mail-nickname "sg-platform-eng" \
  --description "Platform engineering team"

Create a new security group in Entra ID with a display name and description.

List Service Principals

az ad sp list \
  --filter "displayName eq 'MyApp'" \
  --query "[].{Name:displayName, AppId:appId}" \
  --output table

Find service principals (app registrations) by display name.

Assign Role

az role assignment create \
  --assignee jdoe@contoso.com \
  --role "Reader" \
  --scope "/subscriptions/{sub-id}"

Grant the Reader role to a user at the subscription scope.

II

Core Concepts

The foundational pillars of identity and access management, from authentication primitives to the claims that bind them.

Identity vs Authentication vs Authorization

These three concepts form the AAA model (Authentication, Authorization, and Accounting) that underpins every identity system. While often conflated, each serves a distinct purpose in the security lifecycle.

  • Identity — A claim about who you are. An identity is a set of attributes (username, email, employee ID) that uniquely describe an entity within a system. Identities exist before any verification occurs.
  • Authentication (AuthN) — The process of proving that identity claim is valid. This is where credentials enter the picture: passwords, certificates, biometrics, or hardware tokens. Multi-factor authentication (MFA) layers multiple proof types for stronger assurance.
  • Authorization (AuthZ) — Determining what an authenticated identity is allowed to do. Authorization is evaluated after authentication and relies on policies, roles, group memberships, or attribute-based rules.
The AAA Triad

The third "A" is Accounting (also called Auditing). It answers the question: what did this identity actually do? Audit logs, sign-in records, and access reviews all fall under accounting. Without it, authentication and authorization are unverifiable.

Concept Question Answered AD Example Token Field
Identity Who are you? sAMAccountName: jsmith sub (subject)
Authentication Can you prove it? Kerberos TGT via password/smartcard auth_time, amr
Authorization What can you do? Member of Domain Admins roles, groups, scp
Accounting What did you do? Security Event ID 4624 (logon) Audit log correlation ID

Directory Services

A directory service is a specialized database optimized for read-heavy lookups of identity data. Unlike relational databases designed for transactions, directories are hierarchical, schema-driven, and tuned for queries like "find all users in the Engineering department" or "what groups does this computer belong to?"

Active Directory Domain Services (AD DS) is Microsoft's implementation, first shipped with Windows 2000. It stores objects (users, groups, computers, printers) in a hierarchical namespace modeled on the X.500 standard and queried via LDAP (Lightweight Directory Access Protocol).

Why centralized identity matters:

  • Single source of truth — One authoritative store for all identity data eliminates credential sprawl and orphaned accounts.
  • Consistent policy enforcement — Group Policy, conditional access, and security baselines propagate from one place.
  • Reduced attack surface — Centralized credential stores are easier to monitor, rotate, and harden than scattered local accounts.
  • Scalable delegation — OU-based administration lets you grant scoped control without sharing domain-wide privileges.

Security Principals

A security principal is any entity that can be authenticated by the operating system and assigned permissions to resources. In Active Directory, every security principal has a unique Security Identifier (SID) that the system uses internally (never the display name).

Principal Type Description SID Prefix Common Use
User Human or interactive identity S-1-5-21-...-RID Employee login, resource access
Computer Machine account joined to domain S-1-5-21-...-RID GPO application, Kerberos auth
Security Group Collection of principals for ACL assignment S-1-5-21-...-RID File share permissions, app roles
Service Account Identity for background services S-1-5-21-...-RID SQL Server, IIS app pools
gMSA Group Managed Service Account (auto-password rotation) S-1-5-21-...-RID Scheduled tasks, service farm identity
Well-Known SIDs

Some SIDs are universal across every Windows installation. S-1-5-18 is always the Local System account. S-1-5-32-544 is always the local Administrators group. Attackers who compromise these principals gain the highest level of control on that machine.

Claims-Based Identity

Modern identity systems have moved beyond simple username/password verification toward a claims-based model. Instead of each application querying AD directly, an Identity Provider (IdP) issues a cryptographically signed token containing claims — key-value assertions about the subject.

  • Token — A signed data structure (SAML assertion, JWT, Kerberos ticket) that carries claims. The signature proves the IdP vouches for the contents.
  • Claim — A single assertion: email=jdoe@contoso.com, role=admin, department=Engineering. Claims can describe identity, entitlements, or context.
  • Assertion — A collection of claims packaged in a token, along with metadata about when and how the subject was authenticated.
# Decoded JWT claims (simplified)
{
  "sub": "jdoe@contoso.com",
  "name": "Jane Doe",
  "groups": ["Domain Admins", "VPN-Users"],
  "roles": ["GlobalAdmin"],
  "iss": "https://login.microsoftonline.com/{tenant-id}",
  "aud": "https://graph.microsoft.com",
  "iat": 1700000000,
  "exp": 1700003600,
  "amr": ["pwd", "mfa"]
}

The shift to claims-based identity enables federation: an application in one organization can trust tokens issued by another organization's IdP, provided there is a trust relationship. This is the foundation of SSO, SAML, and OpenID Connect.

The CIA Triad in IAM

The CIA triad (Confidentiality, Integrity, Availability) applies directly to identity infrastructure. A breach in any pillar can cascade into full domain compromise.

Pillar IAM Application Threat Example Control
Confidentiality Credentials and tokens must remain secret NTLM hash extraction (Mimikatz) Credential Guard, LAPS, MFA
Integrity Identity data and policies must be tamper-proof AD object modification (DCShadow) AdminSDHolder, signed LDAP, audit logging
Availability Authentication services must remain operational DC denial-of-service, replication failure Multi-DC topology, site redundancy
Identity Is the New Perimeter

In zero-trust architectures, the network boundary is no longer the primary trust boundary. Identity is the perimeter. Every access decision must verify who is requesting, from what device, under what conditions — regardless of network location.

III

AD Architecture

The logical and physical topology of Active Directory — forests, domains, replication, and the FSMO roles that hold it all together.

Forests, Domains, and Trees

Active Directory's logical structure is a hierarchy of forests, trees, and domains. Understanding this hierarchy is essential because it defines the boundaries of trust, replication, and administration.

  • Forest — The outermost security boundary in AD. All domains within a forest share a common schema, configuration partition, and Global Catalog. A forest is named after its first (root) domain. Trust does not automatically extend beyond the forest boundary.
  • Tree — A collection of domains that share a contiguous DNS namespace. For example, corp.contoso.com and us.corp.contoso.com form a tree because one is a child of the other.
  • Domain — The core unit of administration and replication. Each domain has its own set of domain controllers, its own security policy, and its own trust relationships. A domain represents a partition of the directory database.
# View forest topology
Get-ADForest | Select-Object Name, RootDomain, Domains, ForestMode

# Example output:
# Name       : contoso.com
# RootDomain : contoso.com
# Domains    : {contoso.com, corp.contoso.com, eu.contoso.com}
# ForestMode : Windows2016Forest

# View current domain details
Get-ADDomain | Select-Object DNSRoot, NetBIOSName, DomainMode, ParentDomain

# Example output:
# DNSRoot      : corp.contoso.com
# NetBIOSName  : CORP
# DomainMode   : Windows2016Domain
# ParentDomain : contoso.com
Trust Relationships

Within a forest, all domains trust each other via automatic transitive, two-way trusts. Cross-forest trusts must be created manually and can be one-way or two-way. The forest is the ultimate trust boundary — schema changes in one forest never propagate to another.

Organizational Units (OUs)

Organizational Units are containers within a domain that let you organize objects (users, computers, groups) into logical hierarchies. Unlike domains, OUs do not create security boundaries — they exist for administrative delegation and Group Policy scoping.

Key design principles for OU structure:

  • Delegation — Assign granular permissions at the OU level so helpdesk staff can reset passwords in OU=Users without touching OU=Servers.
  • Group Policy linkage — GPOs can be linked to OUs, applying specific configurations only to the objects within. Nest OUs to create inherited policy chains.
  • Flat over deep — Avoid nesting beyond 3-4 levels. Deep OU trees complicate GPO inheritance, delegation audits, and LDAP query performance.
  • Separate users and computers — User and computer policies differ fundamentally. Keeping them in parallel OU branches makes policy targeting cleaner.
# List top-level OUs in the current domain
Get-ADOrganizationalUnit -Filter * -SearchScope OneLevel |
  Select-Object Name, DistinguishedName

# Create a new OU with accidental-deletion protection
New-ADOrganizationalUnit -Name "Service Accounts" `
  -Path "DC=corp,DC=contoso,DC=com" `
  -ProtectedFromAccidentalDeletion $true

# Delegate password-reset rights on an OU
dsacls "OU=Users,DC=corp,DC=contoso,DC=com" /G "CORP\Helpdesk:CA;Reset Password;user"

Domain Controllers

A Domain Controller (DC) is a server that hosts a writable (or read-only) copy of the AD database (ntds.dit), responds to authentication requests, and replicates changes with its peers. Active Directory uses a multi-master replication model: any DC can accept writes, and changes propagate to all other DCs in the domain.

  • Multi-master replication — Unlike single-master databases, every DC can process writes simultaneously. Conflict resolution uses update sequence numbers (USNs) and timestamps. The "last writer wins" for attribute-level conflicts.
  • RODC — A Read-Only Domain Controller stores a non-writable copy of the database. Used in branch offices where physical security is weaker. RODCs never replicate outbound and cache only specifically allowed credentials.
  • Placement strategy — Deploy at least two DCs per domain for redundancy. Place DCs geographically close to users and application servers to minimize authentication latency.
Protect Your DCs

Domain Controllers are Tier 0 assets. Compromise of a single DC means compromise of the entire domain. DCs should run on dedicated hardware (or isolated VMs), have restricted admin access, and never run non-AD workloads. Treat them like crown jewels.

FSMO Roles

While AD is multi-master, five operations require a single authoritative DC to avoid conflicts. These are the Flexible Single Master Operations (FSMO) roles. Two are forest-wide; three exist per domain.

Role Scope Purpose Recovery Priority
Schema Master Forest Controls all schema modifications (adding attributes, classes). Only one DC in the entire forest can write to the schema partition. Low — Schema changes are rare
Domain Naming Master Forest Authorizes adding or removing domains from the forest. Ensures domain name uniqueness across the forest. Low — Domain additions are rare
RID Master Domain Allocates pools of Relative IDs (RIDs) to each DC. RIDs are combined with the domain SID to create unique SIDs for new objects. Medium — DC runs out of RIDs if pool exhausted
PDC Emulator Domain Processes password changes, account lockouts, time sync (NTP root), and is the default target for Group Policy edits. Critical — Immediate user impact
Infrastructure Master Domain Updates cross-domain object references (e.g., when a group in Domain A references a user in Domain B). Not needed if all DCs are Global Catalogs. Low — Impact only in multi-domain forests
# Find all FSMO role holders
netdom query fsmo

# PowerShell equivalent
Get-ADForest | Select SchemaMaster, DomainNamingMaster
Get-ADDomain | Select RIDMaster, PDCEmulator, InfrastructureMaster

# Transfer a role (graceful move to another DC)
Move-ADDirectoryServerOperationMasterRole `
  -Identity "DC02" `
  -OperationMasterRole PDCEmulator
Seize vs Transfer

Always transfer FSMO roles when the current holder is online and reachable. Only seize a role (using ntdsutil) when the current holder is permanently offline. A seized role holder must never be brought back online — doing so creates duplicate role holders and potential data corruption.

Sites and Replication

AD sites represent the physical network topology. They control how clients locate nearby DCs and how replication traffic flows between locations. A site is essentially a collection of IP subnets with well-connected (high-bandwidth, low-latency) network links.

  • Intrasite replication — Between DCs in the same site. Uses change notification (near-instant, within ~15 seconds). Uncompressed for speed.
  • Intersite replication — Between DCs in different sites. Scheduled (default: every 180 minutes). Compressed to conserve WAN bandwidth. Managed via site link objects.
  • KCC (Knowledge Consistency Checker) — An automatic process running on every DC that calculates the optimal replication topology. It creates connection objects to ensure every DC can reach every other DC within a maximum of three hops.
# List all AD sites
Get-ADReplicationSite -Filter *

# List site links and their replication schedules
Get-ADReplicationSiteLink -Filter * |
  Select Name, Cost, ReplicationFrequencyInMinutes, SitesIncluded

# Check replication status across all DCs
repadmin /replsummary

# Force replication between two DCs
repadmin /syncall DC01 /d /e /P

Global Catalog

The Global Catalog (GC) is a distributed data repository that contains a searchable, partial representation of every object in every domain within the forest. While a regular DC holds the full attribute set for objects in its own domain, a GC server additionally holds a subset of attributes for objects in all domains.

  • Ports — GC queries use LDAP port 3268 (unencrypted) or 3269 (LDAPS/TLS). Standard LDAP uses ports 389/636.
  • Universal Group Membership — During logon, the DC contacts a GC to enumerate the user's universal group memberships. Without a reachable GC, logon can fail (unless universal group caching is enabled).
  • Cross-domain searches — Applications like Exchange and SharePoint rely on the GC to search for recipients and users across the entire forest without querying each domain individually.
  • Recommendation — Make every DC a Global Catalog server unless you have a specific reason not to (such as the Infrastructure Master placement constraint in multi-domain forests).
# Check which DCs are Global Catalog servers
Get-ADDomainController -Filter {IsGlobalCatalog -eq $true} |
  Select Name, Site, IPv4Address

# Query the Global Catalog for a user across all domains
Get-ADUser -Filter {mail -eq "jdoe@contoso.com"} `
  -Server "corp.contoso.com:3268" `
  -Properties DisplayName, mail, Company
GC Partial Attribute Set

The Global Catalog does not store every attribute. Only attributes marked for GC replication in the schema (the isMemberOfPartialAttributeSet flag) are replicated. You can add custom attributes to the GC via the Active Directory Schema snap-in, but be conservative — every addition increases replication traffic forest-wide.

IV

LDAP & Directory Services

The protocol that speaks to Active Directory — LDAP queries, distinguished names, search filters, and the schema that defines every object.

LDAP Protocol Basics

The Lightweight Directory Access Protocol (LDAP) is the standard protocol for querying and modifying directory services. Active Directory is, at its core, an LDAP-compliant directory. Every object you create, every group membership you check, and every user you authenticate traverses LDAP (or its Kerberos-augmented variants).

LDAP operates over TCP and uses a hierarchical data model. Clients bind (authenticate), then perform operations: search, add, modify, delete, compare. Each operation targets a specific location in the directory tree.

Port Protocol Encryption Purpose
389 LDAP None (or STARTTLS) Standard directory queries within a single domain
636 LDAPS TLS/SSL Encrypted directory queries (certificate required on DC)
3268 GC None (or STARTTLS) Global Catalog queries across all forest domains
3269 GC-SSL TLS/SSL Encrypted Global Catalog queries
Plaintext LDAP Is a Credential Risk

LDAP on port 389 transmits bind credentials (including passwords for simple binds) in cleartext unless STARTTLS is negotiated. Microsoft has been progressively enforcing LDAP channel binding and LDAP signing requirements. Always prefer LDAPS (port 636) or enforce STARTTLS. Unsigned, unencrypted LDAP binds are a prime target for man-in-the-middle credential theft.

Distinguished Names

Every object in LDAP has a globally unique Distinguished Name (DN) that describes its exact position in the directory tree. A DN is constructed by chaining Relative Distinguished Names (RDNs) from the object up to the root of the directory.

# A typical Distinguished Name
CN=John Doe,OU=Sales,OU=Users,DC=corp,DC=contoso,DC=com

# Reading right-to-left:
#   DC=corp,DC=contoso,DC=com  → Domain: corp.contoso.com
#   OU=Users                   → Organizational Unit: Users
#   OU=Sales                   → Nested OU: Sales
#   CN=John Doe                → Common Name: the object itself
Abbreviation Attribute Used For Example
DC Domain Component Domain name segments DC=corp,DC=contoso,DC=com
OU Organizational Unit Container for organizing objects OU=Engineering
CN Common Name Leaf objects (users, groups, computers) CN=Jane Smith
O Organization X.500 organization (rarely used in AD) O=Contoso Ltd
L Locality Geographic location L=Seattle
C Country Two-letter country code C=US

LDAP Search Filters

LDAP filters use a prefix-notation syntax wrapped in parentheses. Filters can be simple attribute matches or complex boolean expressions combining multiple conditions. Mastering filter syntax is essential for efficient directory queries.

Operator Syntax Description Example
Equality = Exact match (sAMAccountName=jdoe)
Approximate ~= Phonetic/fuzzy match (cn~=Jon)
Greater/Equal >= Lexicographic comparison (whenCreated>=20240101000000.0Z)
Less/Equal <= Lexicographic comparison (pwdLastSet<=132500000000000000)
Presence =* Attribute exists (mail=*)
AND & All conditions must match (&(objectClass=user)(department=Sales))
OR | Any condition may match (|(cn=John*)(cn=Jane*))
NOT ! Negate a condition (!(userAccountControl:1.2.840.113556.1.4.803:=2))
# Find all enabled users in the Sales department
(&(objectClass=user)(objectCategory=person)(department=Sales)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))

# Find users whose name starts with "A" or "B"
(&(objectClass=user)(|(cn=A*)(cn=B*)))

# Find computers running Windows Server
(&(objectClass=computer)(operatingSystem=Windows Server*))

ldapsearch Command

The ldapsearch utility is the standard CLI tool for querying LDAP directories from Linux and macOS. It supports simple binds, SASL authentication, TLS, and full filter syntax.

Search for a User

ldapsearch -H ldap://dc01.corp.contoso.com \
  -D "CN=admin,CN=Users,DC=corp,DC=contoso,DC=com" \
  -W -b "DC=corp,DC=contoso,DC=com" \
  "(sAMAccountName=jdoe)" \
  cn mail memberOf

Bind as admin, search the entire domain for user jdoe, return name, email, and groups.

Find Group Members

ldapsearch -H ldaps://dc01.corp.contoso.com \
  -D "CN=svc-ldap,OU=Service,DC=corp,DC=contoso,DC=com" \
  -W -b "DC=corp,DC=contoso,DC=com" \
  "(&(objectClass=group)(cn=VPN-Users))" \
  member

List all members of the VPN-Users group over an encrypted LDAPS connection.

List All Computers

ldapsearch -H ldap://dc01.corp.contoso.com \
  -D "CN=svc-ldap,OU=Service,DC=corp,DC=contoso,DC=com" \
  -W -b "OU=Workstations,DC=corp,DC=contoso,DC=com" \
  "(objectClass=computer)" \
  cn operatingSystem lastLogonTimestamp

Enumerate computers in the Workstations OU with OS and last-logon details.

Search by Attribute

ldapsearch -H ldap://dc01.corp.contoso.com \
  -D "CN=svc-ldap,OU=Service,DC=corp,DC=contoso,DC=com" \
  -W -b "DC=corp,DC=contoso,DC=com" \
  "(&(objectClass=user)(title=*Engineer*))" \
  cn title department mail

Find all users with "Engineer" in their title across the domain.

LDAP Schema

The AD schema defines every object class and attribute that can exist in the directory. Object classes form an inheritance hierarchy rooted at the top class. Understanding this hierarchy helps you write accurate LDAP filters and predict which attributes are available on a given object.

# objectClass inheritance for a user object:
top
  └── person
        └── organizationalPerson
              └── user

# A user object inherits attributes from every class above it:
#   top             → objectClass, cn
#   person          → sn, telephoneNumber, userPassword
#   orgPerson       → title, department, company, manager
#   user            → sAMAccountName, userPrincipalName, memberOf
Attribute Description Example Value Indexed
sAMAccountName Pre-Windows 2000 logon name (NetBIOS) jdoe Yes
userPrincipalName UPN logon format (email-style) jdoe@corp.contoso.com Yes
distinguishedName Full DN path in the directory CN=Jane Doe,OU=Users,DC=corp... Yes
memberOf Groups the object belongs to CN=VPN-Users,OU=Groups,DC=... Yes
objectSid Security Identifier (binary) S-1-5-21-...-1234 Yes
userAccountControl Bitmask of account flags 512 (normal enabled account) No
pwdLastSet Timestamp of last password change 133500000000000000 No
whenCreated Object creation timestamp 20240115143022.0Z No

Securing LDAP

Hardening LDAP communications is a critical part of AD security. Microsoft has been tightening default LDAP security with each Windows Server release, progressively requiring encryption and signing.

  • LDAPS (port 636) — Wraps the entire LDAP session in TLS. Requires a valid server certificate on every DC. The simplest path to encrypted LDAP.
  • LDAP Channel Binding — Ties the LDAP session to the underlying TLS channel, preventing token relay attacks. Set via the LdapEnforceChannelBinding registry value.
  • LDAP Signing — Requires that all LDAP traffic is cryptographically signed (integrity protection). Configure via Group Policy: Domain controller: LDAP server signing requirements.
  • STARTTLS — Upgrades an existing plaintext LDAP connection on port 389 to TLS. An alternative to LDAPS when you cannot use a dedicated TLS port.
# Enforce LDAP signing via Group Policy (on DCs)
# Policy: Computer Configuration → Policies → Windows Settings →
#         Security Settings → Local Policies → Security Options
#         → Domain controller: LDAP server signing requirements = Require signing

# Check current LDAP signing enforcement
Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" `
  -Name "LDAPServerIntegrity"

# Enforce LDAP channel binding (registry)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" `
  -Name "LdapEnforceChannelBinding" -Value 2 -Type DWord
# Value 0 = Never, 1 = When supported, 2 = Always
Audit Before Enforcing

Before setting LDAP signing or channel binding to "Required," enable diagnostic logging (Event ID 2889 for unsigned binds, 3039 for channel binding failures) and audit your environment for legacy applications that still use unsigned simple binds. Enforcing without auditing first will break those applications.

V

Authentication Protocols

From Kerberos tickets to OAuth tokens — the protocols that prove identity and grant access across on-premises and cloud environments.

Kerberos

Kerberos is the primary authentication protocol in Active Directory. It uses symmetric-key cryptography and a trusted third party (the Key Distribution Center, running on every DC) to authenticate users and services without transmitting passwords over the network.

Component Purpose
KDC (Key Distribution Center) Runs on every DC. Contains the AS (Authentication Service) and TGS (Ticket-Granting Service).
TGT (Ticket-Granting Ticket) Issued by the AS after initial authentication. Acts as proof of identity for requesting service tickets. Default lifetime: 10 hours.
Service Ticket Issued by the TGS for access to a specific service. Contains session key encrypted with the service's secret key.
AS-REQ / AS-REP Authentication Service exchange. Client sends credentials; KDC returns a TGT.
TGS-REQ / TGS-REP Ticket-Granting Service exchange. Client presents TGT; KDC returns a service ticket for the target resource.
AP-REQ / AP-REP Application exchange. Client presents service ticket to the target service for access.
KRBTGT The service account whose password encrypts all TGTs in the domain. Compromising this account means forging any ticket (Golden Ticket attack).
# View current Kerberos tickets (Windows)
klist

# View tickets with full details
klist -e

# Purge all cached tickets
klist purge

# Linux: obtain a TGT
kinit jdoe@CORP.CONTOSO.COM

# Linux: list cached tickets
klist -l

# Linux: destroy all cached tickets
kdestroy -A
krb5.conf (Linux Kerberos Configuration)
[libdefaults]
    default_realm = CORP.CONTOSO.COM
    dns_lookup_realm = false
    dns_lookup_kdc = true
    ticket_lifetime = 10h
    renew_lifetime = 7d
    forwardable = true

[realms]
    CORP.CONTOSO.COM = {
        kdc = dc01.corp.contoso.com
        kdc = dc02.corp.contoso.com
        admin_server = dc01.corp.contoso.com
    }

[domain_realm]
    .corp.contoso.com = CORP.CONTOSO.COM
    corp.contoso.com = CORP.CONTOSO.COM

NTLM

NTLM (NT LAN Manager) is the legacy challenge-response authentication protocol that predates Kerberos in Windows environments. While still supported for backward compatibility, NTLM has fundamental security weaknesses and should be eliminated wherever possible.

The NTLM authentication flow works as follows:

  1. Client sends a NEGOTIATE message to the server declaring NTLM support.
  2. Server responds with a CHALLENGE — a random 8-byte nonce.
  3. Client computes a RESPONSE by hashing the user's password with the challenge and sends it back.
  4. Server forwards the challenge-response pair to a DC for verification (or validates locally).
Version Hash Algorithm Security Level Status
NTLMv1 DES-based, 56-bit key Broken Trivially crackable; disable immediately
NTLMv2 HMAC-MD5 with timestamp Weak Better than v1 but still vulnerable to relay attacks
NTLM Relay Attacks

NTLM is vulnerable to relay attacks: an attacker intercepts an NTLM authentication exchange and forwards it to a different server, impersonating the victim. Tools like ntlmrelayx and Responder automate this. Mitigations include EPA (Extended Protection for Authentication), SMB signing, disabling NTLM via Group Policy, and enforcing Kerberos everywhere. Audit NTLM usage with Event IDs 4624 (logon type) and 8004 (NTLM authentication in the domain).

SAML 2.0

Security Assertion Markup Language (SAML) 2.0 is an XML-based framework for exchanging authentication and authorization data between an Identity Provider (IdP) and a Service Provider (SP). It is the dominant protocol for enterprise SSO to web applications.

  • Assertion — An XML document containing statements about the subject (authentication, attributes, authorization decisions).
  • IdP (Identity Provider) — The authority that authenticates users and issues assertions (e.g., AD FS, Entra ID, Okta).
  • SP (Service Provider) — The application that consumes assertions and grants access (e.g., Salesforce, AWS Console).
  • Bindings — How SAML messages are transported: HTTP POST (assertion in form body), HTTP Redirect (assertion in URL query string), or Artifact (reference resolved server-to-server).
SAML Assertion Structure (Simplified)
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
    ID="_abc123" IssueInstant="2024-01-15T14:30:00Z" Version="2.0">
  <saml:Issuer>https://idp.contoso.com</saml:Issuer>
  <ds:Signature>...XML digital signature...</ds:Signature>
  <saml:Subject>
    <saml:NameID Format="emailAddress">jdoe@contoso.com</saml:NameID>
    <saml:SubjectConfirmation Method="bearer">
      <saml:SubjectConfirmationData
        NotOnOrAfter="2024-01-15T14:35:00Z"
        Recipient="https://app.example.com/saml/acs"/>
    </saml:SubjectConfirmation>
  </saml:Subject>
  <saml:Conditions NotBefore="2024-01-15T14:29:00Z"
                   NotOnOrAfter="2024-01-15T14:35:00Z">
    <saml:AudienceRestriction>
      <saml:Audience>https://app.example.com</saml:Audience>
    </saml:AudienceRestriction>
  </saml:Conditions>
  <saml:AttributeStatement>
    <saml:Attribute Name="groups">
      <saml:AttributeValue>Domain Admins</saml:AttributeValue>
    </saml:Attribute>
  </saml:AttributeStatement>
</saml:Assertion>
SAML Validation Checklist

When consuming SAML assertions, always validate: (1) Signature — verify the XML signature against the IdP's public certificate; (2) Issuer — must match the expected IdP entity ID; (3) Audience — must match your SP entity ID; (4) NotBefore / NotOnOrAfter — assertion must be within the valid time window (account for clock skew); (5) InResponseTo — must match the original AuthnRequest ID to prevent replay attacks.

OAuth 2.0

OAuth 2.0 is an authorization framework (not an authentication protocol) that allows applications to obtain limited access to user resources without exposing credentials. It works by issuing access tokens with specific scopes.

Grant Type Use Case Flow
Authorization Code + PKCE Web apps, SPAs, mobile apps User redirected to IdP, receives code, exchanges for token. PKCE prevents code interception.
Client Credentials Service-to-service (daemon apps) App authenticates with its own credentials (client ID + secret or certificate). No user interaction.
Device Code Input-constrained devices (CLI tools, TVs) Device displays a code; user authenticates on a separate device. App polls for the token.
Refresh Token Long-lived sessions without re-authentication Exchange an expired access token for a new one using a refresh token. Scoped to original grant.
Token Request (Client Credentials Grant)
# Request an access token using client credentials
curl -X POST "https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id={app-id}" \
  -d "client_secret={secret}" \
  -d "scope=https://graph.microsoft.com/.default" \
  -d "grant_type=client_credentials"

# Response:
# {
#   "token_type": "Bearer",
#   "expires_in": 3599,
#   "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIs..."
# }

OpenID Connect

OpenID Connect (OIDC) is an identity layer built on top of OAuth 2.0. While OAuth 2.0 handles authorization (access tokens), OIDC adds authentication by introducing the ID token — a JWT that contains claims about the authenticated user.

  • ID Token — A signed JWT issued alongside the access token. Contains standard claims like sub, name, email, iss, aud, and exp.
  • UserInfo Endpoint — An API endpoint that returns claims about the authenticated user when presented with a valid access token. Useful for fetching additional profile data.
  • Discovery — OIDC providers publish their configuration at /.well-known/openid-configuration, including supported grant types, token endpoints, signing keys (JWKS), and supported scopes.
Claim Description Example
sub Subject identifier (unique per user per client) AItOawmwtWwcT0k51BayewNvutrJUqsvl6qs7A4
iss Issuer identifier (the IdP URL) https://login.microsoftonline.com/{tenant}/v2.0
aud Audience (the client application) 6cb04018-a3f5-46a7-b995-940c78f5aef3
name Full display name Jane Doe
email Email address jdoe@contoso.com
preferred_username Human-readable identifier jdoe@contoso.com
groups Security group memberships ["sg-engineers", "sg-vpn"]
tid Tenant ID (Entra ID specific) 72f988bf-86f1-41af-91ab-2d7cd011db47
# Fetch the OIDC discovery document
curl -s "https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration" | jq .

# Key fields returned:
# - authorization_endpoint
# - token_endpoint
# - userinfo_endpoint
# - jwks_uri (public signing keys)
# - scopes_supported: ["openid", "profile", "email", "offline_access"]
# - response_types_supported: ["code", "id_token", "code id_token"]

Protocol Comparison

Choosing the right authentication protocol depends on the environment, transport, and trust model. The following table compares the five major protocols used in Active Directory and cloud IAM.

Protocol Use Case Token Type Transport Best For
Kerberos On-premises domain auth Encrypted tickets TCP/UDP 88 LAN services, file shares, SQL
NTLM Legacy fallback Challenge-response hash Embedded in SMB/HTTP Nothing (deprecate aggressively)
SAML 2.0 Enterprise SSO to web apps XML assertion HTTP POST / Redirect SaaS apps (Salesforce, AWS, ServiceNow)
OAuth 2.0 API authorization Bearer access token (JWT) HTTPS API access, mobile apps, SPAs
OIDC Modern authentication + identity ID token (JWT) + access token HTTPS Cloud-native apps, user sign-in
Choosing a Protocol

For new applications: use OIDC (authentication) and OAuth 2.0 (API authorization). For enterprise SaaS integrations: SAML 2.0 remains dominant. For on-premises Active Directory resources: Kerberos is mandatory and automatic. NTLM should never be the target protocol for new deployments.

VI

Role-Based Access Control

Structuring permissions through roles and groups — from AD group nesting strategies to Azure RBAC scope hierarchies.

RBAC Fundamentals

Role-Based Access Control assigns permissions to roles rather than individual users. Users are then assigned to roles, inheriting all associated permissions. This indirection simplifies large-scale permission management and makes access auditable.

  • Users — The identities (human or service) that need access to resources.
  • Roles — Named collections of permissions that reflect job functions (e.g., "Help Desk Operator", "Database Admin", "Reader").
  • Permissions — Granular actions on specific resources (e.g., "reset password on OU=Users", "read blob in storage account").
  • Principle of Least Privilege — Grant only the minimum permissions required for a role. Overprivileged accounts are the most common path to lateral movement in breaches.
  • Separation of Duties — No single role should have end-to-end control over a critical process. The person who creates an account should not be the same person who approves its elevated access.
Role Explosion

A common RBAC pitfall is role explosion — creating so many fine-grained roles that the model becomes unmanageable. Aim for a balance between granularity and simplicity. If you have more roles than users, your model needs consolidation. Use attribute-based conditions (ABAC) to handle edge cases instead of creating one-off roles.

AD Group Types

Active Directory supports two group types and three group scopes. Choosing the right combination is critical for both security modeling and replication efficiency.

Group Types:

  • Security Groups — Used to assign permissions to resources (ACLs, GPO filtering, application roles). Security groups have a SID and appear in Kerberos tickets.
  • Distribution Groups — Used only for email distribution lists (Exchange). Cannot be used for access control. Have no SID.
Scope Can Contain Can Access Resources In Replicated To
Domain Local DL Users, global groups, universal groups from any domain in the forest; domain local groups from the same domain Same domain only DCs in the same domain
Global G Users and global groups from the same domain only Any domain in the forest (and trusted forests) All DCs in the same domain; GC stores membership
Universal U Users, global groups, and universal groups from any domain in the forest Any domain in the forest All Global Catalog servers (forest-wide)

AGDLP / IGDLP Strategy

The AGDLP (Account → Global → Domain Local → Permission) pattern is Microsoft's recommended group nesting strategy. In multi-forest environments, this extends to IGDLP (Identity → Global → Domain Local → Permission).

# AGDLP Example:
# 1. ACCOUNT: jdoe (user in corp.contoso.com)
#    ↓ member of
# 2. GLOBAL GROUP: GG-Sales-Staff (scope: Global, same domain)
#    ↓ member of
# 3. DOMAIN LOCAL GROUP: DL-FileShare-Sales-Read (scope: Domain Local)
#    ↓ assigned to
# 4. PERMISSION: Read access on \\fs01\Sales$

# Create the Global Group (organize by role)
New-ADGroup -Name "GG-Sales-Staff" `
  -GroupScope Global -GroupCategory Security `
  -Path "OU=Groups,DC=corp,DC=contoso,DC=com"

# Create the Domain Local Group (organize by resource)
New-ADGroup -Name "DL-FileShare-Sales-Read" `
  -GroupScope DomainLocal -GroupCategory Security `
  -Path "OU=Groups,DC=corp,DC=contoso,DC=com"

# Nest Global into Domain Local
Add-ADGroupMember -Identity "DL-FileShare-Sales-Read" `
  -Members "GG-Sales-Staff"

# Add user to the Global Group
Add-ADGroupMember -Identity "GG-Sales-Staff" -Members "jdoe"
Why AGDLP Matters

AGDLP decouples who people are (Global groups organized by role/department) from what they can access (Domain Local groups tied to specific resources). When a new file share is created, you add the appropriate Global groups to a new Domain Local group. When someone changes departments, you move them between Global groups. Neither change affects the other layer.

Delegation of Control

Delegation allows you to grant specific administrative permissions on an OU or container without making someone a Domain Admin. This is the cornerstone of least-privilege administration in Active Directory.

Delegate Password Resets

dsacls "OU=Users,DC=corp,DC=contoso,DC=com" `
  /G "CORP\Helpdesk:CA;Reset Password;user"

Allow the Helpdesk group to reset passwords for all users in the Users OU.

Delegate Account Unlock

dsacls "OU=Users,DC=corp,DC=contoso,DC=com" `
  /G "CORP\Helpdesk:WP;lockoutTime;user"

Allow the Helpdesk group to write the lockoutTime attribute (effectively unlocking accounts).

Delegate Group Management

dsacls "OU=Groups,DC=corp,DC=contoso,DC=com" `
  /G "CORP\GroupAdmins:WP;member;group"

Allow GroupAdmins to modify group membership for all groups in the Groups OU.

Audit Current Delegations

# List all explicit permissions on an OU
dsacls "OU=Users,DC=corp,DC=contoso,DC=com"

# PowerShell equivalent with AD module
(Get-Acl "AD:\OU=Users,DC=corp,DC=contoso,DC=com").Access |
  Where-Object {$_.IsInherited -eq $false} |
  Select IdentityReference, ActiveDirectoryRights,
    ObjectType, InheritanceType

Review all non-inherited (explicit) permissions set on the Users OU.

Fine-Grained Password Policies

By default, a domain has a single password policy applied to all users (set in the Default Domain Policy GPO). Fine-Grained Password Policies (FGPPs) allow you to define different password requirements for different groups — for example, stricter policies for administrators and service accounts.

FGPPs are implemented using Password Settings Objects (PSOs), stored in the CN=Password Settings Container,CN=System,DC=... container. Each PSO has a precedence value; lower numbers take priority when multiple PSOs apply to the same user.

# Create a strict PSO for admin accounts
New-ADFineGrainedPasswordPolicy -Name "PSO-AdminAccounts" `
  -Precedence 10 `
  -MinPasswordLength 16 `
  -PasswordHistoryCount 24 `
  -ComplexityEnabled $true `
  -ReversibleEncryptionEnabled $false `
  -MaxPasswordAge "30.00:00:00" `
  -MinPasswordAge "1.00:00:00" `
  -LockoutThreshold 3 `
  -LockoutDuration "00:30:00" `
  -LockoutObservationWindow "00:30:00"

# Apply the PSO to the Domain Admins group
Add-ADFineGrainedPasswordPolicySubject -Identity "PSO-AdminAccounts" `
  -Subjects "Domain Admins"

# View which PSO applies to a specific user
Get-ADUserResultantPasswordPolicy -Identity jdoe

# List all PSOs and their precedence
Get-ADFineGrainedPasswordPolicy -Filter * |
  Select Name, Precedence, MinPasswordLength, MaxPasswordAge |
  Sort-Object Precedence

Azure RBAC

Azure Role-Based Access Control governs access to Azure resources through a scope hierarchy. Every role assignment consists of three elements: a security principal (who), a role definition (what permissions), and a scope (where).

The Azure scope hierarchy, from broadest to most specific:

  • Management GroupSubscriptionResource GroupResource

Permissions assigned at a higher scope are inherited by all child scopes. A Contributor role at the subscription level grants Contributor access to every resource group and resource within that subscription.

Built-In Role Scope Description
Owner Any Full access to all resources including the right to delegate access to others
Contributor Any Create and manage all resources but cannot grant access to others
Reader Any View all resources but cannot make any changes
User Access Admin Any Manage user access to Azure resources (role assignments only)
# Assign Reader role at subscription scope
az role assignment create \
  --assignee "jdoe@contoso.com" \
  --role "Reader" \
  --scope "/subscriptions/{subscription-id}"

# Assign a custom role at resource group scope
az role assignment create \
  --assignee "sg-platform-eng" \
  --role "Custom-VM-Operator" \
  --scope "/subscriptions/{sub-id}/resourceGroups/rg-production"

# List all role assignments for a user
az role assignment list \
  --assignee "jdoe@contoso.com" \
  --output table

# Create a custom role definition
az role definition create --role-definition '{
  "Name": "Custom-VM-Operator",
  "Description": "Start, stop, and restart virtual machines",
  "Actions": [
    "Microsoft.Compute/virtualMachines/start/action",
    "Microsoft.Compute/virtualMachines/restart/action",
    "Microsoft.Compute/virtualMachines/deallocate/action",
    "Microsoft.Compute/virtualMachines/read"
  ],
  "NotActions": [],
  "AssignableScopes": ["/subscriptions/{subscription-id}"]
}'
Azure RBAC vs Entra ID Roles

Azure RBAC controls access to Azure resources (VMs, storage, networks). Entra ID roles (formerly Azure AD roles) control access to Entra ID features (user management, app registrations, conditional access policies). These are separate role systems. A Global Administrator in Entra ID does not automatically have Owner access to Azure subscriptions unless the "Access management for Azure resources" setting is elevated.

VII

Single Sign-On & Federation

Crossing trust boundaries with tokens and assertions — from SAML and WS-Federation to SCIM provisioning and enterprise SSO architectures.

SSO Architectures

Single Sign-On (SSO) allows users to authenticate once and gain access to multiple applications without re-entering credentials. The implementation varies depending on where the authentication intercept occurs and how tokens are propagated.

Architecture How It Works Strengths Best For
Agent-Based A software agent installed on each application server intercepts requests and validates the user's session against a central policy server Deep integration; per-app policy enforcement Legacy web apps (SiteMinder, Oracle Access Manager)
Reverse Proxy A proxy gateway sits in front of all applications, authenticating users before forwarding requests with injected identity headers No app modification; centralized enforcement point Internal apps behind a gateway (Azure AD App Proxy, F5 APM)
Token-Based The IdP issues a signed token (SAML assertion, JWT, or OIDC id_token) that the application validates independently Stateless; works across network boundaries; cloud-native SaaS apps, modern web/mobile apps, microservices
Kerberos SSO in Active Directory

On-premises Active Directory provides SSO natively via Kerberos. Once a user obtains a Ticket Granting Ticket (TGT) at logon, the OS transparently requests service tickets for each resource accessed. This is why domain-joined users can open file shares and internal web apps without being prompted for credentials — it is SSO through Kerberos delegation.

SAML Federation

The Security Assertion Markup Language (SAML 2.0) is the most widely deployed federation protocol in enterprise environments. It enables cross-domain SSO by establishing trust between an Identity Provider (IdP) and a Service Provider (SP) through signed XML assertions.

Two primary flows exist:

  • SP-Initiated SSO — User visits the SP, gets redirected to the IdP for authentication, then is redirected back with a SAML assertion. This is the most common flow.
  • IdP-Initiated SSO — User logs into the IdP portal first, then clicks an app tile. The IdP sends an unsolicited SAML assertion to the SP. Common in enterprise portals but less secure (susceptible to assertion replay).

Trust is established by exchanging metadata XML files that contain entity IDs, endpoints, and X.509 signing certificates:

<!-- IdP Metadata (simplified) -->
<EntityDescriptor entityID="https://idp.contoso.com/adfs"
  xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
  <IDPSSODescriptor
    protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    <KeyDescriptor use="signing">
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <X509Data>
          <X509Certificate>MIIC8jCC...base64cert...</X509Certificate>
        </X509Data>
      </KeyInfo>
    </KeyDescriptor>
    <SingleSignOnService
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
      Location="https://idp.contoso.com/adfs/ls/" />
    <SingleSignOnService
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
      Location="https://idp.contoso.com/adfs/ls/" />
  </IDPSSODescriptor>
</EntityDescriptor>
SAML Certificate Rotation

SAML trust breaks when signing certificates expire. Always configure secondary certificates on both IdP and SP before the primary expires. Set calendar reminders for certificate expiry dates. In ADFS, use Update-AdfsCertificate -CertificateType Token-Signing to roll certificates with a grace period.

WS-Federation

WS-Federation is a federation protocol from the WS-* family of specifications. While SAML dominates cross-vendor federation, WS-Federation remains the default protocol for Microsoft-stack applications including SharePoint, Dynamics, and older Office 365 integrations.

  • WS-Trust — The underlying token issuance protocol. Clients request Security Token Service (STS) tokens using SOAP messages. Supports both active (SOAP client) and passive (browser redirect) requestors.
  • Passive Federation — Browser-based SSO using HTTP redirects, similar to SAML. The user is redirected to the IdP's WS-Federation endpoint, authenticates, and is redirected back with a signed token.
  • Active Federation — Application code directly calls the STS endpoint via SOAP/WS-Trust to obtain a token programmatically. Used by rich clients and services, not browsers.
# Test WS-Federation metadata endpoint
Invoke-WebRequest `
  "https://adfs.contoso.com/FederationMetadata/2007-06/FederationMetadata.xml" |
  Select-Object StatusCode, ContentType

# Typical WS-Federation sign-in URL structure:
# https://adfs.contoso.com/adfs/ls/
#   ?wa=wsignin1.0
#   &wtrealm=https://app.contoso.com
#   &wctx=rm=0&id=passive&ru=%2f

AD FS (Active Directory Federation Services)

AD FS is Microsoft's on-premises federation server. It acts as an Identity Provider (IdP) that authenticates users against Active Directory and issues SAML tokens, WS-Federation tokens, or OAuth/OIDC tokens to relying party applications.

Key AD FS concepts:

  • Claims Provider Trust — The source of identity (typically Active Directory). AD FS extracts attributes (UPN, email, groups) and converts them into claims.
  • Relying Party Trust (RPT) — Represents an application or service that consumes tokens from AD FS. Each RPT defines the claims rules, token format, and endpoints for that application.
  • Claims Rules — Transform, filter, and pass-through identity attributes. Written in the AD FS claims rule language or configured via the GUI.

List Relying Party Trusts

Get-AdfsRelyingPartyTrust |
  Select Name, Identifier, IssuanceAuthorizationRules |
  Format-List

Show all configured relying parties and their authorization rules.

Add a Relying Party Trust

Add-AdfsRelyingPartyTrust `
  -Name "Contoso Helpdesk" `
  -MetadataUrl "https://helpdesk.contoso.com/saml/metadata" `
  -IssuanceTransformRules '@RuleTemplate = "LdapClaims"
    @RuleName = "Send AD Attributes"
    c:[Type ==
      "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname",
       Issuer == "AD AUTHORITY"]
    => issue(store = "Active Directory",
       types = (
         "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn",
         "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"),
       query = ";userPrincipalName,mail;{0}", param = c.Value);'

Register a new SP using its SAML metadata URL, with claims rules to emit UPN and email.

Test AD FS Health

# Check AD FS service status
Get-AdfsProperties | Select HostName, HttpsPort, CurrentFarmBehavior

# Verify the SSL certificate
Get-AdfsSslCertificate

# Test the federation metadata endpoint
Test-AdfsServerHealth

Verify AD FS is running, its certificate is valid, and health checks pass.

Export/Import Claims Rules

# Export rules from an existing RPT
(Get-AdfsRelyingPartyTrust -Name "Contoso App").IssuanceTransformRules |
  Out-File .\claims-rules.txt

# Import rules to another RPT
$rules = Get-Content .\claims-rules.txt -Raw
Set-AdfsRelyingPartyTrust -TargetName "New App" `
  -IssuanceTransformRules $rules

Back up and replicate claims rule configurations across relying party trusts.

Trust Relationships

Active Directory supports multiple trust types that allow authentication across domain and forest boundaries. Trusts define the direction and transitivity of authentication flow between security domains.

Trust Type Direction Transitivity Use Case
Parent-Child Two-way Transitive Automatically created between parent and child domains in a tree
Tree-Root Two-way Transitive Automatically created between tree roots in the same forest
Forest Trust One-way or Two-way Transitive Cross-forest resource sharing (requires Forest Functional Level 2003+)
External Trust One-way or Two-way Non-transitive Connecting to a specific domain in another forest without full forest trust
Realm Trust One-way or Two-way Transitive or Non-transitive Connecting AD to a non-Windows Kerberos realm (MIT KDC, Linux)
Shortcut Trust One-way or Two-way Transitive Optimizing authentication between two domains in different trees within the same forest
# Verify an existing trust
netdom trust corp.contoso.com /domain:partner.fabrikam.com /verify

# List all trusts for the current domain
Get-ADTrust -Filter *

# Create a new forest trust (run on both sides)
netdom trust corp.contoso.com /domain:partner.fabrikam.com `
  /add /twoway /transitive

# Validate trust with specific credentials
Test-ComputerSecureChannel -Server "dc01.partner.fabrikam.com" -Verbose

# View trust details including SID filtering status
Get-ADTrust -Identity "partner.fabrikam.com" |
  Select Name, Direction, ForestTransitive, SIDFilteringQuarantined,
    SIDFilteringForestAware
SID Filtering & Trust Security

SID Filtering (quarantine) is enabled by default on external trusts and blocks SIDs from the trusted domain that do not belong to that domain's SID authority. Disabling SID filtering (e.g., for SID history migration) creates a serious privilege escalation vector — a compromised admin in the trusted domain could inject a Domain Admins SID into their token. Only disable it temporarily during migrations and re-enable immediately afterward.

SCIM Provisioning

System for Cross-domain Identity Management (SCIM 2.0) is a REST API standard for automating user provisioning and deprovisioning across identity domains. While SAML and OIDC handle authentication, SCIM handles the lifecycle: creating accounts in downstream apps when a user joins, updating attributes when they transfer, and disabling accounts when they leave.

The user lifecycle follows three phases:

  • Join New employee starts → HR system creates identity → SCIM provisions accounts in all connected apps
  • Change Employee transfers departments → HR updates attributes → SCIM patches group memberships and permissions
  • Leave Employee departs → HR marks inactive → SCIM deactivates or deletes accounts across all apps
# SCIM 2.0 Core Endpoints

# Create a user (Joiner)
POST /scim/v2/Users
Content-Type: application/scim+json
{
  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
  "userName": "jdoe@contoso.com",
  "name": { "givenName": "Jane", "familyName": "Doe" },
  "emails": [{ "value": "jdoe@contoso.com", "primary": true }],
  "active": true,
  "groups": []
}

# Update a user (Mover) — change department
PATCH /scim/v2/Users/a1b2c3d4
Content-Type: application/scim+json
{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [{
    "op": "replace",
    "path": "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department",
    "value": "Engineering"
  }]
}

# Deactivate a user (Leaver)
PATCH /scim/v2/Users/a1b2c3d4
Content-Type: application/scim+json
{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [{ "op": "replace", "path": "active", "value": false }]
}

# Delete a user (hard delete — use sparingly)
DELETE /scim/v2/Users/a1b2c3d4
Azure AD SCIM Provisioning

Azure AD (Entra ID) includes a built-in SCIM client for provisioning to SaaS apps. Configure it under Enterprise Applications → Provisioning. You provide the SCIM endpoint URL and a bearer token. Azure AD then syncs users and groups on a 40-minute cycle (or on-demand). Attribute mappings let you transform AD attributes to the target app's schema.

VIII

Azure AD / Entra ID

Microsoft's cloud identity platform — from tenant fundamentals and hybrid sync to Conditional Access, managed identities, and the Graph API.

Cloud Identity Fundamentals

Azure Active Directory (now Microsoft Entra ID) is Microsoft's cloud-based identity and access management service. Unlike on-premises AD, which uses LDAP and Kerberos, Entra ID is built on REST APIs and modern authentication protocols (OAuth 2.0, OIDC, SAML).

The core hierarchy:

  • Tenant — A dedicated instance of Entra ID. Each organization gets one tenant, identified by a unique tenant ID and a *.onmicrosoft.com domain.
  • Directory — The identity store within the tenant containing users, groups, applications, and devices.
  • Subscription — A billing and resource boundary for Azure services. Subscriptions trust a single tenant for authentication.
Aspect On-Premises AD (AD DS) Azure AD / Entra ID
Protocol LDAP, Kerberos, NTLM OAuth 2.0, OpenID Connect, SAML
Auth Method Domain-join, GPO, service tickets Token-based, Conditional Access, MFA
Device Management Group Policy, SCCM Intune, Azure AD Join, compliance policies
Structure Forests, Domains, OUs Flat tenant, no OU hierarchy (use Administrative Units)
Admin Portal ADUC, ADSI Edit, PowerShell Entra admin center, Azure CLI, Graph API, PowerShell

Azure AD Connect

Azure AD Connect (and its successor, Azure AD Connect Cloud Sync) bridges on-premises Active Directory with Entra ID, creating a hybrid identity. Users authenticate with the same credentials across on-prem and cloud resources.

Three authentication methods for hybrid identity:

  • Password Hash Sync (PHS) — A hash of the on-prem password hash is synced to Entra ID. Users authenticate directly against the cloud. Simplest to deploy; enables leaked credential detection.
  • Pass-Through Authentication (PTA) — Authentication requests are forwarded to on-prem agents that validate against AD DS. Passwords never leave the on-prem boundary. Requires agents on domain-joined servers.
  • Federation (AD FS) — All authentication is redirected to on-prem AD FS servers. Maximum control over sign-in experience, but highest complexity and maintenance burden.
# Trigger a delta sync cycle (sync recent changes)
Start-ADSyncSyncCycle -PolicyType Delta

# Trigger a full sync cycle (re-sync everything)
Start-ADSyncSyncCycle -PolicyType Initial

# Check current sync status
Get-ADSyncScheduler

# View sync errors
Get-ADSyncCSObject -ConnectorName "contoso.com" |
  Where-Object {$_.HasSyncError -eq $true} |
  Select DistinguishedName, SyncError

# Review sync rules and their precedence
Get-ADSyncRule | Select Name, Direction, Precedence,
  SourceObjectType, TargetObjectType |
  Sort Precedence | Format-Table
Source of Authority

When Azure AD Connect is active, on-premises AD is the source of authority for synced objects. Changes to synced attributes (displayName, department, manager) must be made on-premises — edits made in the Entra portal will be overwritten on the next sync cycle. Cloud-only attributes (like Conditional Access assignments) are managed exclusively in Entra ID.

Conditional Access

Conditional Access policies are the central policy engine of Entra ID. They evaluate signals (who, where, what device, what app, risk level) and enforce access decisions (allow, block, require MFA, require compliant device) in real time during sign-in.

Every policy has two parts:

  • AssignmentsWhen does this policy apply? Define users/groups, target apps, and conditions (location, device platform, sign-in risk, client app type).
  • Access ControlsWhat happens when the conditions are met? Grant access (with requirements like MFA, compliant device, hybrid Azure AD join) or block access entirely. Session controls can limit download/upload, enforce app restrictions, or set sign-in frequency.

Common policy patterns:

Require MFA from Untrusted Networks

Assignments:
  Users: All users
  Apps: All cloud apps
  Conditions:
    Locations: Exclude — Named: "Corporate Network"

Access Controls:
  Grant: Require multi-factor authentication

Users on corporate IPs skip MFA; all others must complete a second factor.

Block Legacy Authentication

Assignments:
  Users: All users
  Apps: All cloud apps
  Conditions:
    Client apps: Exchange ActiveSync, Other clients

Access Controls:
  Block access

Prevent IMAP, POP3, SMTP AUTH, and older Office clients that cannot support MFA.

Require Compliant Devices

Assignments:
  Users: All users (exclude break-glass accounts)
  Apps: Office 365
  Conditions:
    Device platforms: Windows, iOS, Android

Access Controls:
  Grant: Require device to be marked as compliant

Only Intune-enrolled devices meeting compliance policies can access Office 365.

Risk-Based MFA

Assignments:
  Users: All users
  Apps: All cloud apps
  Conditions:
    Sign-in risk: Medium and above

Access Controls:
  Grant: Require multi-factor authentication

Entra ID Identity Protection triggers MFA when anomalous sign-in behavior is detected.

Break-Glass Accounts

Always exclude at least two emergency access (break-glass) accounts from all Conditional Access policies. These are cloud-only accounts with Global Administrator role, long random passwords, and no MFA requirement. Store credentials in a physical safe. Without them, a misconfigured Conditional Access policy can lock every admin out of the tenant permanently.

App Registrations & Service Principals

In Entra ID, applications have a two-object model that separates the definition of an app from its instantiation in a tenant:

  • App Registration — The global definition of the application (client ID, redirect URIs, API permissions, certificates/secrets). Lives in the home tenant. Think of it as the "class definition."
  • Service Principal — The local instance of an app within a specific tenant. Created automatically when an app is consented to or provisioned. Think of it as the "object instance." Enterprise applications in the Entra portal are service principals.
  • Managed Identity — A special type of service principal whose credentials are managed entirely by Azure. No secrets to rotate.
# Create an app registration
az ad app create --display-name "Contoso Automation" \
  --sign-in-audience "AzureADMyOrg"

# Create a service principal with RBAC role assignment
az ad sp create-for-rbac \
  --name "sp-contoso-automation" \
  --role "Contributor" \
  --scopes "/subscriptions/{subscription-id}/resourceGroups/rg-production"

# List app registrations
az ad app list --display-name "Contoso" --output table

# Add a client secret (rotate before expiry!)
az ad app credential reset \
  --id {app-id} \
  --append \
  --display-name "automation-secret-2025" \
  --years 1

Managed Identities

Managed Identities eliminate the need for developers to manage credentials. Azure automatically provisions and rotates the identity's certificates behind the scenes.

Type Lifecycle Sharing Best For
System-Assigned Tied to the resource; deleted when the resource is deleted One-to-one (cannot be shared) Single-resource workloads (a VM accessing Key Vault, an App Service calling SQL)
User-Assigned Independent resource; persists until explicitly deleted One-to-many (assigned to multiple resources) Shared identity across VMs, Functions, and containers in the same workload
# Enable system-assigned managed identity on a VM
az vm identity assign --name vm-web01 --resource-group rg-production

# Create a user-assigned managed identity
az identity create --name mi-shared-workload --resource-group rg-production

# Assign the user-assigned identity to a VM
az vm identity assign --name vm-web01 --resource-group rg-production \
  --identities mi-shared-workload

# Grant the managed identity access to Key Vault
az keyvault set-policy --name kv-production \
  --object-id $(az vm identity show --name vm-web01 -g rg-production \
    --query principalId -o tsv) \
  --secret-permissions get list
No Secrets to Rotate

Managed identities obtain tokens from the Azure Instance Metadata Service (IMDS) at http://169.254.169.254/metadata/identity/oauth2/token. The credentials never appear in code, config files, or environment variables. This eliminates an entire class of credential-leak vulnerabilities.

Microsoft Graph API

The Microsoft Graph API is the unified REST endpoint for interacting with all Microsoft cloud services, including Entra ID. All identity operations — managing users, groups, applications, and policies — flow through Graph.

# List users in the Engineering department
GET https://graph.microsoft.com/v1.0/users?$filter=department eq 'Engineering'
  &$select=displayName,userPrincipalName,jobTitle
  &$orderby=displayName

# Get a specific user's group memberships
GET https://graph.microsoft.com/v1.0/users/{user-id}/memberOf
  ?$select=displayName,groupTypes

# List all enterprise applications (service principals)
GET https://graph.microsoft.com/v1.0/servicePrincipals
  ?$filter=tags/any(t:t eq 'WindowsAzureActiveDirectoryIntegratedApp')
  &$select=displayName,appId,servicePrincipalType
# Microsoft Graph PowerShell SDK
Install-Module Microsoft.Graph -Scope CurrentUser
Connect-MgGraph -Scopes "User.Read.All", "Group.ReadWrite.All"

# Get all users
Get-MgUser -All -Property DisplayName, UserPrincipalName, Department |
  Format-Table

# Create a new security group
New-MgGroup -DisplayName "SG-Engineering-Leads" `
  -MailEnabled:$false -MailNickname "sg-eng-leads" `
  -SecurityEnabled:$true `
  -Description "Engineering leadership team"

# Add a member to a group
New-MgGroupMember -GroupId {group-id} `
  -DirectoryObjectId {user-id}

# List app registrations with expiring credentials
Get-MgApplication -All | ForEach-Object {
  $app = $_
  $_.PasswordCredentials | Where-Object {
    $_.EndDateTime -lt (Get-Date).AddDays(30)
  } | Select @{N='App';E={$app.DisplayName}},
    @{N='SecretName';E={$_.DisplayName}},
    @{N='Expires';E={$_.EndDateTime}}
} | Where-Object {$_} | Format-Table

B2B & B2C

Entra ID supports two models for external identity scenarios, each designed for a fundamentally different audience:

Aspect B2B (Business-to-Business) B2C (Business-to-Consumer)
Audience Partners, vendors, contractors with their own organizational identity Customers and end users (public-facing)
Identity Source Guest user's home tenant, Google, Microsoft accounts Local accounts, social IdPs (Google, Facebook, Apple), custom OIDC
Tenant Guests appear in your tenant's directory as external users Separate B2C tenant with its own user directory
Customization Limited — uses standard Entra sign-in experience Fully customizable sign-up/sign-in flows and UI branding
Scale Hundreds to thousands of external collaborators Millions of consumer accounts
# Invite a B2B guest user
New-MgInvitation -InvitedUserEmailAddress "partner@fabrikam.com" `
  -InviteRedirectUrl "https://myapp.contoso.com" `
  -SendInvitationMessage:$true

# List all guest users in the tenant
Get-MgUser -Filter "userType eq 'Guest'" -All |
  Select DisplayName, Mail, CreatedDateTime |
  Sort CreatedDateTime -Descending

# Remove stale guest accounts (no sign-in for 90 days)
Get-MgUser -Filter "userType eq 'Guest'" -All `
  -Property DisplayName, SignInActivity |
  Where-Object {
    $_.SignInActivity.LastSignInDateTime -lt (Get-Date).AddDays(-90)
  } | Select DisplayName, @{
    N='LastSignIn'; E={$_.SignInActivity.LastSignInDateTime}
  }
Guest Account Governance

B2B guest users accumulate over time and often retain access long after a collaboration ends. Use Entra ID Access Reviews to periodically require guest sponsors to re-confirm that access is still needed. Configure automatic removal of guests who are denied or not reviewed. Without governance, guest accounts become a significant attack surface.

IX

Group Policy Management

Centralized configuration at scale — GPO processing order, precedence rules, administrative templates, and the commands that make policy visible.

GPO Fundamentals

A Group Policy Object (GPO) is a collection of settings that define what a computer or user environment looks like. GPOs are linked to Active Directory containers — Sites, Domains, and OUs — and are processed by clients during startup (computer policies) and logon (user policies).

Every GPO contains two top-level nodes:

  • Computer Configuration — Settings applied to the machine regardless of who logs in. Processed at startup before the logon screen appears. Examples: audit policies, firewall rules, service configurations, BitLocker settings.
  • User Configuration — Settings applied to the user session regardless of which machine they log into. Processed at logon. Examples: folder redirection, drive mappings, Start menu restrictions, proxy settings.

The LSDOU processing order determines which GPOs apply and in what sequence:

  1. Local Group Policy — Settings in gpedit.msc on the local machine. Lowest precedence; overridden by everything above.
  2. Site-linked GPOs — Applied based on the AD site the computer belongs to. Rarely used in modern environments.
  3. Domain-linked GPOs — Applied to all objects in the domain. The Default Domain Policy lives here (and should contain only password, Kerberos, and account lockout settings).
  4. OU-linked GPOs — Applied to the OU (and child OUs) where the object resides. Highest precedence in normal processing. Most specific wins.
Last Writer Wins

When multiple GPOs configure the same setting, the last GPO processed wins. Since LSDOU processes from broadest to most specific, an OU-level setting overrides a domain-level setting for the same policy. Within a single container, GPOs with a lower link order number are processed last and therefore take precedence.

GPO Precedence & Inheritance

Beyond LSDOU, several mechanisms modify which GPOs actually apply to a given object:

  • Block Inheritance — Set on an OU to prevent GPOs linked at higher levels (domain, parent OUs) from applying to objects in this OU. Use sparingly — it creates exceptions that are hard to troubleshoot.
  • Enforced (No Override) — Set on a GPO link to force its settings to apply even when child OUs block inheritance. Enforced GPOs always win, regardless of LSDOU position.
  • Security Filtering — By default, GPOs apply to "Authenticated Users." You can restrict a GPO to specific security groups by removing Authenticated Users and adding targeted groups to the security filter.
  • WMI Filtering — Evaluate a WMI query on the client before applying the GPO. If the query returns true, the GPO applies. Example: apply a GPO only to laptops, or only to machines with more than 8 GB RAM.
  • Loopback Processing — Normally, user policies come from the OU where the user object resides. Loopback mode (Replace or Merge) applies user policies based on the OU where the computer object resides. Essential for kiosks, terminal servers, and conference room PCs.

Effective precedence from lowest to highest:

  1. Local GPO
  2. Site-linked GPOs
  3. Domain-linked GPOs
  4. Parent OU GPOs
  5. Child OU GPOs (most specific, highest normal precedence)
  6. Enforced GPOs (reverse order — domain-level enforced beats OU-level enforced)
Enforced + Block Inheritance

When an OU has Block Inheritance enabled and a parent GPO is Enforced, Enforced wins. This is by design — Enforced exists specifically to override Block Inheritance. The only way to prevent an Enforced GPO from applying is security filtering or WMI filtering.

Common GPO Settings

These are the GPO settings most frequently configured in enterprise environments:

Setting Category Policy Path Recommended Value
Minimum Password Length Computer → Windows Settings → Security → Account Policies → Password Policy 14+ characters
Password Complexity Same path as above Enabled (3 of 4 character categories)
Account Lockout Threshold Computer → Windows Settings → Security → Account Policies → Account Lockout 5-10 failed attempts
Lockout Duration Same path as above 15-30 minutes
Audit Logon Events Computer → Windows Settings → Security → Advanced Audit → Logon/Logoff Success and Failure
Audit Account Management Computer → Windows Settings → Security → Advanced Audit → Account Management Success and Failure
Software Restriction Computer → Windows Settings → Security → Software Restriction Policies Default deny with path/hash rules for approved software

Administrative Templates

Administrative Templates are registry-based policy definitions stored as ADMX (XML) and ADML (language-specific XML) files. They define the settings you see under Computer Configuration → Administrative Templates and User Configuration → Administrative Templates in the Group Policy editor.

By default, each machine has its own copy of ADMX files. In a domain environment, you should create a Central Store so all administrators see the same template definitions:

# Central Store path (create this folder on a DC, it replicates via SYSVOL)
\\corp.contoso.com\SYSVOL\corp.contoso.com\Policies\PolicyDefinitions\

# Copy ADMX files from a Windows machine to the Central Store
Copy-Item "C:\Windows\PolicyDefinitions\*.admx" `
  "\\corp.contoso.com\SYSVOL\corp.contoso.com\Policies\PolicyDefinitions\"

# Copy language-specific ADML files
Copy-Item "C:\Windows\PolicyDefinitions\en-US\*.adml" `
  "\\corp.contoso.com\SYSVOL\corp.contoso.com\Policies\PolicyDefinitions\en-US\"

# For third-party templates (Chrome, Office, Adobe, etc.):
# Download the vendor's ADMX/ADML files and copy to the Central Store
# Chrome example:
#   chrome.admx → PolicyDefinitions\
#   chrome.adml → PolicyDefinitions\en-US\
Custom ADMX Templates

You can create custom ADMX templates to manage application-specific registry settings through Group Policy. Microsoft provides the ADMX Migrator tool to convert legacy ADM files, and the ADMX schema is well-documented for writing templates from scratch. Custom templates appear in the Group Policy editor alongside built-in settings once placed in the Central Store.

Group Policy Preferences vs Policies

Group Policy contains two fundamentally different mechanisms for configuring settings: Policies (the traditional settings under Administrative Templates) and Preferences (added in Windows Server 2008). They look similar in the editor but behave very differently.

Aspect Group Policy (Policies) Group Policy Preferences
Enforcement Strictly enforced — user cannot change the setting Applied as defaults — user can modify afterward
Registry Location Written to HKLM\Software\Policies or HKCU\Software\Policies Written to the application's normal registry location
Removal Behavior Setting is removed ("tattooing" does not occur) when GPO no longer applies Setting persists ("tattoos" the registry) even after GPO is unlinked
User Override The UI element is grayed out; user cannot change it Setting appears normal; user can change it (until next refresh cycle)
Use Case Security policies, mandatory configurations that must be enforced Default drive mappings, printer installations, environment variables, scheduled tasks
Preferences and Stored Credentials

Group Policy Preferences historically allowed storing credentials (e.g., for scheduled tasks or drive mappings running as a specific user). These credentials were encrypted with a publicly known AES key (published by Microsoft in MS14-025). Never use the "Run as" feature in GP Preferences. The vulnerability was patched to prevent creating new entries, but existing entries with stored passwords may still exist in your SYSVOL. Audit with: findstr /S /I "cpassword" \\corp.contoso.com\SYSVOL\*.xml

GPO Commands

Essential commands for managing, diagnosing, and reporting on Group Policy:

View Resultant Set of Policy

# Console summary of applied GPOs
gpresult /r

# Detailed HTML report (save and open in browser)
gpresult /h C:\Temp\gpo-report.html /f

# Remote machine report
gpresult /s SERVER01 /r /user CORP\jdoe

See which GPOs are applied to the current user and computer, with precedence details.

Force Policy Refresh

# Refresh all policies immediately
gpupdate /force

# Refresh only computer policies
gpupdate /target:computer /force

# Refresh with logoff (for policies requiring it)
gpupdate /force /logoff

# Remote refresh via PowerShell
Invoke-GPUpdate -Computer "SERVER01" -Force -RandomDelayInMinutes 0

Force an immediate policy refresh rather than waiting for the default 90-minute cycle.

Manage GPOs with PowerShell

# List all GPOs in the domain
Get-GPO -All | Select DisplayName, GpoStatus, CreationTime |
  Sort DisplayName

# Create a new GPO
New-GPO -Name "Security-Baseline-Workstations" `
  -Comment "Baseline security settings for domain workstations"

# Link a GPO to an OU
New-GPLink -Name "Security-Baseline-Workstations" `
  -Target "OU=Workstations,DC=corp,DC=contoso,DC=com" `
  -LinkEnabled Yes

# Set GPO link enforcement
Set-GPLink -Name "Security-Baseline-Workstations" `
  -Target "OU=Workstations,DC=corp,DC=contoso,DC=com" `
  -Enforced Yes

Create, link, and enforce GPOs programmatically.

Reporting & Simulation

# Generate HTML report for a specific GPO
Get-GPOReport -Name "Security-Baseline-Workstations" `
  -ReportType HTML -Path C:\Temp\baseline-report.html

# RSoP simulation: what would apply if a user logged
# into a specific computer?
Get-GPResultantSetOfPolicy -ReportType HTML `
  -Path C:\Temp\rsop-simulation.html `
  -User "CORP\jdoe" -Computer "CORP\WS-JDOE01"

# GUI tools for GPO management
# gpmc.msc  — Group Policy Management Console
# rsop.msc  — Resultant Set of Policy snap-in

Generate detailed reports and simulate policy application before deploying changes.

Backup & Restore GPOs

# Backup all GPOs
Backup-GPO -All -Path "C:\GPO-Backups\$(Get-Date -Format yyyy-MM-dd)"

# Backup a specific GPO
Backup-GPO -Name "Security-Baseline-Workstations" `
  -Path "C:\GPO-Backups"

# Restore a GPO from backup
Restore-GPO -Name "Security-Baseline-Workstations" `
  -Path "C:\GPO-Backups\2025-01-15"

# Import settings from one GPO to another
Import-GPO -BackupGpoName "Template-Security" `
  -TargetName "Production-Security" `
  -Path "C:\GPO-Backups"

Always back up GPOs before changes. Backup captures settings, links, and WMI filters.

Troubleshoot GPO Application

# Check Group Policy event log
Get-WinEvent -LogName "Microsoft-Windows-GroupPolicy/Operational" `
  -MaxEvents 50 | Select TimeCreated, Id, Message |
  Format-Table -Wrap

# Verbose GP processing log (enable for debugging)
# Registry: HKLM\Software\Policies\Microsoft\Windows\
#   Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}
# Set: LogLevel = DWORD:3, TraceLevel = DWORD:2

# Check SYSVOL replication health
dcdiag /test:sysvolcheck /test:frsevent /test:frssysvol

When GPOs are not applying, check the operational log and SYSVOL replication status.

X

Identity Governance

The lifecycle of identity from creation to deprovisioning — access reviews, entitlement management, just-in-time privileges, and the compliance frameworks that govern them all.

Identity Lifecycle

Every identity follows the Joiner → Mover → Leaver lifecycle. Each transition carries specific provisioning and deprovisioning actions. Failures at any stage create orphaned accounts, privilege accumulation, or security gaps.

Stage Actions Systems Involved Risk if Missed
Joiner Create AD account, assign to groups based on role, provision mailbox, license cloud apps, issue hardware token or enroll MFA, set initial password with forced change AD DS, Entra ID, Exchange, HR system (Workday, SAP), ITSM (ServiceNow) Employee cannot work on day one; shadow IT usage begins as they find workarounds
Mover Update department/title attributes, recalculate group memberships, revoke old project access, grant new role entitlements, update manager field AD DS, Entra ID, HR system, application-specific RBAC systems Privilege accumulation — user retains old access while gaining new, violating least privilege
Leaver Disable account (do not delete immediately), remove from all groups, revoke OAuth tokens, convert mailbox to shared, transfer OneDrive ownership, archive after retention period, then delete AD DS, Entra ID, Exchange, OneDrive, all SaaS apps, VPN/certificate authorities Orphaned account — active credentials for a departed employee; top vector for insider threat and compliance violations
The Mover Problem

Most organizations handle Joiners and Leavers reasonably well but fail at Movers. When an employee transfers departments, they typically gain new access without losing old access. After several moves, a single user may hold more cumulative privilege than any single role was designed to grant. Automated access reviews and role-based reprovisioning are essential to combat this drift.

Access Reviews

Access reviews (also called access certifications or attestations) are periodic audits where designated reviewers confirm that users still need their current access. Microsoft Entra ID Governance provides built-in access review capabilities.

Key configuration decisions:

  • Reviewer — Direct manager, group owner, application owner, or self-review (least secure)
  • Frequency — Quarterly for standard access, monthly for privileged roles, weekly for Tier 0
  • Scope — Group memberships, application role assignments, access package assignments, Entra directory roles
  • On denial — Remove the user from the group/role, block sign-in, or flag for manual review
  • On no response — Auto-approve (dangerous) or auto-deny (safer, forces engagement)
# Create an access review for a security group using Microsoft Graph
$params = @{
    displayName = "Quarterly Engineering Access Review"
    descriptionForAdmins = "Review members of SG-Engineering-All"
    descriptionForReviewers = "Confirm each member still needs Engineering access"
    scope = @{
        query = "/groups/a1b2c3d4-e5f6-7890-abcd-ef1234567890/transitiveMembers"
        queryType = "MicrosoftGraph"
    }
    reviewers = @(
        @{ query = "/groups/a1b2c3d4-e5f6-7890-abcd-ef1234567890/owners"; queryType = "MicrosoftGraph" }
    )
    settings = @{
        mailNotificationsEnabled  = $true
        reminderNotificationsEnabled = $true
        justificationRequiredOnApproval = $true
        defaultDecisionEnabled    = $true
        defaultDecision           = "Deny"
        instanceDurationInDays    = 14
        recurrence = @{
            pattern = @{ type = "absoluteMonthly"; interval = 3 }
            range   = @{ type = "noEnd"; startDate = "2025-04-01" }
        }
    }
}
New-MgIdentityGovernanceAccessReviewDefinition -BodyParameter $params
# List all active access reviews
Get-MgIdentityGovernanceAccessReviewDefinition |
  Where-Object { $_.Status -eq "InProgress" } |
  Select DisplayName, Status, @{N='Reviewers';E={$_.Reviewers.Count}}

# Get decisions from a completed review
Get-MgIdentityGovernanceAccessReviewDefinitionInstanceDecision `
  -AccessReviewScheduleDefinitionId $reviewId `
  -AccessReviewInstanceId $instanceId |
  Select Principal, Decision, Justification

Entitlement Management

Access packages in Microsoft Entra ID Governance bundle together the resources a user needs for a specific role or project. Instead of manually adding a user to five groups, three apps, and a SharePoint site, you assign them a single access package that grants all of those simultaneously.

Each access package defines:

  • Resources — Groups, applications, SharePoint sites, Entra roles
  • Policies — Who can request, approval chain, expiration, access review schedule
  • Catalog — Logical container grouping related packages (e.g., "Engineering", "Finance")
# Create an access package catalog
$catalog = New-MgEntitlementManagementCatalog -DisplayName "Engineering" `
  -Description "Access packages for the Engineering department" `
  -IsExternallyVisible $false

# Create an access package
$package = New-MgEntitlementManagementAccessPackage `
  -DisplayName "Backend Developer Access" `
  -Description "Standard access for backend engineering roles" `
  -CatalogId $catalog.Id

# Add a group resource to the package
$group = Get-MgGroup -Filter "displayName eq 'SG-Backend-Developers'"
New-MgEntitlementManagementAccessPackageResourceRoleScope `
  -AccessPackageId $package.Id `
  -AccessPackageResourceRole @{
      OriginId   = "Member_$($group.Id)"
      OriginSystem = "AadGroup"
  } `
  -AccessPackageResourceScope @{
      OriginId     = $group.Id
      OriginSystem = "AadGroup"
  }

# Create a request policy (manager approval, 180-day expiration)
New-MgEntitlementManagementAssignmentPolicy `
  -AccessPackageId $package.Id `
  -DisplayName "Manager Approval Policy" `
  -AllowedTargetScope "allMemberUsers" `
  -ExpirationDuration "P180D" `
  -RequestApprovalSettings @{
      IsApprovalRequiredForAdd = $true
      Stages = @(
          @{
              ApprovalStageTimeOutInDays = 7
              PrimaryApprovers = @(@{
                  odataType = "#microsoft.graph.requestorManager"
                  ManagerLevel = 1
              })
          }
      )
  }

Just-In-Time (JIT) Access

Privileged Identity Management (PIM) eliminates standing privileged access by making role assignments eligible rather than active. An eligible user must explicitly activate the role when needed, with a time limit and optional approval workflow.

Concept Description
Eligible Assignment User can activate the role but does not hold it by default. No privileges until activation.
Active Assignment User holds the role permanently (traditional model). PIM aims to minimize these.
Activation User requests to "turn on" an eligible role. May require MFA, justification text, or manager approval.
Duration Activated roles expire automatically (default: 8 hours, configurable 0.5–24 hours).
Approval Optional workflow where a designated approver must approve before activation completes.
# Make a user eligible for Global Administrator (via PIM)
$roleDefinitionId = (Get-MgRoleManagementDirectoryRoleDefinition `
  -Filter "displayName eq 'Global Administrator'").Id
$userId = (Get-MgUser -UserId "admin@contoso.com").Id

New-MgRoleManagementDirectoryRoleEligibilityScheduleRequest `
  -Action "adminAssign" `
  -RoleDefinitionId $roleDefinitionId `
  -PrincipalId $userId `
  -DirectoryScopeId "/" `
  -ScheduleInfo @{
      StartDateTime = (Get-Date)
      Expiration    = @{
          Type     = "afterDuration"
          Duration = "P365D"  # Eligible for 1 year
      }
  } `
  -Justification "Annual eligible assignment for break-glass scenarios"

# Activate an eligible role (self-service)
New-MgRoleManagementDirectoryRoleAssignmentScheduleRequest `
  -Action "selfActivate" `
  -RoleDefinitionId $roleDefinitionId `
  -PrincipalId $userId `
  -DirectoryScopeId "/" `
  -ScheduleInfo @{
      StartDateTime = (Get-Date)
      Expiration    = @{
          Type     = "afterDuration"
          Duration = "PT4H"  # Active for 4 hours
      }
  } `
  -Justification "Investigating sign-in anomaly INC-4821"
PIM for Groups

PIM is not limited to Entra directory roles. You can also make group memberships eligible, including groups that grant access to Azure resources, applications, or on-premises systems via Entra Cloud Sync. This is the recommended approach for extending JIT access to non-directory resources.

Compliance Frameworks

Identity and access management controls map to requirements across every major compliance framework. The table below shows what each framework demands from your IAM implementation.

Framework Scope IAM Requirements Key Controls
SOX Financial reporting Segregation of duties, access reviews for financial systems, audit trails of access changes Quarterly access certifications, privileged access logging, change management for role modifications
HIPAA Protected health information Unique user IDs, emergency access procedures, automatic logoff, audit controls Break-glass accounts with alerts, session timeouts, access logs retained 6 years minimum
GDPR Personal data (EU residents) Data minimization in identity stores, right to erasure, consent-based access, breach notification within 72 hours Attribute-level access controls, automated data subject request workflows, DPO role assignment
PCI-DSS Payment card data Unique IDs for all users, MFA for remote and admin access, password complexity, 90-day review cycles No shared/generic accounts, immediate revocation on termination, service account inventory
NIST 800-53 Federal information systems AC (Access Control) and IA (Identification & Authentication) control families, continuous monitoring, risk-based authentication AC-2 (Account Management), AC-6 (Least Privilege), IA-2 (Multi-Factor), IA-5 (Authenticator Management)

Audit & Reporting

Comprehensive audit logging is the foundation of identity governance. Both on-premises AD and Entra ID generate events that must be collected, correlated, and reviewed.

Critical Windows Security Event IDs:

Event ID Description Why It Matters
4624 Successful logon Baseline for normal authentication patterns; anomalies indicate compromise
4625 Failed logon Brute force and password spray detection; correlate with account lockouts (4740)
4720 User account created Unauthorized account creation is a persistence technique
4726 User account deleted Audit trail for account lifecycle; deletion of evidence by attackers
4728 Member added to global security group Privilege escalation via group membership modification
4732 Member added to local security group Local admin group modifications on endpoints and servers
# Search Unified Audit Log (Exchange Online / Microsoft 365)
Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-7) `
  -EndDate (Get-Date) `
  -Operations "Add member to role.", "Remove member from role." `
  -ResultSize 500 |
  Select-Object CreationDate, UserIds, Operations, AuditData |
  Export-Csv -Path "C:\Audit\role-changes-7d.csv" -NoTypeInformation

# Query Entra ID sign-in logs via Microsoft Graph
Get-MgAuditLogSignIn -Filter "status/errorCode ne 0" `
  -Top 100 -OrderBy "createdDateTime desc" |
  Select UserDisplayName, AppDisplayName, IpAddress,
    @{N='Error';E={$_.Status.ErrorCode}},
    @{N='Reason';E={$_.Status.FailureReason}},
    ConditionalAccessStatus

# Query Entra ID audit logs for directory changes
Get-MgAuditLogDirectoryAudit -Filter "activityDisplayName eq 'Add member to group'" `
  -Top 50 |
  Select ActivityDisplayName, ActivityDateTime,
    @{N='Actor';E={$_.InitiatedBy.User.UserPrincipalName}},
    @{N='Target';E={$_.TargetResources[0].DisplayName}}
XI

Security & Hardening

The adversarial reality of Active Directory — tiered administration, common attack techniques, mitigation strategies, and the tools that expose what defenders must see.

Tiered Administration Model

Microsoft's Enhanced Security Admin Environment (ESAE) defines three tiers that isolate administrative privileges by asset sensitivity. The cardinal rule: credentials from a higher tier must never be exposed on a lower tier. A Tier 0 admin account must never log into a Tier 2 workstation.

Tier Assets Accounts Restrictions
Tier 0 Domain Controllers, AD DS, PKI root CAs, ADFS, Entra Connect, Schema/Enterprise/Domain Admins Dedicated Tier 0 admin accounts (e.g., t0-admin-jsmith), break-glass accounts Logon restricted to Tier 0 PAWs only; no internet access; no email; smart card required; monitored 24/7
Tier 1 Member servers, databases, line-of-business applications, Exchange, SQL, file servers Dedicated Tier 1 admin accounts (e.g., t1-admin-jsmith), service accounts Cannot log into Tier 0 or Tier 2 systems; separate admin workstations; MFA required for all admin sessions
Tier 2 End-user workstations, laptops, printers, mobile devices Helpdesk accounts, desktop support accounts, standard user accounts No server or DC access; local admin via LAPS only; cannot manage Tier 0 or Tier 1 assets
Credential Theft Cascades

If a Tier 0 admin logs into a compromised Tier 2 workstation, their credential hash is cached in memory and extractable via tools like Mimikatz. An attacker who compromises one workstation can then pivot to full domain compromise. This is not theoretical — it is the single most common Active Directory attack path in real-world breaches. Enforce tier isolation with authentication policies and GPO logon restrictions.

Common AD Attacks

Active Directory is the most targeted infrastructure component in enterprise environments. Understanding these attacks is essential for building effective defenses.

Attack How It Works Impact Detection
Pass-the-Hash (PtH) Attacker extracts NTLM password hashes from memory (e.g., via Mimikatz sekurlsa::logonpasswords) and uses them to authenticate without knowing the plaintext password Lateral movement across any system accepting NTLM authentication Event 4624 with Logon Type 3 (Network) from unusual sources; anomalous NTLM traffic patterns
Golden Ticket Attacker compromises the KRBTGT account hash and forges Kerberos TGTs with arbitrary privileges and lifetimes (default: 10 years) Total domain compromise — attacker can impersonate any user including Domain Admin TGTs with abnormally long lifetimes; TGT usage without corresponding AS-REQ; Event 4769 anomalies
Silver Ticket Attacker compromises a service account hash and forges Kerberos service tickets (TGS) for that specific service Unauthorized access to the targeted service (SQL, HTTP, CIFS) without contacting the DC Service ticket usage without corresponding TGS-REQ at the DC; PAC validation failures
Kerberoasting Any authenticated user requests TGS tickets for service accounts with SPNs, then cracks the tickets offline to recover plaintext passwords Service account compromise; often these accounts have elevated privileges Excessive Event 4769 requests for multiple SPNs from a single user; RC4 encryption type requests
DCSync Attacker with Replicating Directory Changes permissions mimics a domain controller and requests password hash replication via MS-DRSR Full credential dump — all user and computer hashes including KRBTGT Event 4662 with replication GUIDs from non-DC sources; DRS RPC traffic from workstations
AS-REP Roasting Targets accounts with "Do not require Kerberos pre-authentication" enabled; attacker requests AS-REP without credentials and cracks the response offline Account compromise for any user with pre-auth disabled Event 4768 with pre-auth type 0; audit accounts with DONT_REQ_PREAUTH flag
Password Spraying Attacker tries a small number of common passwords against a large number of accounts, staying below lockout thresholds Account compromise while evading lockout policies Distributed Event 4625 failures across many accounts with the same error code from few source IPs

Attack Mitigation

Each attack vector has specific countermeasures. Layered defense is essential — no single control stops every technique.

Pass-the-Hash Mitigations

Disable NTLM where possible. Enforce Kerberos-only authentication via GPO (Network security: Restrict NTLM). Deploy Credential Guard on Windows 10/11 and Server 2016+ to isolate LSASS credentials in a virtualization-based security boundary. Implement LAPS (Local Administrator Password Solution) to prevent lateral movement via shared local admin passwords. Remove users from the local Administrators group on workstations.

Golden Ticket & KRBTGT Mitigations

Rotate the KRBTGT password twice in succession (with a 12-hour gap) to invalidate all existing TGTs. Implement a regular rotation schedule (every 180 days at minimum). Monitor for Tier 0 credential exposure. Deploy Microsoft Defender for Identity to detect forged ticket usage. Limit accounts with DCSync-equivalent permissions to Domain Controllers only.

Kerberoasting & AS-REP Roasting Mitigations

Use Group Managed Service Accounts (gMSA) which have 240-character randomly generated passwords that rotate automatically every 30 days. For legacy service accounts, enforce 25+ character passwords and AES-only encryption (disable RC4). Audit accounts with SPNs: Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName. For AS-REP Roasting, audit and remove the DONT_REQ_PREAUTH flag: Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true}.

DCSync Mitigations

Audit and restrict Replicating Directory Changes permissions. By default, only Domain Controllers, Domain Admins, Enterprise Admins, and Administrators have this right. Run: Get-ACL "AD:\DC=corp,DC=contoso,DC=com" | Select-Object -ExpandProperty Access | Where-Object { $_.ObjectType -match "1131f6a[d|c]-9c07-11d1-f79f-00c04fc2dcd2" } to find all principals with replication rights. Alert on any non-DC principal. Deploy Microsoft Defender for Identity for real-time DCSync detection.

Multi-Factor Authentication

MFA is the single most effective control against credential-based attacks. Microsoft reports that MFA blocks 99.9% of automated attacks. Modern MFA in the Microsoft ecosystem centers on three technologies:

  • Microsoft Authenticator — Push notifications with number matching (anti-MFA fatigue), TOTP codes, and passwordless phone sign-in
  • Windows Hello for Business — Biometric or PIN-based authentication using asymmetric key pairs bound to the device TPM. The private key never leaves the device.
  • FIDO2 Security Keys — Hardware authenticators (YubiKey, Feitian) using the WebAuthn standard. Phishing-resistant because the authenticator verifies the origin URL.
# Conditional Access policy: require MFA for all admin roles
$params = @{
    displayName = "Require MFA for Admins"
    state       = "enabled"
    conditions  = @{
        users = @{
            includeRoles = @(
                "62e90394-69f5-4237-9190-012177145e10"  # Global Admin
                "f28a1f94-e132-4e03-8882-49d36ef22f89"  # SharePoint Admin
                "29232cdf-9323-42fd-ade2-1d097af3e4de"  # Exchange Admin
                "fe930be7-5e62-47db-91af-98c3a49a38b1"  # User Admin
            )
        }
        applications = @{ includeApplications = @("All") }
    }
    grantControls = @{
        operator        = "OR"
        builtInControls = @("mfa")
    }
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $params
MFA Fatigue Attacks

Attackers with stolen passwords can bombard users with repeated MFA push notifications until the user approves one out of frustration. Always enable number matching (the user must type a number shown on the login screen into the Authenticator app) and additional context (shows the app name and location). These features are now default in Microsoft Authenticator.

KRBTGT Account

The KRBTGT account is the most critical account in Active Directory. Its password hash is used to encrypt and sign every Kerberos Ticket Granting Ticket (TGT) in the domain. If an attacker obtains this hash, they can forge Golden Tickets and impersonate any user indefinitely.

Double-reset procedure: KRBTGT maintains the current and previous password hashes (to allow in-flight tickets to remain valid). To fully invalidate all existing TGTs:

  1. First reset — Changes the current hash. Tickets encrypted with the old "current" hash still work because it becomes the "previous" hash.
  2. Wait 12–24 hours — Allow all legitimate TGTs to expire and be renewed with the new hash. The maximum TGT lifetime (default 10 hours) plus clock skew must elapse.
  3. Second reset — Now both the "current" and "previous" hashes are new. All old TGTs (including Golden Tickets) are invalidated.
# Check KRBTGT password last set date
Get-ADUser -Identity krbtgt -Properties PasswordLastSet |
  Select-Object Name, PasswordLastSet,
    @{N='DaysSinceReset';E={((Get-Date) - $_.PasswordLastSet).Days}}

# Reset KRBTGT password (run on DC with PDC emulator role)
# WARNING: Plan a maintenance window. Schedule the second reset
# 12-24 hours later.
Set-ADAccountPassword -Identity krbtgt -Reset `
  -NewPassword (ConvertTo-SecureString (
    [System.Web.Security.Membership]::GeneratePassword(64, 16)
  ) -AsPlainText -Force)

# Verify the reset took effect
Get-ADUser -Identity krbtgt -Properties PasswordLastSet |
  Select-Object PasswordLastSet

# Monitor for Kerberos errors after reset
Get-WinEvent -LogName Security -FilterXPath `
  "*[System[(EventID=4769)]]" -MaxEvents 100 |
  Where-Object { $_.Properties[5].Value -eq '0x1f' } |
  Select TimeCreated, @{N='User';E={$_.Properties[0].Value}}
Rotation Schedule

Microsoft recommends resetting the KRBTGT password every 180 days as a minimum. High-security environments should rotate every 90 days. Always test in a lab first, and schedule resets during low-activity windows. Monitor for Kerberos failures (Event 4769 with failure code 0x1f) immediately after each reset.

Security Assessment Tools

These tools provide visibility into AD security posture, attack paths, and configuration weaknesses that manual audits often miss.

BloodHound

# Collect AD data with SharpHound
# (Run from a domain-joined machine as a domain user)
.\SharpHound.exe -c All -d corp.contoso.com --zipfilename ad_audit.zip

# Alternative: BloodHound.py for Linux
bloodhound-python -u jsmith -p 'P@ssw0rd' \
  -d corp.contoso.com -dc dc01.corp.contoso.com \
  -c all --zip

Attack path visualization. Maps relationships between users, groups, computers, and ACLs to find paths to Domain Admin. The single most important offensive/defensive AD tool.

PingCastle

# Run a health check (generates HTML report with risk score)
.\PingCastle.exe --healthcheck --server dc01.corp.contoso.com

# Run specific checks
.\PingCastle.exe --healthcheck --level Full
.\PingCastle.exe --scanner aclcheck
.\PingCastle.exe --scanner antivirus

AD security health scorer. Assigns a risk rating (0–100) across Stale Objects, Privileged Accounts, Trust Relationships, and Anomalies. Ideal for executive-level reporting.

Purple Knight

# Run Purple Knight (interactive GUI)
# Downloads from purple-knight.com (free, no install)
.\PurpleKnight.exe

# Checks include:
# - Account security (KRBTGT age, AdminSDHolder, etc.)
# - AD delegation risks
# - Group Policy security
# - Kerberos configuration
# - OS-level security

Community-driven AD security assessment by Semperis. Tests over 130 indicators of exposure (IOEs) and indicators of compromise (IOCs) against MITRE ATT&CK framework mappings.

ADRecon

# Run full AD reconnaissance (generates Excel report)
.\ADRecon.ps1 -OutputType EXCEL

# Specific modules
.\ADRecon.ps1 -Collect Users,Groups,GPO,DNS
.\ADRecon.ps1 -Collect ACLs -DomainController dc01

# Output includes: Users, Groups, Computers, OUs,
# GPOs, SPNs, LAPS, ACLs, Trusts, DNS records

Comprehensive AD enumeration and reporting. Extracts and correlates data into structured reports covering every major AD object type. Excellent for inventory and baseline audits.

XII

Troubleshooting & Tools

When the domain breaks at 3 AM — diagnostic commands, event log analysis, common failures, and the health check scripts that keep the empire running.

Diagnostic Commands

The essential toolkit for diagnosing Active Directory issues. These commands should be committed to muscle memory for every AD administrator.

Domain Controller Diagnostics

# Comprehensive DC health check (verbose, all tests)
dcdiag /v /c /d /e

# Key individual tests
dcdiag /test:DNS /v           # DNS health
dcdiag /test:Replications     # Replication status
dcdiag /test:FSMOCheck        # FSMO role holder health
dcdiag /test:Services          # Critical AD services
dcdiag /test:KnowsOfRoleHolders  # FSMO awareness
dcdiag /test:Advertising      # DC advertising (SRV records)

# Test a remote DC specifically
dcdiag /s:DC02 /v /c

The single most important AD diagnostic tool. The /e flag tests all DCs in the enterprise; /c runs all tests; /d adds debug output.

Replication Status

# Show replication partners and status for all DCs
repadmin /showrepl * /csv | ConvertFrom-Csv |
  Where-Object { $_.'Number of Failures' -gt 0 }

# Summary of replication across the enterprise
repadmin /replsummary

# Force sync all partitions on all DCs
repadmin /syncall /A /d /e /P

# Show replication queue
repadmin /queue

# Check USN (Update Sequence Number) for changes
repadmin /showutdvec DC01 "DC=corp,DC=contoso,DC=com"

Replication is the lifeblood of multi-DC environments. A failure here causes stale objects, authentication errors, and split-brain scenarios.

DC Locator & Secure Channel

# Find the DC a client is using
nltest /dsgetdc:corp.contoso.com

# Verify secure channel to domain
nltest /sc_verify:corp.contoso.com

# Reset the secure channel (fixes trust issues)
nltest /sc_reset:corp.contoso.com

# List all DCs in the domain
nltest /dclist:corp.contoso.com

# Check trust relationships
nltest /domain_trusts /all_trusts /v

When clients authenticate against the wrong DC or secure channel breaks, these commands diagnose and repair the connection.

Time Synchronization

# Check time source and offset
w32tm /query /status
w32tm /query /source
w32tm /query /peers

# Monitor time offset across DCs
w32tm /monitor /domain:corp.contoso.com

# Force resync with authoritative source
w32tm /resync /rediscover

# Check PDC emulator time config (should be external NTP)
w32tm /query /computer:DC01 /configuration

# Kerberos allows max 5-minute skew by default
# Verify: Default Domain Policy > Kerberos Policy
# > Maximum tolerance for computer clock synchronization

Kerberos requires clocks synchronized within 5 minutes. Time drift is a silent killer — authentication failures appear random until you check w32tm.

Event Log Analysis

Windows Security and Directory Services event logs are the definitive record of what happens in Active Directory. These are the events you must monitor.

Event ID Log Description Severity
4624 Security Successful logon (check Logon Type: 2=Interactive, 3=Network, 7=Unlock, 10=RDP) Info
4625 Security Failed logon (Sub Status reveals cause: 0xC000006A=bad password, 0xC0000234=locked out) Warning
4720 Security User account created Warning
4722 Security User account enabled Info
4726 Security User account deleted Warning
4728 Security Member added to a global security group Warning
4732 Security Member added to a local security group Warning
4756 Security Member added to a universal security group Warning
4768 Security Kerberos TGT requested (AS-REQ) — initial authentication Info
4769 Security Kerberos service ticket requested (TGS-REQ) — monitor for Kerberoasting (many requests from one source) Info
4771 Security Kerberos pre-authentication failed — often indicates password issues or clock skew Warning
4662 Security Directory service object accessed — watch for replication permission usage (DCSync detection) Critical
# Find recent failed logon attempts (last 24 hours)
Get-WinEvent -FilterHashtable @{
    LogName   = 'Security'
    Id        = 4625
    StartTime = (Get-Date).AddHours(-24)
} | Select-Object TimeCreated,
    @{N='User';    E={$_.Properties[5].Value}},
    @{N='Source';  E={$_.Properties[19].Value}},
    @{N='Status';  E={'0x{0:X}' -f $_.Properties[7].Value}},
    @{N='SubStatus';E={'0x{0:X}' -f $_.Properties[9].Value}} |
  Group-Object User | Sort-Object Count -Descending

# Detect potential Kerberoasting (many TGS requests)
Get-WinEvent -FilterHashtable @{
    LogName   = 'Security'
    Id        = 4769
    StartTime = (Get-Date).AddHours(-1)
} | Group-Object @{E={$_.Properties[0].Value}} |
  Where-Object { $_.Count -gt 10 } |
  Select-Object Count, Name

ADSI Edit & LDP

These low-level tools provide direct access to the AD database. They bypass the safety rails of higher-level tools like Active Directory Users and Computers (ADUC).

  • ADSI Edit (adsiedit.msc) — A Microsoft Management Console snap-in that provides raw attribute-level access to every object in AD. You can view and modify attributes that ADUC does not expose, including schema objects, configuration partitions, and system containers.
  • LDP (ldp.exe) — A lightweight LDAP client for binding, searching, comparing, and modifying AD objects. More flexible than ADSI Edit for complex LDAP queries and troubleshooting LDAP connectivity. Also useful for testing LDAP over SSL (port 636) and verifying certificate configurations.
ADSI Edit Safety Warning

ADSI Edit performs no validation on changes. You can corrupt objects, break replication, or render your domain inoperable with a single incorrect modification. There is no undo. Never use ADSI Edit unless you understand exactly which attribute you are modifying and why standard tools cannot accomplish the task. Always make a System State backup before using ADSI Edit on production DCs. Common safe use cases: clearing lockoutTime, modifying servicePrincipalName, viewing msDS-ReplAttributeMetaData.

PowerShell Diagnostic Module

The ActiveDirectory and built-in PowerShell modules provide powerful diagnostic cmdlets that complement dcdiag and repadmin.

Secure Channel Test

# Test the trust relationship with the domain
Test-ComputerSecureChannel -Verbose

# Repair a broken secure channel
Test-ComputerSecureChannel -Repair -Verbose

# Alternative: Reset machine account password
Reset-ComputerMachinePassword -Server DC01 `
  -Credential (Get-Credential)

When a computer falls out of trust with the domain (error "trust relationship failed"), this is the fix.

Replication Diagnostics

# Get replication partner metadata
Get-ADReplicationPartnerMetadata -Target * `
  -Scope Domain |
  Select Server, Partner, LastReplicationSuccess,
    ConsecutiveReplicationFailures |
  Where-Object { $_.ConsecutiveReplicationFailures -gt 0 }

# Get replication failures
Get-ADReplicationFailure -Target * -Scope Domain |
  Select Server, Partner, FirstFailureTime,
    FailureCount, LastError

PowerShell-native replication monitoring. The -Target * parameter queries all DCs in scope.

DNS Diagnostics

# Verify SRV records for DC locator
Resolve-DnsName -Name _ldap._tcp.dc._msdcs.corp.contoso.com `
  -Type SRV

# Check A record for a specific DC
Resolve-DnsName -Name dc01.corp.contoso.com -Type A

# Test DNS resolution from a specific server
Resolve-DnsName -Name corp.contoso.com `
  -Server 10.0.0.1 -DnsOnly

# Verify all critical SRV records exist
@('_ldap._tcp','_kerberos._tcp','_gc._tcp',
  '_kpasswd._tcp') | ForEach-Object {
    Resolve-DnsName "$_.$domain" -Type SRV -ErrorAction SilentlyContinue
} | Select Name, Type, NameTarget, Port

AD is entirely dependent on DNS. If SRV records are missing, clients cannot locate DCs, and authentication fails silently.

FSMO Role Verification

# Query all FSMO role holders
Get-ADForest | Select SchemaMaster, DomainNamingMaster
Get-ADDomain | Select PDCEmulator, RIDMaster,
  InfrastructureMaster

# Verify role holder is responding
$roles = @{
    'Schema Master'        = (Get-ADForest).SchemaMaster
    'Domain Naming Master' = (Get-ADForest).DomainNamingMaster
    'PDC Emulator'         = (Get-ADDomain).PDCEmulator
    'RID Master'           = (Get-ADDomain).RIDMaster
    'Infrastructure Master'= (Get-ADDomain).InfrastructureMaster
}
$roles.GetEnumerator() | ForEach-Object {
    [PSCustomObject]@{
        Role   = $_.Key
        Holder = $_.Value
        Online = (Test-Connection $_.Value -Count 1 -Quiet)
    }
}

FSMO roles must be held by reachable, healthy DCs. If a role holder goes offline, specific operations (RID allocation, password changes, schema updates) will fail.

Common Issues & Fixes

The most frequently encountered Active Directory problems and their resolutions.

Symptom Likely Cause Resolution
Users cannot log in; "trust relationship between this workstation and the primary domain has failed" Computer account password out of sync (machine was offline >30 days, or restored from old snapshot) Test-ComputerSecureChannel -Repair or rejoin the domain: Reset-ComputerMachinePassword -Server DC01
Replication failures; repadmin /replsummary shows errors DNS misconfiguration, network connectivity, lingering objects, or USN rollback Check DNS (dcdiag /test:DNS), verify connectivity between DCs, remove lingering objects: repadmin /removelingeringobjects
Accounts locking out repeatedly with no apparent cause Cached credentials (mapped drives, scheduled tasks, mobile devices, service accounts using old passwords) Use Microsoft Account Lockout Tools (LockoutStatus.exe) to find the source DC, then check Event 4740 for the calling computer name
DNS resolution fails for AD domain names Missing SRV records, DNS zone not AD-integrated, scavenging deleted active records, forwarder issues Run dcdiag /test:DNS /v; re-register SRV records: nltest /dsregdns; restart Netlogon service on DCs
Cross-domain/cross-forest authentication fails Trust broken, DNS conditional forwarder missing, firewall blocking Kerberos/LDAP ports Verify trust: nltest /sc_verify:trustedDomain; check DNS: Resolve-DnsName _ldap._tcp.dc._msdcs.trusted.com -Type SRV; verify ports 88, 389, 636, 445, 3268
Kerberos authentication failures; NTLM fallback Time skew >5 minutes, duplicate SPNs, missing SPNs, or clock not synced to PDC emulator Check time: w32tm /monitor; find duplicate SPNs: setspn -X; verify SPN: setspn -L serviceaccount

Health Check Script

A comprehensive PowerShell script that performs a quick AD health assessment. Run this as a daily scheduled task or before and after maintenance windows.

# AD-HealthCheck.ps1 — Quick Active Directory Health Assessment
# Run on any domain-joined machine with RSAT tools installed

$domain = (Get-ADDomain).DNSRoot
$forest = (Get-ADForest).Name
Write-Host "=== AD Health Check: $domain (Forest: $forest) ===" -ForegroundColor Cyan
Write-Host "Timestamp: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Gray

# 1. DNS Resolution
Write-Host "`n[1/6] DNS Resolution" -ForegroundColor Yellow
$srvRecords = Resolve-DnsName "_ldap._tcp.dc._msdcs.$domain" -Type SRV -ErrorAction SilentlyContinue
if ($srvRecords) {
    Write-Host "  PASS: Found $($srvRecords.Count) LDAP SRV records" -ForegroundColor Green
} else {
    Write-Host "  FAIL: No LDAP SRV records found!" -ForegroundColor Red
}

# 2. DC Connectivity
Write-Host "`n[2/6] Domain Controller Connectivity" -ForegroundColor Yellow
$dcs = Get-ADDomainController -Filter * | Select-Object Name, IPv4Address, IsGlobalCatalog
foreach ($dc in $dcs) {
    $ping = Test-Connection -ComputerName $dc.Name -Count 1 -Quiet
    $status = if ($ping) { "PASS" } else { "FAIL" }
    $color  = if ($ping) { "Green" } else { "Red" }
    $gc     = if ($dc.IsGlobalCatalog) { " [GC]" } else { "" }
    Write-Host "  $status`: $($dc.Name) ($($dc.IPv4Address))$gc" -ForegroundColor $color
}

# 3. FSMO Roles
Write-Host "`n[3/6] FSMO Role Holders" -ForegroundColor Yellow
$fsmo = @{
    'PDC Emulator'  = (Get-ADDomain).PDCEmulator
    'RID Master'    = (Get-ADDomain).RIDMaster
    'Infra Master'  = (Get-ADDomain).InfrastructureMaster
    'Schema Master' = (Get-ADForest).SchemaMaster
    'Naming Master' = (Get-ADForest).DomainNamingMaster
}
$fsmo.GetEnumerator() | ForEach-Object {
    $online = Test-Connection $_.Value -Count 1 -Quiet
    $color  = if ($online) { "Green" } else { "Red" }
    Write-Host "  $($_.Key): $($_.Value) $(if($online){'(Online)'}else{'(OFFLINE!)'})" -ForegroundColor $color
}

# 4. Replication Health
Write-Host "`n[4/6] Replication Status" -ForegroundColor Yellow
$replFailures = Get-ADReplicationFailure -Target * -Scope Domain -ErrorAction SilentlyContinue
if ($replFailures) {
    Write-Host "  WARN: $($replFailures.Count) replication failures detected" -ForegroundColor Red
    $replFailures | Select Server, Partner, FailureCount, FirstFailureTime |
      Format-Table -AutoSize | Out-String | Write-Host
} else {
    Write-Host "  PASS: No replication failures" -ForegroundColor Green
}

# 5. KRBTGT Password Age
Write-Host "`n[5/6] KRBTGT Password Age" -ForegroundColor Yellow
$krbtgt = Get-ADUser -Identity krbtgt -Properties PasswordLastSet
$age = ((Get-Date) - $krbtgt.PasswordLastSet).Days
$color = if ($age -gt 180) { "Red" } elseif ($age -gt 90) { "Yellow" } else { "Green" }
Write-Host "  KRBTGT password last set: $($krbtgt.PasswordLastSet) ($age days ago)" -ForegroundColor $color

# 6. Stale Accounts
Write-Host "`n[6/6] Stale Accounts (inactive >90 days)" -ForegroundColor Yellow
$staleDate = (Get-Date).AddDays(-90)
$staleUsers = (Get-ADUser -Filter {LastLogonDate -lt $staleDate -and Enabled -eq $true} `
  -Properties LastLogonDate).Count
$staleComputers = (Get-ADComputer -Filter {LastLogonDate -lt $staleDate -and Enabled -eq $true} `
  -Properties LastLogonDate).Count
Write-Host "  Stale enabled users: $staleUsers" -ForegroundColor $(if($staleUsers -gt 50){"Yellow"}else{"Green"})
Write-Host "  Stale enabled computers: $staleComputers" -ForegroundColor $(if($staleComputers -gt 20){"Yellow"}else{"Green"})

Write-Host "`n=== Health Check Complete ===" -ForegroundColor Cyan