Dargslan.WinSecurityAudit.psm1

<#
.SYNOPSIS
    Windows security hardening audit toolkit — CIS benchmark checks, UAC status, BitLocker, Windows Defender, audit policy, and security scoring

.DESCRIPTION
    Part of the Dargslan Windows Admin Toolkit collection.
    More tools and resources at https://dargslan.com
    Free Cheat Sheets: https://dargslan.com/cheat-sheets
    Windows & DevOps Books: https://dargslan.com/books

.LINK
    https://dargslan.com

.LINK
    https://github.com/Dargslan/powershell-admin-scripts
#>


function Get-SecurityAudit {
    <#
    .SYNOPSIS
        Comprehensive Windows security configuration audit
    .DESCRIPTION
        Checks UAC, BitLocker, Defender, firewall, password policy, audit policy, and provides a security score based on CIS benchmarks.
        Part of Dargslan.WinSecurityAudit — https://dargslan.com
    #>

    [CmdletBinding()] param([switch]$Json)

    $score = 0; $maxScore = 0; $checks = @()
    $addCheck = { param($name, $pass, $detail) $script:maxScore += 10; if ($pass) { $script:score += 10 }; $script:checks += [PSCustomObject]@{ Check = $name; Pass = $pass; Detail = $detail } }

    $uac = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -ErrorAction SilentlyContinue
    & $addCheck "UAC Enabled" ($uac.EnableLUA -eq 1) "EnableLUA=$($uac.EnableLUA)"
    & $addCheck "UAC Prompt Admin" ($uac.ConsentPromptBehaviorAdmin -ge 1) "ConsentPrompt=$($uac.ConsentPromptBehaviorAdmin)"

    $fw = Get-NetFirewallProfile
    & $addCheck "Firewall Domain On" (($fw | Where-Object Name -eq "Domain").Enabled) "Domain profile"
    & $addCheck "Firewall Private On" (($fw | Where-Object Name -eq "Private").Enabled) "Private profile"
    & $addCheck "Firewall Public On" (($fw | Where-Object Name -eq "Public").Enabled) "Public profile"

    $defender = Get-MpComputerStatus -ErrorAction SilentlyContinue
    & $addCheck "Defender RealTime" ($defender.RealTimeProtectionEnabled -eq $true) "Real-time protection"
    & $addCheck "Defender Updated" (($defender.AntivirusSignatureLastUpdated -gt (Get-Date).AddDays(-3))) "Signatures < 3 days old"

    $bl = Get-BitLockerVolume -ErrorAction SilentlyContinue | Where-Object MountPoint -eq "C:"
    & $addCheck "BitLocker C:" ($bl.ProtectionStatus -eq "On") "Protection=$($bl.ProtectionStatus)"

    $rdp = Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server" -ErrorAction SilentlyContinue
    & $addCheck "RDP Restricted" ($rdp.fDenyTSConnections -eq 1) "fDenyTSConnections=$($rdp.fDenyTSConnections)"

    & $addCheck "Guest Disabled" (-not (Get-LocalUser -Name "Guest" -ErrorAction SilentlyContinue).Enabled) "Guest account"

    $pct = [math]::Round($score / $maxScore * 100, 0)
    $grade = if ($pct -ge 90) { "A" } elseif ($pct -ge 75) { "B" } elseif ($pct -ge 60) { "C" } elseif ($pct -ge 40) { "D" } else { "F" }
    $report = [ordered]@{ Score = "$score/$maxScore ($pct%)"; Grade = $grade; Checks = $checks }

    if ($Json) { return $report | ConvertTo-Json -Depth 3 }
    Write-Host "`n [Security Audit]" -ForegroundColor Cyan
    $checks | ForEach-Object { $color = if ($_.Pass) { "Green" } else { "Red" }; $icon = if ($_.Pass) { "✓" } else { "✗" }; Write-Host " $icon $($_.Check): $($_.Detail)" -ForegroundColor $color }
    Write-Host "`n Score: $score/$maxScore ($pct%) — Grade: $grade" -ForegroundColor $(if ($pct -ge 75) { "Green" } elseif ($pct -ge 50) { "Yellow" } else { "Red" })
    return $report
}

Export-ModuleMember -Function *