# DefaultDCPolicy.ps1 # DSC Configuration: Default Domain Controllers Policy for example.internal # # SINGLE SOURCE OF TRUTH: All values are read from settings.ps1. # Do NOT hardcode policy values here -- edit settings.ps1 instead. # # These settings define who can perform privileged operations on DCs # and how DC network communications are secured. # Load helpers for SID resolution and registry value parsing . (Join-Path $PSScriptRoot '..\lib\GPOHelper.ps1') # Load the authoritative settings $dcSettings = & (Join-Path $PSScriptRoot 'settings.ps1') $privRights = $dcSettings.SecurityPolicy['Privilege Rights'] $regValues = $dcSettings.SecurityPolicy['Registry Values'] # --------------------------------------------------------------- # Privilege Rights: Se* constant -> DSC policy name mapping # --------------------------------------------------------------- $privilegeMap = @{ 'SeAssignPrimaryTokenPrivilege' = 'Replace_a_process_level_token' 'SeAuditPrivilege' = 'Generate_security_audits' 'SeDebugPrivilege' = 'Debug_programs' 'SeBackupPrivilege' = 'Back_up_files_and_directories' 'SeRestorePrivilege' = 'Restore_files_and_directories' 'SeBatchLogonRight' = 'Log_on_as_a_batch_job' 'SeInteractiveLogonRight' = 'Allow_log_on_locally' 'SeRemoteInteractiveLogonRight' = 'Allow_log_on_through_Remote_Desktop_Services' 'SeNetworkLogonRight' = 'Access_this_computer_from_the_network' 'SeChangeNotifyPrivilege' = 'Bypass_traverse_checking' 'SeMachineAccountPrivilege' = 'Add_workstations_to_domain' 'SeEnableDelegationPrivilege' = 'Enable_computer_and_user_accounts_to_be_trusted_for_delegation' 'SeCreatePagefilePrivilege' = 'Create_a_pagefile' 'SeIncreaseBasePriorityPrivilege' = 'Increase_scheduling_priority' 'SeIncreaseQuotaPrivilege' = 'Adjust_memory_quotas_for_a_process' 'SeLoadDriverPrivilege' = 'Load_and_unload_device_drivers' 'SeProfileSingleProcessPrivilege' = 'Profile_single_process' 'SeSystemProfilePrivilege' = 'Profile_system_performance' 'SeRemoteShutdownPrivilege' = 'Force_shutdown_from_a_remote_system' 'SeShutdownPrivilege' = 'Shut_down_the_system' 'SeSecurityPrivilege' = 'Manage_auditing_and_security_log' 'SeTakeOwnershipPrivilege' = 'Take_ownership_of_files_or_other_objects' 'SeSystemEnvironmentPrivilege' = 'Modify_firmware_environment_values' 'SeSystemTimePrivilege' = 'Change_the_system_time' 'SeUndockPrivilege' = 'Remove_computer_from_docking_station' } # Build DSC-friendly privilege list: resolve SIDs to NTAccount names $dscPrivileges = @() foreach ($seConst in $privRights.Keys) { if (-not $privilegeMap.ContainsKey($seConst)) { Write-Warning "Unknown privilege constant '$seConst' -- no DSC mapping. Skipping." continue } $dscPrivileges += @{ ResourceName = $seConst -replace '^Se', '' Policy = $privilegeMap[$seConst] Identity = Resolve-SIDsToNames $privRights[$seConst] } } # --------------------------------------------------------------- # Registry Values -> SecurityOption mapping (semantic) # The mapping from DWORD values to DSC enum strings is # setting-specific and must be maintained here. # --------------------------------------------------------------- $dcRegToSecOption = @{ 'LDAPServerIntegrity' = @{ DscProperty = 'Domain_controller_LDAP_server_signing_requirements' ValueMap = @{ 1 = 'None'; 2 = 'Require signing' } } 'RequireSignOrSeal' = @{ DscProperty = 'Domain_member_Digitally_encrypt_or_sign_secure_channel_data_always' ValueMap = @{ 0 = 'Disabled'; 1 = 'Enabled' } } 'RequireSecuritySignature' = @{ DscProperty = 'Microsoft_network_server_Digitally_sign_communications_always' ValueMap = @{ 0 = 'Disabled'; 1 = 'Enabled' } } 'EnableSecuritySignature' = @{ DscProperty = 'Microsoft_network_server_Digitally_sign_communications_if_client_agrees' ValueMap = @{ 0 = 'Disabled'; 1 = 'Enabled' } } } # Extract short key name from full registry paths and map to DSC values $dscSecOptions = @{} foreach ($regPath in $regValues.Keys) { $shortKey = ($regPath -split '\\')[-1] if ($dcRegToSecOption.ContainsKey($shortKey)) { $mapping = $dcRegToSecOption[$shortKey] $numValue = Get-GptTmplRegValue $regValues[$regPath] $dscValue = $mapping.ValueMap[$numValue] if ($null -eq $dscValue) { throw "No DSC value mapping for $shortKey = $numValue" } $dscSecOptions[$mapping.DscProperty] = $dscValue } } # --------------------------------------------------------------- # DSC Configuration # --------------------------------------------------------------- Configuration DefaultDCPolicy { Import-DscResource -ModuleName SecurityPolicyDsc Node 'localhost' { # =============================================================== # User Rights Assignments (generated from settings.ps1) # Force = $true means DSC controls the full list exclusively. # Any identities not listed will be removed from the privilege. # =============================================================== foreach ($priv in $dscPrivileges) { UserRightsAssignment $priv.ResourceName { Policy = $priv.Policy Identity = $priv.Identity Force = $true } } # =============================================================== # Security Options (generated from settings.ps1 Registry Values) # =============================================================== SecurityOption 'DCSecurityOptions' { Name = 'DCSecurityOptions' Domain_controller_LDAP_server_signing_requirements = $dscSecOptions['Domain_controller_LDAP_server_signing_requirements'] Domain_member_Digitally_encrypt_or_sign_secure_channel_data_always = $dscSecOptions['Domain_member_Digitally_encrypt_or_sign_secure_channel_data_always'] Microsoft_network_server_Digitally_sign_communications_always = $dscSecOptions['Microsoft_network_server_Digitally_sign_communications_always'] Microsoft_network_server_Digitally_sign_communications_if_client_agrees = $dscSecOptions['Microsoft_network_server_Digitally_sign_communications_if_client_agrees'] } } }