noid-privacy/Modules/SecurityBaseline/Private/Set-AuditPolicies.ps1

146 lines
6.2 KiB
PowerShell

<#
.SYNOPSIS
Apply audit policies from parsed Security Baseline JSON
.DESCRIPTION
Uses native auditpol.exe to configure Advanced Audit Policies.
Applies settings from AuditPolicies.json generated by Parse-SecurityBaseline.
.PARAMETER AuditPoliciesPath
Path to AuditPolicies.json
.PARAMETER DryRun
Preview changes without applying
.OUTPUTS
PSCustomObject with applied count and errors
.NOTES
Requires Administrator privileges
Uses auditpol.exe (built into Windows since Vista)
#>
function Set-AuditPolicies {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$AuditPoliciesPath,
[Parameter(Mandatory = $false)]
[switch]$DryRun
)
$result = [PSCustomObject]@{
Applied = 0
Errors = @()
}
if (-not (Test-Path $AuditPoliciesPath)) {
$result.Errors += "Audit policies file not found: $AuditPoliciesPath"
return $result
}
try {
$auditPolicies = Get-Content -Path $AuditPoliciesPath -Raw | ConvertFrom-Json
if ($auditPolicies.Count -eq 0) {
Write-Log -Level DEBUG -Message "No audit policies to apply" -Module "SecurityBaseline"
return $result
}
Write-Log -Level DEBUG -Message "Applying $($auditPolicies.Count) audit policies..." -Module "SecurityBaseline"
Write-Host " Applying $($auditPolicies.Count) audit policies..." -ForegroundColor Cyan
$currentPolicy = 0
foreach ($policy in $auditPolicies) {
$currentPolicy++
try {
# Convert SettingValue to auditpol format
# SettingValue is numeric: 0=No Auditing, 1=Success, 2=Failure, 3=Success and Failure
# auditpol format: "enable" or "disable" with /success or /failure flags
$settingValue = [int]$policy.SettingValue
# Build auditpol command using GUID (language-independent!)
$auditpolArgs = @("/set")
$auditpolArgs += "/subcategory:$($policy.SubcategoryGUID)"
switch ($settingValue) {
3 {
# Success and Failure
$auditpolArgs += "/success:enable"
$auditpolArgs += "/failure:enable"
}
1 {
# Success only
$auditpolArgs += "/success:enable"
$auditpolArgs += "/failure:disable"
}
2 {
# Failure only
$auditpolArgs += "/success:disable"
$auditpolArgs += "/failure:enable"
}
default {
# No Auditing (0 or any other value)
$auditpolArgs += "/success:disable"
$auditpolArgs += "/failure:disable"
}
}
if ($DryRun) {
Write-Log -Level DEBUG -Message "[DRYRUN] Would run: auditpol.exe $($auditpolArgs -join ' ')" -Module "SecurityBaseline"
Write-Host " [$currentPolicy/$($auditPolicies.Count)] $($policy.Subcategory) [DRYRUN]" -ForegroundColor DarkGray
$result.Applied++
continue
}
# Show progress (every 5th policy or first/last)
if ($currentPolicy % 5 -eq 0 -or $currentPolicy -eq 1 -or $currentPolicy -eq $auditPolicies.Count) {
# Remove "Audit " prefix if present for cleaner output
$displayName = $policy.Subcategory -replace '^Audit\s+', ''
Write-Host " [$currentPolicy/$($auditPolicies.Count)] $displayName..." -ForegroundColor Gray -NoNewline
}
# Execute auditpol
$process = Start-Process -FilePath "auditpol.exe" `
-ArgumentList $auditpolArgs `
-Wait `
-NoNewWindow `
-PassThru `
-RedirectStandardOutput (Join-Path $env:TEMP "auditpol_stdout.txt") `
-RedirectStandardError (Join-Path $env:TEMP "auditpol_stderr.txt")
if ($process.ExitCode -eq 0) {
$result.Applied++
# Show success for displayed policies
if ($currentPolicy % 5 -eq 0 -or $currentPolicy -eq 1 -or $currentPolicy -eq $auditPolicies.Count) {
Write-Host " OK" -ForegroundColor Green
}
}
else {
$stderr = Get-Content (Join-Path $env:TEMP "auditpol_stderr.txt") -Raw -ErrorAction SilentlyContinue
$result.Errors += "auditpol failed for $($policy.Subcategory): $stderr"
Write-Log -Level DEBUG -Message "auditpol failed for $($policy.Subcategory): $stderr" -Module "SecurityBaseline"
# Show failure
if ($currentPolicy % 5 -eq 0 -or $currentPolicy -eq 1 -or $currentPolicy -eq $auditPolicies.Count) {
Write-Host " FAILED" -ForegroundColor Red
}
}
}
catch {
$result.Errors += "Failed to set audit policy $($policy.Subcategory): $($_.Exception.Message)"
Write-Log -Level DEBUG -Message "Failed to set audit policy $($policy.Subcategory): $_" -Module "SecurityBaseline"
}
}
Write-Log -Level DEBUG -Message "Applied $($result.Applied) audit policies" -Module "SecurityBaseline"
Write-Host " Completed: $($result.Applied)/$($auditPolicies.Count) audit policies applied" -ForegroundColor Green
}
catch {
$result.Errors += "Audit policy application failed: $($_.Exception.Message)"
Write-Log -Level DEBUG -Message "Audit policy application failed: $_" -Module "SecurityBaseline"
}
return $result
}