Infrastructure-as-code framework for Active Directory objects and Group Policy. Sanitized from production deployment for public sharing.
358 lines
13 KiB
PowerShell
358 lines
13 KiB
PowerShell
# Servers-01 -- Settings Declaration
|
|
# Linked to: OU=ExampleServers,DC=example,DC=internal
|
|
#
|
|
# Server hardening policy. Full audit coverage, PowerShell transcription,
|
|
# and operational baselines for domain-joined servers in the ExampleServers OU.
|
|
# All settings are Computer Configuration (HKLM).
|
|
|
|
@{
|
|
GPOName = 'Servers-01'
|
|
Description = 'Server hardening -- full audit, transcription, and operational baseline'
|
|
|
|
DisableUserConfiguration = $true
|
|
|
|
LinkTo = 'OU=ExampleServers,DC=example,DC=internal'
|
|
|
|
# Defense-in-depth: only apply to member servers (ProductType 3).
|
|
# ProductType 2 = domain controllers (have their own OU/GPO).
|
|
WMIFilter = @{
|
|
Name = 'Member Servers Only'
|
|
Description = 'Targets member server operating systems (ProductType = 3)'
|
|
Query = "SELECT * FROM Win32_OperatingSystem WHERE ProductType = 3"
|
|
}
|
|
|
|
# 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]@{
|
|
# Full audit -- servers are high-value targets, log everything
|
|
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 = 3 # Success + Failure
|
|
AuditDSAccess = 3 # Success + Failure
|
|
AuditAccountLogon = 3 # Success + Failure
|
|
}
|
|
|
|
'Registry Values' = [ordered]@{
|
|
# Interactive logon: Machine inactivity limit -- 15 min (servers may have long console sessions)
|
|
'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: Require CTRL+ALT+DEL
|
|
'MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\DisableCAD' = '4,0'
|
|
}
|
|
}
|
|
|
|
# =================================================================
|
|
# Windows Firewall -- default-deny inbound, allow management traffic
|
|
# =================================================================
|
|
|
|
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 (Invoke-Command, Enter-PSSession)
|
|
@{
|
|
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 console access (NLA required via registry setting above)
|
|
@{
|
|
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 and monitoring
|
|
@{
|
|
DisplayName = 'Allow ICMP Echo Request (Inbound)'
|
|
Direction = 'Inbound'
|
|
Action = 'Allow'
|
|
Protocol = 'ICMPv4'
|
|
Profile = 'Domain'
|
|
Description = 'ICMP echo for ping-based health monitoring'
|
|
}
|
|
|
|
# SMB -- file sharing and administrative shares (C$, ADMIN$)
|
|
@{
|
|
DisplayName = 'Allow SMB (Inbound)'
|
|
Direction = 'Inbound'
|
|
Action = 'Allow'
|
|
Protocol = 'TCP'
|
|
LocalPort = '445'
|
|
Profile = 'Domain'
|
|
Description = 'Server Message Block for file sharing and admin shares'
|
|
}
|
|
)
|
|
|
|
# =================================================================
|
|
# GPP Local Groups -- additive membership (does not replace full list)
|
|
# Use RestrictedGroups above for Administrators (exact membership).
|
|
# Use GPP Local Groups here for groups where we add members without
|
|
# wiping existing ones.
|
|
# =================================================================
|
|
|
|
Preferences = @{
|
|
LocalUsersAndGroups = @(
|
|
@{
|
|
GroupName = 'Remote Desktop Users'
|
|
Action = 'Update'
|
|
DeleteAllUsers = $false
|
|
DeleteAllGroups = $false
|
|
Members = @(
|
|
@{ Name = 'EXAMPLE\MasterAdmins'; Action = 'ADD' }
|
|
)
|
|
}
|
|
)
|
|
}
|
|
|
|
# =================================================================
|
|
# Advanced Audit Policy -- granular subcategory-level auditing
|
|
# Overrides the legacy Event Audit above with 53 subcategories.
|
|
# When both are present, Advanced Audit takes precedence on clients.
|
|
# =================================================================
|
|
|
|
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'
|
|
'File Share' = 'Success and Failure'
|
|
'Detailed File Share' = 'Failure'
|
|
'SAM' = 'Success and Failure'
|
|
'Removable Storage' = 'Success and Failure'
|
|
'Filtering Platform Connection' = 'Failure'
|
|
|
|
# Privilege Use
|
|
'Sensitive Privilege Use' = 'Success and Failure'
|
|
|
|
# Detailed Tracking
|
|
'Process Creation' = 'Success and Failure'
|
|
'Process Termination' = 'Success'
|
|
'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'
|
|
'Computer Account Management' = 'Success and Failure'
|
|
'Security Group Management' = 'Success and Failure'
|
|
'Other Account Management Events' = 'Success and Failure'
|
|
|
|
# Account Logon
|
|
'Credential Validation' = 'Success and Failure'
|
|
'Kerberos Authentication Service' = 'Success and Failure'
|
|
'Kerberos Service Ticket Operations' = 'Success and Failure'
|
|
}
|
|
|
|
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 -- weekly Sunday 3 AM
|
|
# =============================================================
|
|
|
|
# Enable automatic updates
|
|
@{
|
|
Key = 'HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU'
|
|
ValueName = 'NoAutoUpdate'
|
|
Type = 'DWord'
|
|
Value = 0
|
|
}
|
|
|
|
# Auto download and schedule install
|
|
@{
|
|
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 = 1
|
|
}
|
|
|
|
# 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 -- full forensic capability
|
|
# =============================================================
|
|
|
|
# PowerShell script block logging
|
|
@{
|
|
Key = 'HKLM\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging'
|
|
ValueName = 'EnableScriptBlockLogging'
|
|
Type = 'DWord'
|
|
Value = 1
|
|
}
|
|
|
|
# PowerShell transcription -- full session recording
|
|
@{
|
|
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 -- match AdminWorkstations (servers generate heavy event volume)
|
|
|
|
# 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
|
|
}
|
|
)
|
|
}
|