Damien Coles f172d00514 Initial release: Declarative AD Framework v2.1.0
Infrastructure-as-code framework for Active Directory objects and Group Policy.
Sanitized from production deployment for public sharing.
2026-02-19 17:02:42 +00:00

12 KiB

Declarative AD Framework -- Infrastructure as Code

Declarative management of Active Directory objects and Group Policy for Windows Server domains. All configuration is defined in PowerShell data files and applied idempotently via orchestration scripts.

Architecture

Admin Workstation                    Domain Controller
+--------------------------+         +------------------------------+
| Edit definitions         |  git    | Pull, test, apply            |
| Push to remote           | ------> | GPO + AD baseline scripts    |
+--------------------------+         +------------------------------+

Two management domains:

Subsystem Scripts What it manages
AD Objects ad-objects/Apply-ADBaseline.ps1 OUs, security groups, user accounts, delegation ACLs, password policies (PSOs)
Group Policy gpo/Apply-GPOBaseline.ps1 GPOs via 12 modular libraries (see below)
DC Compliance gpo/Apply-DscBaseline.ps1 Validates DC local state matches GPO definitions
AD Hygiene ad-objects/Get-StaleADObjects.ps1 Stale accounts, orphans, unmanaged objects report
GPO Operations Restore-GPOBaseline.ps1, Get-UnmanagedGPOs.ps1 Backup/restore, orphan detection

GPO Capabilities

The framework manages 15 setting types through 12 modular libraries:

Capability Library Description
Security policy GPOPolicy.ps1 GptTmpl.inf: password, lockout, Kerberos, user rights, security options
Registry settings GPOPolicy.ps1 Administrative Template values via Set-GPRegistryValue
Restricted groups GPOPolicy.ps1 Local group membership enforcement
GPO links GPOPermissions.ps1 OU linking with order and enforcement
Security filtering GPOPermissions.ps1 Deny Apply ACEs for group exemptions
Scripts GPOScripts.ps1 Startup/shutdown/logon/logoff script deployment
Advanced audit GPOAudit.ps1 53 subcategory-level audit settings
Preferences GPOPreferences.ps1 10 GPP types (tasks, drives, printers, shortcuts, etc.)
WMI filters GPOWmiFilter.ps1 OS-targeting filters
Backup/restore GPOBackup.ps1 Pre-apply snapshots with rollback
Firewall GPOFirewall.ps1 Rules and profile defaults
AppLocker GPOAppLocker.ps1 Application whitelisting (audit or enforce)
WDAC GPOWdac.ps1 Kernel-level code integrity policy
Folder redirection GPOFolderRedirection.ps1 User folder redirection to network paths

Getting Started

Prerequisites

  • Windows Server 2016+ domain controller
  • RSAT (Remote Server Administration Tools) on admin workstation
  • Windows PowerShell 5.1
  • PowerShell modules: GroupPolicy, ActiveDirectory, SecurityPolicyDsc (for DSC validation)

Customization

  1. Clone the repo and update the definition files for your domain:

    • ad-objects/ous.ps1 -- set $domainDN to your domain's distinguished name, rename OUs
    • ad-objects/groups.ps1 -- define your security groups and members
    • ad-objects/users.ps1 -- define your user accounts
    • ad-objects/delegations.ps1 -- define your OU delegation ACLs
    • ad-objects/password-policies.ps1 -- define fine-grained password policies
    • gpo/*/settings.ps1 -- update LinkTo paths with your OU DNs, update NETBIOS group references in RestrictedGroups
  2. Test first, then apply:

.\ad-objects\Apply-ADBaseline.ps1 -TestOnly    # Drift detection, no changes
.\ad-objects\Apply-ADBaseline.ps1              # Apply AD objects

.\gpo\Apply-GPOBaseline.ps1 -TestOnly         # Drift detection, no changes
.\gpo\Apply-GPOBaseline.ps1 -GpUpdate         # Apply GPO settings + gpupdate

Adding a new GPO

Create a directory under gpo/ with a settings.ps1 -- auto-discovered on next run. No code changes needed.

Example Security Model

The included example definitions demonstrate a tiered admin model:

Tier Account Group Access
Break-glass Administrator Domain Admins Full domain control -- emergency only
Tier 0 (operations) t0admin MasterAdmins Full control on managed OUs, GPO edit, DNS, RDP to DC
Tier 2 (helpdesk) jsmith DelegatedAdmins Password resets, user properties in ExampleUsers only
  • Domain Admins is reserved for break-glass scenarios only
  • MasterAdmins has self-healing edit rights on all managed GPOs (no DA required)
  • DelegatedAdmins are exempted from user desktop lockdown via GPO security filtering
  • Fine-grained password policies (PSOs) enforce stricter requirements for admin tiers

Workflow

Day-to-day operations

1. Edit definitions on your admin workstation
   - AD objects:  ad-objects/ous.ps1, groups.ps1, users.ps1
   - GPO settings: gpo/<gpo-name>/settings.ps1

2. Commit and push
   git add -A && git commit -m "description" && git push origin master

3. RDP to DC
   mstsc /v:dc01.example.internal

4. Pull and test
   cd C:\declarative-ad-framework
   git pull origin master
   .\ad-objects\Apply-ADBaseline.ps1 -TestOnly
   .\gpo\Apply-GPOBaseline.ps1 -TestOnly

5. Review drift output, then apply
   .\ad-objects\Apply-ADBaseline.ps1
   .\gpo\Apply-GPOBaseline.ps1 -GpUpdate

6. Confirm DC compliance
   .\gpo\Apply-DscBaseline.ps1 -TestOnly

Adding a new user

  1. Edit ad-objects/users.ps1 -- add a hashtable with SamAccountName, Name, Path, MemberOf
  2. Push to git, pull on DC
  3. Run .\ad-objects\Apply-ADBaseline.ps1 -- creates the user with a CSPRNG password
  4. Read the password from ad-objects/.credentials/<username>.txt
  5. Securely share the password with the user, then delete the file
  6. User must change password on first login

Adding a new GPO setting

  1. Edit gpo/<gpo-name>/settings.ps1 -- add to SecurityPolicy, RegistrySettings, FirewallRules, AppLockerPolicy, etc.
  2. Push to git, pull on DC
  3. Run .\gpo\Apply-GPOBaseline.ps1 -GpUpdate

Creating a new GPO

  1. Create gpo/<new-name>/settings.ps1 with GPOName, LinkTo, SecurityPolicy, RegistrySettings
  2. Push to git, pull on DC
  3. Run .\gpo\Apply-GPOBaseline.ps1 -GpUpdate -- auto-creates the GPO, applies settings, links to OU

Key Flags

Flag Script Effect
-TestOnly Both Drift detection, no changes (always run first)
-GpUpdate GPO Runs gpupdate /force after applying
-NoBackup GPO Skip automatic pre-apply backup
-NoCleanup GPO Keep stale registry values instead of removing them

Example GPO Inventory

GPO Linked To Purpose
Default Domain Policy Domain root Password, lockout, Kerberos policies
Default Domain Controllers Policy Domain Controllers OU User rights assignments, security options
Admins-01 ExampleAdmins OU Session lock, PS logging, taskbar cleanup
Users-01 ExampleUsers OU Desktop lockdown (DelegatedAdmins exempted)
Workstations-01 ExampleWorkstations OU Audit, autorun, Windows Update, NLA, firewall, AppLocker (audit)
AdminWorkstations-01 ExampleAdminWorkstations OU PAW: full audit, PS transcription, firewall, AppLocker (audit), WDAC (audit)
Servers-01 ExampleServers OU Server hardening: full audit, PS transcription, firewall, GPP local groups

DSC Validation

Apply-DscBaseline.ps1 is a second-layer check that validates the DC's actual local state against what the GPOs should have applied. It catches issues that the GPO baseline can't see -- processing failures, conflicting policies, or settings that were applied out-of-band.

Layer 1 (GPO Baseline):  "Is the policy definition in SYSVOL correct?"
Layer 2 (DSC Baseline):  "Did the DC actually apply it?"

Both DSC configurations read from their respective settings.ps1 files -- single source of truth, no value duplication.

Important: DSC apply mode writes directly to the local security database, bypassing GPO. It requires typing APPLY to confirm and should only be used for emergency remediation.

Bootstrap

The first run of Apply-GPOBaseline.ps1 must be executed as Administrator (Domain Admins) to grant MasterAdmins edit rights on the managed GPOs. After that, MasterAdmins is self-maintaining.

runas /user:EXAMPLE\Administrator "powershell.exe -ExecutionPolicy Bypass -Command cd C:\declarative-ad-framework\gpo; .\Apply-GPOBaseline.ps1 -GpUpdate"

Recovery

If the default GPOs become corrupted beyond repair:

dcgpofix /target:domain    # Reset Default Domain Policy
dcgpofix /target:dc        # Reset Default Domain Controllers Policy

Then re-run Apply-GPOBaseline.ps1 to reapply all settings.

Repo Structure

declarative-ad-framework/
  README.md                        # This file
  CHANGELOG.md                     # Version history
  FRAMEWORK.md                     # Developer reference for extending the framework
  ad-objects/
    Apply-ADBaseline.ps1           # Orchestration: OUs -> groups -> users -> membership -> delegations -> PSOs
    Get-StaleADObjects.ps1         # Read-only: stale accounts, orphans, unmanaged objects
    ous.ps1                        # OU definitions
    groups.ps1                     # Security group definitions
    users.ps1                      # User account definitions (supports optional properties)
    delegations.ps1                # OU delegation rules (ACLs)
    password-policies.ps1          # Fine-grained password policy (PSO) definitions
    lib/
      ADHelper.ps1                 # Loader: dot-sources the 6 modules below
      ADCore.ps1                   # CSPRNG password generation
      ADOrganizationalUnit.ps1     # OU ensure/compare
      ADGroup.ps1                  # Security group ensure/compare
      ADUser.ps1                   # User account ensure/compare
      ADDelegation.ps1             # OU delegation ACLs
      ADPasswordPolicy.ps1         # Fine-grained password policy ensure/compare
    .credentials/                  # Temp password files (gitignored, ACL-locked)
  gpo/
    Apply-GPOBaseline.ps1          # Orchestration: GPO settings to AD
    Apply-DscBaseline.ps1          # DC-local compliance (DSC, test-only)
    Restore-GPOBaseline.ps1        # List/restore GPO backups
    Get-UnmanagedGPOs.ps1          # Discover orphan GPOs not managed by framework
    lib/
      GPOHelper.ps1                # Loader: dot-sources the 12 modules below
      GPOCore.ps1                  # SYSVOL paths, version bump, extension GUIDs, DSC helpers
      GPOPolicy.ps1                # Security policy (GptTmpl.inf) + registry + restricted groups
      GPOPermissions.ps1           # GPO links, management permissions, security filtering
      GPOScripts.ps1               # Startup/shutdown/logon/logoff script deployment
      GPOAudit.ps1                 # Advanced audit policy (audit.csv)
      GPOPreferences.ps1           # Group Policy Preferences XML (10 types)
      GPOWmiFilter.ps1             # WMI filter creation + GPO linking
      GPOBackup.ps1                # Pre-apply backup + restore functions
      GPOFirewall.ps1              # Windows Firewall rules + profile management
      GPOAppLocker.ps1             # AppLocker policy management
      GPOWdac.ps1                  # WDAC policy deployment
      GPOFolderRedirection.ps1     # Folder redirection (fdeploy1.ini)
    default-domain/                # Default Domain Policy + DSC config
    default-domain-controller/     # Default DC Policy + DSC config
    admins-01/                     # Admin session/logging policy
    users-01/                      # User desktop lockdown
    workstations-01/               # Workstation hardening + AppLocker audit
    adminworkstations-01/          # PAW: forensics, AppLocker audit, WDAC audit
    servers-01/                    # Server hardening + GPP local groups
    backups/                       # Pre-apply GPO snapshots (gitignored)
    Output/                        # Compiled MOF files (gitignored)

License

This project is provided as-is for educational and operational use. Adapt the definition files to your environment.