# Apply-DscBaseline.ps1 # DC-local compliance validation using DSC. # # Compiles DSC configurations from settings.ps1 (same source of truth as # Apply-GPOBaseline.ps1), then tests local state against the compiled MOF. # This script is test-only by design — it never modifies the system. # To fix drift, edit settings.ps1 and run Apply-GPOBaseline.ps1. # # Usage: # .\Apply-DscBaseline.ps1 # Check DC compliance (read-only) [CmdletBinding()] param() $ErrorActionPreference = 'Stop' $ScriptRoot = $PSScriptRoot $OutputPath = Join-Path $ScriptRoot 'Output' # ------------------------------------------------------------------- # Load shared helper functions (needed by DSC config files) # ------------------------------------------------------------------- . (Join-Path $ScriptRoot 'lib\GPOHelper.ps1') # ------------------------------------------------------------------- # Step 1: Ensure SecurityPolicyDsc module is installed # ------------------------------------------------------------------- Write-Host 'Checking for SecurityPolicyDsc module...' -ForegroundColor Cyan if (-not (Get-Module -ListAvailable -Name SecurityPolicyDsc)) { Write-Host 'Installing SecurityPolicyDsc from PSGallery...' -ForegroundColor Yellow Install-Module -Name SecurityPolicyDsc -Repository PSGallery -Force -Scope AllUsers Write-Host 'Installed.' -ForegroundColor Green } else { Write-Host 'SecurityPolicyDsc is already installed.' -ForegroundColor Green } # ------------------------------------------------------------------- # Step 2: Create output directory for compiled MOF files # ------------------------------------------------------------------- if (-not (Test-Path $OutputPath)) { New-Item -ItemType Directory -Path $OutputPath | Out-Null } # ------------------------------------------------------------------- # Step 3: Load and compile configurations # ------------------------------------------------------------------- $configurations = @( @{ Name = 'DefaultDomainPolicy' Script = Join-Path $ScriptRoot 'default-domain\DefaultDomainPolicy.ps1' }, @{ Name = 'DefaultDCPolicy' Script = Join-Path $ScriptRoot 'default-domain-controller\DefaultDCPolicy.ps1' } ) foreach ($config in $configurations) { Write-Host "`nLoading $($config.Name)..." -ForegroundColor Cyan . $config.Script $mofOutput = Join-Path $OutputPath $config.Name Write-Host "Compiling $($config.Name) -> $mofOutput" -ForegroundColor Cyan & $config.Name -OutputPath $mofOutput | Out-Null Write-Host "Compiled." -ForegroundColor Green } # ------------------------------------------------------------------- # Step 4: Test compliance # ------------------------------------------------------------------- foreach ($config in $configurations) { $mofPath = Join-Path $OutputPath $config.Name Write-Host "`n--- Testing compliance: $($config.Name) ---" -ForegroundColor Yellow $result = Test-DscConfiguration -ReferenceConfiguration (Join-Path $mofPath 'localhost.mof') if ($result.InDesiredState) { Write-Host " [OK] All $($result.ResourcesInDesiredState.Count) resource(s) in desired state" -ForegroundColor Green } else { Write-Host " [DRIFT] $($result.ResourcesNotInDesiredState.Count) resource(s) out of desired state:" -ForegroundColor Red foreach ($resource in $result.ResourcesNotInDesiredState) { Write-Host " $($resource.ResourceId)" -ForegroundColor Red } if ($result.ResourcesInDesiredState.Count -gt 0) { Write-Host " [OK] $($result.ResourcesInDesiredState.Count) resource(s) in desired state" -ForegroundColor Green } } } # ------------------------------------------------------------------- # Step 5: Summary # ------------------------------------------------------------------- Write-Host "`nCompliance test complete. No changes were made." -ForegroundColor Yellow Write-Host 'To fix drift, edit settings.ps1 and run Apply-GPOBaseline.ps1.' -ForegroundColor DarkGray