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

289 lines
10 KiB
PowerShell

# Workstations-01 -- Settings Declaration
# Linked to: OU=ExampleWorkstations,DC=example,DC=internal
#
# This GPO targets computer configuration for the ExampleWorkstations OU.
# All settings are Computer Configuration (HKLM) -- both Security Policy and Administrative Templates.
@{
GPOName = 'Workstations-01'
Description = 'Workstation hardening -- security, updates, logging, and remote desktop'
DisableUserConfiguration = $true
LinkTo = 'OU=ExampleWorkstations,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]@{
# Disable local guest account
EnableGuestAccount = 0
}
'Event Audit' = [ordered]@{
# Audit values: 0=None, 1=Success, 2=Failure, 3=Success+Failure
AuditSystemEvents = 1 # Success
AuditLogonEvents = 3 # Success + Failure
AuditObjectAccess = 2 # Failure
AuditPrivilegeUse = 2 # Failure
AuditPolicyChange = 1 # Success
AuditAccountManage = 3 # Success + Failure
AuditProcessTracking = 0 # No auditing
AuditDSAccess = 0 # No auditing (irrelevant for workstations)
AuditAccountLogon = 3 # Success + Failure
}
'Registry Values' = [ordered]@{
# Interactive logon: Machine inactivity limit (seconds) - lock after 15 min
'MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\InactivityTimeoutSecs' = '4,900'
# Interactive logon: Don't display last signed-in user
'MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayLastUserName' = '4,1'
# Interactive logon: Do not require CTRL+ALT+DEL = Disabled (i.e. require it)
'MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\DisableCAD' = '4,0'
}
}
# =================================================================
# Windows Firewall -- default-deny inbound, minimal exceptions
# Standard workstations should not host inbound services.
# Only ICMP for troubleshooting.
# =================================================================
FirewallProfiles = @{
Domain = @{ Enabled = $true; DefaultInboundAction = 'Block'; DefaultOutboundAction = 'Allow' }
Private = @{ Enabled = $true; DefaultInboundAction = 'Block'; DefaultOutboundAction = 'Allow' }
Public = @{ Enabled = $true; DefaultInboundAction = 'Block'; DefaultOutboundAction = 'Allow' }
}
FirewallRules = @(
# ICMP Echo -- network troubleshooting
@{
DisplayName = 'Allow ICMP Echo Request (Inbound)'
Direction = 'Inbound'
Action = 'Allow'
Protocol = 'ICMPv4'
Profile = 'Domain'
Description = 'ICMP echo for ping-based connectivity testing'
}
)
# =================================================================
# AppLocker -- audit mode (logs violations, does not block)
# Standard baseline: allow Microsoft-signed, allow from Windows
# and Program Files, allow admins unrestricted. Deploy in AuditOnly
# first to identify any legitimate apps that would be blocked.
# =================================================================
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
# =============================================================
# Disable autorun on all drive types (bitmask 0xFF = all)
@{
Key = 'HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer'
ValueName = 'NoDriveTypeAutoRun'
Type = 'DWord'
Value = 255
}
# Disable autoplay entirely
@{
Key = 'HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer'
ValueName = 'NoAutorun'
Type = 'DWord'
Value = 1
}
# =============================================================
# Windows Update
# =============================================================
# Enable automatic updates
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU'
ValueName = 'NoAutoUpdate'
Type = 'DWord'
Value = 0
}
# Auto download and schedule install
# 2=Notify, 3=Auto download + notify, 4=Auto download + schedule, 5=Local admin chooses
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU'
ValueName = 'AUOptions'
Type = 'DWord'
Value = 4
}
# Schedule install day (0=Every day, 1=Sunday ... 7=Saturday)
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU'
ValueName = 'ScheduledInstallDay'
Type = 'DWord'
Value = 0
}
# Schedule install time (0-23, 3 = 3:00 AM)
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU'
ValueName = 'ScheduledInstallTime'
Type = 'DWord'
Value = 3
}
# =============================================================
# Logging & Auditing
# =============================================================
# Enable PowerShell script block logging
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging'
ValueName = 'EnableScriptBlockLogging'
Type = 'DWord'
Value = 1
}
# Event log max sizes (in KB)
# Application log: 32 MB
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\EventLog\Application'
ValueName = 'MaxSize'
Type = 'DWord'
Value = 32768
}
# Security log: 192 MB
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\EventLog\Security'
ValueName = 'MaxSize'
Type = 'DWord'
Value = 196608
}
# System log: 32 MB
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows\EventLog\System'
ValueName = 'MaxSize'
Type = 'DWord'
Value = 32768
}
# =============================================================
# Remote Desktop
# =============================================================
# Require Network Level Authentication for RDP connections
@{
Key = 'HKLM\Software\Policies\Microsoft\Windows NT\Terminal Services'
ValueName = 'UserAuthentication'
Type = 'DWord'
Value = 1
}
)
}