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

142 lines
6.5 KiB
PowerShell

# 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']
}
}
}