# 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 } ) }