In this module
PT1.4 Active Directory Domain Controller Build
You know what Active Directory is. You've probably managed user accounts, group policies, or at least queried AD from PowerShell. This sub builds the domain controller that serves as the AD target for credential access, lateral movement, and privilege escalation techniques in Modules 5, 7, 8, and 9. Every step is shown with commands and expected output — including the parts that take a few minutes and produce long output.
Step 1: Create the VM
Follow the same process as PT1.3 but with these settings:
VirtualBox
New VM wizard:
Name: PT-DC01
ISO Image: Windows Server 2022 Evaluation ISO
Type: Microsoft Windows
Version: Windows 2022 (64-bit)
☑ Skip Unattended Installation
Memory: 2048 MB
Processors: 2
Disk: 30 GB (dynamic)After creation: Settings → Network → Adapter 2 → Enable → Host-only Adapter → select your host-only network.
Hyper-V
New VM wizard:
Name: PT-DC01
Generation: Generation 2
Memory: 2048 MB (Dynamic Memory enabled)
Network: Default Switch
Disk: 30 GB
ISO: Windows Server 2022 EvaluationAfter creation: Settings → Add Hardware → Network Adapter → Virtual Switch: PurpleTeamLab. Under Security, confirm Secure Boot is enabled with the Microsoft UEFI Certificate Authority template.
VMware
ISO: Windows Server 2022 Evaluation
Guest OS: Microsoft Windows → Windows Server 2022
Name: PT-DC01
Disk: 30 GB
Memory: 2048 MB
Processors: 2
Network Adapter 1: NAT
Network Adapter 2: Host-only (add via Customize Hardware)Step 2: Install Windows Server
Start the VM. It boots from the ISO.
- Language, time, keyboard — leave defaults, click Next
- Install now — click it
- Select edition — choose "Windows Server 2022 Standard Evaluation (Desktop Experience)". You want Desktop Experience (the GUI version), not Server Core. Server Core works but makes troubleshooting harder during the course.
- Licence terms — accept, click Next
- Installation type — choose "Custom: Install Windows only (advanced)"
- Disk — select Drive 0 → click Next
Windows Server installs and reboots. You're prompted to set the Administrator password.
- Administrator password — set a strong password you'll remember. This becomes the domain admin password after promotion. You'll need it for domain join in PT1.5 and throughout the course.
You land on the Server Manager dashboard.
Install guest tools (same process as PT1.3 — VirtualBox Guest Additions, or VMware Tools. Hyper-V doesn't need a separate install).
Step 3: Set the static IP and hostname
# Identify the internal adapter (the one without a gateway, same as PT1.3)
Get-NetAdapter | Format-Table Name, Status, InterfaceDescription
# Set the DC's static IP on the internal adapter
New-NetIPAddress -InterfaceAlias "Ethernet 2" -IPAddress 10.0.0.1 -PrefixLength 24
# Point DNS to itself — required BEFORE AD DS promotion
# The DC will be its own DNS server after promotion
Set-DnsClientServerAddress -InterfaceAlias "Ethernet 2" -ServerAddresses 10.0.0.1Verification:
# Confirm IP is set
Get-NetIPAddress -InterfaceAlias "Ethernet 2" | Select-Object IPAddress, PrefixLengthIPAddress PrefixLength
--------- ------------
10.0.0.1 24Rename the server and reboot:
Rename-Computer -NewName "PT-DC01" -RestartLog back in as Administrator after reboot.
Step 4: Install AD DS
# Install the Active Directory Domain Services role
# This installs the role + management tools (RSAT, PowerShell module)
Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementToolsThis takes 2–3 minutes. Expected output:
Success Restart Needed Exit Code Feature Result
------- -------------- --------- --------------
True No Success {Active Directory Domain Services, Gro...If Restart Needed shows Yes, reboot and log back in before continuing.
Step 5: Promote to domain controller
This command creates a new forest and domain. The server becomes the first (and only) domain controller.
# Promote to domain controller — creates the forest and domain
# SafeMode password is used for Directory Services Restore Mode (DSRM) —
# set it to something you'll remember but different from the admin password
Install-ADDSForest `
-DomainName "psyche.yourlab.local" `
-DomainNetbiosName "YOURLAB" `
-ForestMode "WinThreshold" `
-DomainMode "WinThreshold" `
-InstallDns:$true `
-SafeModeAdministratorPassword (ConvertTo-SecureString "LabRecovery2026!" -AsPlainText -Force) `
-Force:$trueThe server installs DNS, configures AD, and reboots automatically. This takes 3–5 minutes. You'll see a series of warnings about DNS delegation and cryptography — these are normal for a lab environment.
After reboot, the login screen shows YOURLAB\Administrator. Log in with the same Administrator password you set during Windows installation.
Verification — confirm the domain is functional:
# Check the domain
Get-ADDomain | Select-Object DNSRoot, NetBIOSName, DomainMode, ForestDNSRoot NetBIOSName DomainMode Forest
------- ----------- ---------- ------
psyche.yourlab.local YOURLAB Windows2016Domain psyche.yourlab.local# Check DNS is resolving the domain
Resolve-DnsName psyche.yourlab.localName Type TTL Section IPAddress
---- ---- --- ------- ---------
psyche.yourlab.local A 600 Answer 10.0.0.1# Check the domain controller is advertising correctly
dcdiag /test:advertising /qIf dcdiag returns no errors, the DC is healthy. If it shows errors about DNS or replication, run dcdiag /test:dns /q to see the specific DNS issue.
Troubleshooting — promotion fails:
The most common failures and fixes:
- "Cannot find the domain controller for this domain" — the DNS on the internal adapter must point to
10.0.0.1(itself) before promotion. RunSet-DnsClientServerAddressagain from Step 3. - "The specified domain name is in use" — you've already promoted this server. Check with
Get-ADDomain. - Reboot loop — if the server reboots repeatedly and never reaches the login screen, wait 5 minutes. The first boot after promotion takes longer as AD initialises.
Step 6: Create test user accounts
The course uses Northgate Engineering personas for scenarios. These lab accounts map to those personas with properties that specific techniques require.
# Create an OU for lab users (keeps them organised, separate from built-in accounts)
New-ADOrganizationalUnit -Name "Lab Users" `
-Path "DC=psyche,DC=yourlab,DC=local" `
-Description "Purple-team lab user accounts"# Standard user — the primary attack target in most technique subs
# This is the user you'll log in as on the endpoint
New-ADUser -Name "Tom Ashworth" `
-SamAccountName "t.ashworth" `
-UserPrincipalName "t.ashworth@psyche.yourlab.local" `
-GivenName "Tom" `
-Surname "Ashworth" `
-Path "OU=Lab Users,DC=psyche,DC=yourlab,DC=local" `
-AccountPassword (ConvertTo-SecureString "Purple2026!" -AsPlainText -Force) `
-Enabled $true `
-PasswordNeverExpires $true `
-ChangePasswordAtLogon $false
# Second standard user — used in lateral movement scenarios
# (attacker compromises t.ashworth and moves laterally to systems where p.sharma has access)
New-ADUser -Name "Priya Sharma" `
-SamAccountName "p.sharma" `
-UserPrincipalName "p.sharma@psyche.yourlab.local" `
-GivenName "Priya" `
-Surname "Sharma" `
-Path "OU=Lab Users,DC=psyche,DC=yourlab,DC=local" `
-AccountPassword (ConvertTo-SecureString "Purple2026!" -AsPlainText -Force) `
-Enabled $true `
-PasswordNeverExpires $true `
-ChangePasswordAtLogon $false
# Domain admin account — used for privilege escalation testing
# (attacker escalates from t.ashworth to admin.lab)
New-ADUser -Name "Admin Lab" `
-SamAccountName "admin.lab" `
-UserPrincipalName "admin.lab@psyche.yourlab.local" `
-Path "OU=Lab Users,DC=psyche,DC=yourlab,DC=local" `
-AccountPassword (ConvertTo-SecureString "AdminPurple2026!" -AsPlainText -Force) `
-Enabled $true `
-PasswordNeverExpires $true `
-ChangePasswordAtLogon $false
Add-ADGroupMember -Identity "Domain Admins" -Members "admin.lab"
# Service account with SPN — the Kerberoasting target (T1558.003)
# Kerberoasting works by requesting a Kerberos service ticket for an account
# that has a Service Principal Name (SPN) set. The ticket is encrypted with
# the account's password hash, which can be cracked offline.
New-ADUser -Name "SVC SQL Service" `
-SamAccountName "svc.sql" `
-UserPrincipalName "svc.sql@psyche.yourlab.local" `
-Path "OU=Lab Users,DC=psyche,DC=yourlab,DC=local" `
-AccountPassword (ConvertTo-SecureString "SQLService2026!" -AsPlainText -Force) `
-Enabled $true `
-PasswordNeverExpires $true `
-ChangePasswordAtLogon $false
# Set the SPN — this is what makes the account Kerberoastable
Set-ADUser -Identity "svc.sql" -ServicePrincipalNames @{Add="MSSQLSvc/sql01.psyche.yourlab.local:1433"}Verification — confirm all accounts exist and have the right properties:
# List all lab users
Get-ADUser -Filter * -SearchBase "OU=Lab Users,DC=psyche,DC=yourlab,DC=local" `
-Properties MemberOf, ServicePrincipalName |
Select-Object Name, SamAccountName, Enabled,
@{N='DomainAdmin';E={($_.MemberOf -match 'Domain Admins').Count -gt 0}},
@{N='SPN';E={$_.ServicePrincipalName -join ', '}} |
Format-TableName SamAccountName Enabled DomainAdmin SPN
---- -------------- ------- ----------- ---
Tom Ashworth t.ashworth True False
Priya Sharma p.sharma True False
Admin Lab admin.lab True True
SVC SQL Service svc.sql True False MSSQLSvc/sql01.psyche.yourlab.local:1433Four accounts: two standard users (attack targets), one domain admin (escalation target), one service account with an SPN (Kerberoasting target). Each one serves a specific purpose in the technique modules.
Step 7: Enable advanced audit policies
The default Windows Server audit policy logs very little. The advanced audit policies produce the Security Event Log entries your AD-focused detection rules match on — logon events (4624, 4625), Kerberos ticket operations (4768, 4769), directory service access, and more.
# Logon/Logoff auditing
auditpol /set /subcategory:"Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Logoff" /success:enable
auditpol /set /subcategory:"Special Logon" /success:enable
# Account Logon auditing (Kerberos, credential validation)
auditpol /set /subcategory:"Credential Validation" /success:enable /failure:enable
auditpol /set /subcategory:"Kerberos Authentication Service" /success:enable /failure:enable
auditpol /set /subcategory:"Kerberos Service Ticket Operations" /success:enable /failure:enable
# Directory Service auditing (for DCSync detection)
auditpol /set /subcategory:"Directory Service Access" /success:enable
auditpol /set /subcategory:"Directory Service Changes" /success:enable
# Process tracking (for remote execution detection)
auditpol /set /subcategory:"Process Creation" /success:enableVerification:
# Confirm the key policies are enabled
auditpol /get /subcategory:"Logon"
auditpol /get /subcategory:"Kerberos Service Ticket Operations"
auditpol /get /subcategory:"Directory Service Access" Logon Success and Failure
Kerberos Service Ticket Operations Success and Failure
Directory Service Access SuccessWhat these produce:
- Event 4624 — successful logon. Fires when t.ashworth logs into the endpoint. Your logon detection rules match this.
- Event 4625 — failed logon. Fires on password spray attempts. Module 7.
- Event 4768 — Kerberos TGT request. Fires on initial authentication. Module 7.
- Event 4769 — Kerberos service ticket request. Fires during Kerberoasting. Module 7.
- Event 4662 — Directory service access. Fires during DCSync. Module 7.
Also enable command-line logging in process creation events (this captures the full command line in Event 4688, which is useful for detection alongside Sysmon):
# Enable command line in process creation events
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" `
/v ProcessCreationIncludeCmdLine_Enabled /t REG_DWORD /d 1 /fStep 8: Snapshot
# Hyper-V
Checkpoint-VM -Name "PT-DC01" -SnapshotName "Clean-AD-Baseline"# VirtualBox
VBoxManage snapshot "PT-DC01" take "Clean-AD-Baseline"VMware: right-click → Snapshot → Take Snapshot → name it Clean-AD-Baseline.
Verification checklist
☐ Windows Server 2022 VM running
☐ Hostname is PT-DC01
☐ Static IP 10.0.0.1 on internal adapter
☐ DNS points to itself (10.0.0.1)
☐ AD DS installed (Get-ADDomain returns psyche.yourlab.local)
☐ DNS resolving domain name (Resolve-DnsName psyche.yourlab.local)
☐ dcdiag /test:advertising passes
☐ OU "Lab Users" created
☐ t.ashworth account exists and is enabled
☐ p.sharma account exists and is enabled
☐ admin.lab account exists and is in Domain Admins
☐ svc.sql account exists with SPN set
☐ Advanced audit policies enabled (Logon, Kerberos, DS Access)
☐ Command-line logging enabled in process creation events
☐ VM snapshot "Clean-AD-Baseline" takenYou've built the lab and understand the validation gap.
Module 0 showed you why detection rules fail silently — vendor schema changes, attacker tool evolution, environment divergence, tuning drift. Module 1 gave you a working four-environment, three-SIEM purple-team lab. From here, you walk the kill chain technique by technique.
- 61 ATT&CK techniques across 12 tactic modules — Initial Access through Impact, each walked end-to-end with attack commands, annotated telemetry, and multi-SIEM detection rules
- Every detection in four formats — Sigma rule (canonical), Sentinel KQL, Defender XDR Advanced Hunting KQL, and Splunk SPL or Elastic. Tabbed side-by-side in every technique sub
- Module 14 Capstone — CHAIN-HARVEST — full purple-team exercise on an AiTM credential-phishing chain. Multi-stage attack, detection results across all three SIEMs, coverage gaps, tuning recommendations
- Programme template — coverage matrix, MTTD per technique, FP rates, detection quality scores, remediation backlog. Populated as you work, presentable to leadership by Module 14
- Public Sigma rule repo — every detection rule in a GitHub repository. Alumni contribute via PR. The artefacts outlive the course
Cancel anytime