← All Use Cases

Hybrid AD ↔ Entra
Onboarding / Offboarding

A deterministic, role-driven pipeline that onboards and offboards employees across on-prem Active Directory and Microsoft Entra ID — with human checkpoints for the judgment calls, and a complete, honest audit trail.

Automation does the bulk · Humans own the judgment calls · Every step audited

The Problem

Onboarding and offboarding a hybrid employee is slow and error-prone because the steps span two identity systems plus mail, device, and delegation surfaces that are easy to miss.

The most common failure is incomplete access removal on offboarding — a disabled account that still holds group memberships, active sessions, MFA methods, shared-mailbox delegates, or third-party OAuth tokens. On the other side, onboarding is inconsistent: the same role gets a different set of groups depending on who typed the commands, and there is no record to prove it happened.

The fix is a deterministic, role-template-driven flow where AD is the source of truth, the deterministic bulk is automated, the judgment calls are explicit human checkpoints, and every step — including every failure — is written to a timestamped audit log.

The Architecture

On-prem Active Directory is the write path. Azure AD Connect syncs changes to Microsoft Entra ID. Microsoft Graph is used read-only to verify state and drive the audit — never as a second write source, so the two systems never disagree.

WRITE   AD account + group membership ──(WinRM, DC)──► on-prem AD
BRIDGE  Azure AD Connect (delta sync) ───────────────► pushes AD → Entra ID
VERIFY  Microsoft Graph (read-only service principal) ► confirm + audit
CONTROL explicit human checkpoints — logged, never auto-approved

Role templates drive assignment. Standard roles (e.g. IT-Engineer) run the full automated flow. Roles that declare elevated access (Domain Admin, jump hosts, financial write) stop at a checkpoint — nothing privileged is auto-assigned.

The Flow — with the Human Checkpoints

Onboarding
flowchart TD
    A[INTAKE<br/>Parse HR PDF] --> B{CHECKPOINT<br/>HR-CONFIRM<br/>HR lead approves summary}
    B --> C[P1: Account Creation<br/>Conflict-check →<br/>Create/reconcile AD account →<br/>Set attributes]
    C --> D[Trigger sync →<br/>Wait for Entra →<br/>License-conflict check]
    D --> E[P2: Access Assignment<br/>Assign role groups<br/>security / functional / mail]
    E --> F[Nested-group resolution]
    F --> G{Role declares<br/>elevated access?}
    G -->|Yes| H{{CHECKPOINT<br/>ELEVATED<br/>Flow stops — nothing<br/>privileged auto-assigned}}
    G -->|No| I[P3: Verify & Notify<br/>Verify AD + Entra →<br/>Notify hiring manager]
    H -.->|manual approval required| I

    classDef checkpoint fill:#ff9f0a,stroke:#ffc266,stroke-width:2px,color:#241804
    classDef process fill:#13233b,stroke:#2997ff,stroke-width:1.4px,color:#ffffff
    classDef decision fill:#2a2008,stroke:#ffb340,stroke-width:1.4px,color:#ffb340

    class B,H checkpoint
    class A,C,D,E,F,I process
    class G decision
Offboarding
flowchart TD
    A[P1: Immediate Containment<br/>Disable account →<br/>Revoke sessions + OAuth →<br/>Reset password →<br/>Revoke MFA] --> B[Trigger sync]
    B --> C{Intune-managed<br/>device found?}
    C -->|Yes| D{{CHECKPOINT: DEVICE<br/>Flag for manual decision<br/>wipe / unenroll / recover}}
    C -->|No| E[P2: Access Cleanup<br/>Remove from ALL groups →<br/>Move to restricted OU]
    D -.-> E
    E --> F[Delegate check<br/>shared mailbox / SharePoint]
    F --> G{{CHECKPOINT<br/>MANAGER-DATA<br/>Mailbox forwarding &<br/>data-archival decisions}}
    G --> H{{CHECKPOINT<br/>DUAL-SIGNOFF<br/>IT + HR sign-off +<br/>legal-hold gate}}
    H --> I[/Final Deletion<br/>NOT executed in demo —<br/>gated, logged as pending/]

    classDef checkpoint fill:#ff9f0a,stroke:#ffc266,stroke-width:2px,color:#241804
    classDef process fill:#13233b,stroke:#2997ff,stroke-width:1.4px,color:#ffffff
    classDef decision fill:#2a2008,stroke:#ffb340,stroke-width:1.4px,color:#ffb340
    classDef notrun fill:#17171a,stroke:#86868b,stroke-width:1.4px,stroke-dasharray:6 5,color:#86868b

    class D,G,H checkpoint
    class A,B,E,F process
    class C decision
    class I notrun

The design principle: automation does the deterministic bulk, humans own the judgment calls — elevated access, data handling, and destructive deletion. Nothing privileged or irreversible is auto-executed.

Results — Measured, Not Claimed

Both flows were run end-to-end against a real hybrid lab (on-prem AD, Azure AD Connect, Microsoft Entra ID) for a test employee, and every number below was read from the timestamped audit of that run.

7 / 7
Role groups assigned on onboarding (verified in AD)
9
Groups removed on offboarding (incl. nested)
30
Timestamped audit events, offboard run
4
Human checkpoints (offboard) — all logged, none auto-approved

Where the time actually went

A single known lab defect dominates the wall clock: the AD Connect sync-trigger cmdlet hangs (~90 s per run, finding F4). Stripping that one hung call out, the real automation work is small and fast:

OperationMeasuredNote
Onboard — account + 7 groups + Entra verify~37 s95 s wall includes one 90 s sync-trigger hang
Offboard — disable, pw reset, 9 group removals~12 s92 s wall includes one 90 s sync-trigger hang
9-group removal (the critical step)< 1 s / groupvia Set-ADGroup -Remove; the Remove-ADGroupMember cmdlet hung (F2)
Manual baseline — an estimate, clearly labelledA skilled operator doing the same ~20 steps manually across AD + Entra + mail consoles typically takes 30–45 minutes per offboard, with a real risk of missing a group, MFA method, OAuth token, or delegate — and no trace that it happened at all. This baseline is an estimate, not a stopwatch run; the automation's real value is completeness, auditability, and determinism, not raw speed.

The Findings — Where the Platform Drew the Line

These are the non-obvious, verified-in-lab facts that any team building this automation will hit. Reported honestly — not hidden as errors.

FindingWhat happened
UPN suffix is not assumedAn AD account user@company.com synced to Entra as user@tenant.onmicrosoft.com — not the expected domain. All Entra lookups therefore key on onPremisesSamAccountName (reliable), never the guessed UPN.
Group-removal cmdlet hangsRemove-ADGroupMember hung indefinitely in this multi-DC lab, while the delta-attribute path Set-ADGroup -Remove @{Member=…} completed all 9 removals in < 1 s/group. The pipeline uses the working path and a hard per-call timeout as the guard.
Session contaminationA hung WinRM op left the shared WSMan session locked, so every following call returned HTTP 400. Fixed by evicting the session on timeout so the next call opens fresh — after which the group assignments succeeded.
Disabling ≠ revoking OAuthrevokeSignInSessions returned 403 (scope not granted to the service principal). Disabling an account does not by itself invalidate third-party "Sign in with Microsoft" tokens — the scope must be granted and the call made.
Developer-tenant limitsNo Exchange, no Intune, 0 subscribed SKUs, 0 dynamic groups. So mail delivery, shared-mailbox delegates, Intune wipe, and the license-conflict branch could not be exercised — each is logged as a valid negative result, not a silent skip.
The takeawayThe hard part of identity automation is not the happy path — it is the failure modes and the platform's quiet limits: a cmdlet that hangs instead of erroring, a shared session that poisons itself, an OAuth revocation that 403s, and a Developer tenant that can't host the mail/device surfaces you expect. An honest audit surface all of these; a happy-path script hides them.

What Was Not Exercised (Stated Explicitly)

See also: Entra ID CIS Benchmark Audit — v2 → · Event-Driven Azure AD Sync →