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

471 lines
17 KiB
PowerShell

# AdminWorkstations-01 -- Settings Declaration
# Linked to: OU=ExampleAdminWorkstations,DC=example,DC=internal
#
# Privileged Access Workstation (PAW) policy. Inherits the spirit of Workstations-01
# but with stricter logging, tighter lockout, and enhanced forensic capability.
# All settings are Computer Configuration (HKLM).
@{
GPOName = 'AdminWorkstations-01'
Description = 'Privileged Access Workstation (PAW) -- enhanced logging, strict lockout, forensic capability'
DisableUserConfiguration = $true
LinkTo = 'OU=ExampleAdminWorkstations,DC=example,DC=internal'
# Defense-in-depth: only apply to workstation OS (ProductType 1).
# Prevents misapplication if a server object lands in the wrong OU.
WMIFilter = @{
Name = 'Workstations Only'
Description = 'Targets workstation operating systems (ProductType = 1)'
Query = "SELECT * FROM Win32_OperatingSystem WHERE ProductType = 1"
}
# Lock down local Administrators to Domain Admins + MasterAdmins only.
# Any unauthorized additions are removed on next GPO refresh.
RestrictedGroups = @{
'BUILTIN\Administrators' = @{
Members = @('EXAMPLE\Domain Admins', 'EXAMPLE\MasterAdmins')
}
}
SecurityPolicy = @{
'System Access' = [ordered]@{
EnableGuestAccount = 0
}
'Event Audit' = [ordered]@{
# Everything audited -- admin machines need full visibility
AuditSystemEvents = 3 # Success + Failure
AuditLogonEvents = 3 # Success + Failure
AuditObjectAccess = 3 # Success + Failure
AuditPrivilegeUse = 3 # Success + Failure
AuditPolicyChange = 3 # Success + Failure
AuditAccountManage = 3 # Success + Failure
AuditProcessTracking = 1 # Success (track what admins run)
AuditDSAccess = 0 # No auditing (not a DC)
AuditAccountLogon = 3 # Success + Failure
}
'Registry Values' = [ordered]@{
# Interactive logon: Machine inactivity limit -- 10 min (stricter than workstations)
'MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\InactivityTimeoutSecs' = '4,600'
# Interactive logon: Don't display last signed-in user
'MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayLastUserName' = '4,1'
# Interactive logon: Require CTRL+ALT+DEL
'MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\DisableCAD' = '4,0'
# Allow admin accounts to receive unfiltered tokens over WinRM (e.g. Invoke-Command)
# Required for remote GPO/AD baseline management without RDP to DC
'MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy' = '4,1'
}
}
# =================================================================
# Windows Firewall -- default-deny inbound, allow management traffic
# PAWs need inbound WinRM so the DC can manage them remotely.
# =================================================================
FirewallProfiles = @{
Domain = @{ Enabled = $true; DefaultInboundAction = 'Block'; DefaultOutboundAction = 'Allow' }
Private = @{ Enabled = $true; DefaultInboundAction = 'Block'; DefaultOutboundAction = 'Allow' }
Public = @{ Enabled = $true; DefaultInboundAction = 'Block'; DefaultOutboundAction = 'Allow' }
}
FirewallRules = @(
# WinRM -- remote management
@{
DisplayName = 'Allow WinRM HTTP (Inbound)'
Direction = 'Inbound'
Action = 'Allow'
Protocol = 'TCP'
LocalPort = '5985'
Profile = 'Domain'
Description = 'Windows Remote Management (HTTP) for domain management'
}
# RDP -- remote assistance
@{
DisplayName = 'Allow RDP (Inbound)'
Direction = 'Inbound'
Action = 'Allow'
Protocol = 'TCP'
LocalPort = '3389'
Profile = 'Domain'
Description = 'Remote Desktop Protocol for domain-authenticated sessions'
}
# ICMP Echo -- network troubleshooting
@{
DisplayName = 'Allow ICMP Echo Request (Inbound)'
Direction = 'Inbound'
Action = 'Allow'
Protocol = 'ICMPv4'
Profile = 'Domain'
Description = 'ICMP echo for ping-based health monitoring'
}
)
# =================================================================
# Advanced Audit Policy -- granular subcategory-level auditing
# Overrides the legacy Event Audit above with 53 subcategories.
# PAWs need full visibility into admin actions.
# =================================================================
AdvancedAuditPolicy = @{
# System
'Security State Change' = 'Success and Failure'
'Security System Extension' = 'Success and Failure'
'System Integrity' = 'Success and Failure'
# Logon/Logoff
'Logon' = 'Success and Failure'
'Logoff' = 'Success'
'Account Lockout' = 'Success'
'Special Logon' = 'Success and Failure'
'Other Logon/Logoff Events' = 'Success and Failure'
'Group Membership' = 'Success'
# Object Access
'File System' = 'Success and Failure'
'Registry' = 'Success and Failure'
'SAM' = 'Success and Failure'
'Removable Storage' = 'Success and Failure'
# Privilege Use
'Sensitive Privilege Use' = 'Success and Failure'
# Detailed Tracking -- track what admins run
'Process Creation' = 'Success and Failure'
'Process Termination' = 'Success'
'DPAPI Activity' = 'Success and Failure'
'Plug and Play Events' = 'Success'
# Policy Change
'Audit Policy Change' = 'Success and Failure'
'Authentication Policy Change' = 'Success'
'MPSSVC Rule-Level Policy Change' = 'Success and Failure'
# Account Management
'User Account Management' = 'Success and Failure'
'Security Group Management' = 'Success and Failure'
# Account Logon
'Credential Validation' = 'Success and Failure'
'Kerberos Authentication Service' = 'Success and Failure'
'Kerberos Service Ticket Operations' = 'Success and Failure'
}
# =================================================================
# WDAC -- AllowMicrosoft baseline in audit mode
# Trusts all Microsoft-signed binaries and WHQL drivers.
# Logs CodeIntegrity event 3076 for anything that would be blocked.
# Review: Get-WinEvent 'Microsoft-Windows-CodeIntegrity/Operational' | ? Id -eq 3076
# =================================================================
WDACPolicy = @{
PolicyFile = 'WDACPolicy.xml'
}
Scripts = @{
MachineStartup = @(
@{
Source = 'Install-RSAT.ps1'
Parameters = ''
}
)
}
# =================================================================
# AppLocker -- audit mode (logs violations, does not block)
# Same baseline as Workstations-01 but deployed separately so PAWs
# can be tightened to Enabled independently once audit logs are clean.
# =================================================================
AppLockerPolicy = @{
Exe = @{
EnforcementMode = 'AuditOnly'
Rules = @(
@{
Type = 'Publisher'
Name = 'Allow Microsoft-signed executables'
Action = 'Allow'
User = 'Everyone'
Publisher = 'O=MICROSOFT CORPORATION, L=REDMOND, S=WASHINGTON, C=US'
Product = '*'
Binary = '*'
}
@{
Type = 'Path'
Name = 'Allow executables in Program Files'
Action = 'Allow'
User = 'Everyone'
Path = '%PROGRAMFILES%\*'
}
@{
Type = 'Path'
Name = 'Allow executables in Windows directory'
Action = 'Allow'
User = 'Everyone'
Path = '%WINDIR%\*'
}
@{
Type = 'Path'
Name = 'Allow administrators unrestricted'
Action = 'Allow'
User = 'BUILTIN\Administrators'
Path = '*'
}
)
}
Msi = @{
EnforcementMode = 'AuditOnly'
Rules = @(
@{
Type = 'Publisher'
Name = 'Allow Microsoft-signed installers'
Action = 'Allow'
User = 'Everyone'
Publisher = 'O=MICROSOFT CORPORATION, L=REDMOND, S=WASHINGTON, C=US'
Product = '*'
Binary = '*'
}
@{
Type = 'Path'
Name = 'Allow administrators unrestricted'
Action = 'Allow'
User = 'BUILTIN\Administrators'
Path = '*'
}
)
}
Script = @{
EnforcementMode = 'AuditOnly'
Rules = @(
@{
Type = 'Path'
Name = 'Allow scripts in Windows directory'
Action = 'Allow'
User = 'Everyone'
Path = '%WINDIR%\*'
}
@{
Type = 'Path'
Name = 'Allow scripts in Program Files'
Action = 'Allow'
User = 'Everyone'
Path = '%PROGRAMFILES%\*'
}
@{
Type = 'Path'
Name = 'Allow administrators unrestricted'
Action = 'Allow'
User = 'BUILTIN\Administrators'
Path = '*'
}
)
}
}
RegistrySettings = @(
# =============================================================
# Autorun / Autoplay
# =============================================================
@{
Key = 'HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer'
ValueName = 'NoDriveTypeAutoRun'
Type = 'DWord'
Value = 255
}
@{
Key = 'HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer'
ValueName = 'NoAutorun'
Type = 'DWord'
Value = 1
}
# =============================================================
# Windows Update
# =============================================================
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU'
ValueName = 'NoAutoUpdate'
Type = 'DWord'
Value = 0
}
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU'
ValueName = 'AUOptions'
Type = 'DWord'
Value = 4
}
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU'
ValueName = 'ScheduledInstallDay'
Type = 'DWord'
Value = 0
}
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU'
ValueName = 'ScheduledInstallTime'
Type = 'DWord'
Value = 3
}
# =============================================================
# Logging & Auditing -- Enhanced for admin machines
# =============================================================
# PowerShell script block logging
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging'
ValueName = 'EnableScriptBlockLogging'
Type = 'DWord'
Value = 1
}
# PowerShell transcription -- full session recording for all users on this machine
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\PowerShell\Transcription'
ValueName = 'EnableTranscripting'
Type = 'DWord'
Value = 1
}
# Transcription output directory
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\PowerShell\Transcription'
ValueName = 'OutputDirectory'
Type = 'String'
Value = 'C:\PSlogs\Transcripts'
}
# Include invocation headers in transcripts (timestamps per command)
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\PowerShell\Transcription'
ValueName = 'EnableInvocationHeader'
Type = 'DWord'
Value = 1
}
# PowerShell module logging -- log all module activity
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging'
ValueName = 'EnableModuleLogging'
Type = 'DWord'
Value = 1
}
# Log all modules (wildcard)
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames'
ValueName = '*'
Type = 'String'
Value = '*'
}
# Command line in process creation events (Event ID 4688)
@{
Key = 'HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit'
ValueName = 'ProcessCreationIncludeCmdLine_Enabled'
Type = 'DWord'
Value = 1
}
# Event log sizes -- larger than workstations (admin activity generates more events)
# Application log: 64 MB
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\EventLog\Application'
ValueName = 'MaxSize'
Type = 'DWord'
Value = 65536
}
# Security log: 256 MB
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\EventLog\Security'
ValueName = 'MaxSize'
Type = 'DWord'
Value = 262144
}
# System log: 64 MB
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\EventLog\System'
ValueName = 'MaxSize'
Type = 'DWord'
Value = 65536
}
# PowerShell Operational log: 64 MB
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\EventLog\Windows PowerShell'
ValueName = 'MaxSize'
Type = 'DWord'
Value = 65536
}
# =============================================================
# Remote Desktop
# =============================================================
# Require NLA for RDP
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows NT\Terminal Services'
ValueName = 'UserAuthentication'
Type = 'DWord'
Value = 1
}
# =============================================================
# Windows Defender Exclusions -- IDE Performance
# =============================================================
# Real-time scanning of build artifacts and caches degrades IDE
# build and startup performance. These path exclusions prevent
# Defender from scanning frequently-written IDE directories.
# Enable the path exclusions policy
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows Defender\Exclusions'
ValueName = 'Exclusions_Paths'
Type = 'DWord'
Value = 1
}
# JetBrains IDE settings and configuration
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows Defender\Exclusions\Paths'
ValueName = '%APPDATA%\JetBrains'
Type = 'String'
Value = '0'
}
# JetBrains IDE caches, indexes, and Toolbox binaries
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows Defender\Exclusions\Paths'
ValueName = '%LOCALAPPDATA%\JetBrains'
Type = 'String'
Value = '0'
}
# Gradle cache directory
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows Defender\Exclusions\Paths'
ValueName = '%USERPROFILE%\.gradle'
Type = 'String'
Value = '0'
}
)
}