-
Notifications
You must be signed in to change notification settings - Fork 0
Usage Guide
Comprehensive guide to using the Windows Security Audit Script for various security assessment scenarios.
- Command-Line Parameters
- Module Selection
- Output Configuration
- Remediation Features
- Export Options
- Common Use Cases
- Interpreting Results
- Remediation Workflow
- Automation and Scheduling
- Best Practices
.\Windows-Security-Audit.ps1
[-Modules <String[]>]
[-OutputPath <String>]
[-OutputFormat <String>]
[-RemediateIssues]
[-RemediateIssues_Fail]
[-RemediateIssues_Warning]
[-RemediateIssues_Info]
[-AutoRemediate]
[-RemediationFile <String>]| Parameter | Type | Default | Description |
|---|---|---|---|
-Modules |
String[] | All | Modules to execute (Core, STIG, NIST, CIS, NSA, CISA, MS, All) |
-OutputPath |
String | .\Security-Audit-Report-[timestamp].[ext] |
Path for output file |
-OutputFormat |
String | HTML | Report format (HTML, JSON, CSV, XML, Console) |
-RemediateIssues |
Switch | False | Interactively remediate all issues (Fail, Warning, Info) |
-RemediateIssues_Fail |
Switch | False | Remediate only FAIL status issues |
-RemediateIssues_Warning |
Switch | False | Remediate only WARNING status issues |
-RemediateIssues_Info |
Switch | False | Remediate only INFO status issues |
-AutoRemediate |
Switch | False | Automatically remediate without prompting (requires confirmation) |
-RemediationFile |
String | "" | JSON file containing specific issues to remediate (exported from HTML report) |
| Module | Framework | Checks | Primary Use Case |
|---|---|---|---|
| Core | Essential Windows Security | 177 | Quick baseline assessment |
| STIG | DISA STIGs (CAT I/II/III) | 185 | DoD/Federal compliance |
| NIST | NIST 800-53 Rev 5, CSF | 474 | FISMA, FedRAMP compliance |
| CIS | CIS Benchmarks | 223 | Industry best practices |
| NSA | NSA Cybersecurity Guidance | 173 | Nation-state threat mitigation |
| CISA | CISA Performance Goals | 231 | Critical infrastructure protection |
| MS | Microsoft Security Baselines | 314 | Microsoft recommendations |
| MS-DefenderATP | Defender for Endpoint ATP | 86 | EDR, onboarding, TVM, advanced protection |
Run all modules (comprehensive audit):
.\Windows-Security-Audit.ps1
# OR explicitly:
.\Windows-Security-Audit.ps1 -Modules Core,STIG,NIST,CIS,NSA,CISA,MS,MS-DefenderATPGovernment/Federal systems:
.\Windows-Security-Audit.ps1 -Modules STIG,NIST,CISAEnterprise best practices:
.\Windows-Security-Audit.ps1 -Modules CIS,MSQuick security check:
.\Windows-Security-Audit.ps1 -Modules CoreCritical infrastructure:
.\Windows-Security-Audit.ps1 -Modules CISA,NSAMultiple specific modules:
.\Windows-Security-Audit.ps1 -Modules STIG,CIS,MSHTML Report (Interactive, Human-Readable) ⭐ RECOMMENDED
- Best for manual review and reporting
- Color-coded findings with interactive filtering
- Dark mode support
- Executive summary dashboard
- Built-in export functionality
- Detailed remediation guidance
- Row selection and targeted exports
JSON Report (Machine-Readable, API-Friendly)
- Structured data for automation
- SIEM integration
- Ticketing system import
- Custom analysis tools
- Remediation file format (can be used with
-RemediationFileparameter)
CSV Report (Spreadsheet-Compatible)
- Excel import/analysis
- Remediation tracking
- Dashboard creation
- Trend analysis over time
XML Report (SIEM-Optimized)
- Standards-compliant format
- SIEM ingestion
- Security event management
- Compliance reporting systems
Console Output
- Real-time feedback
- Script debugging
- Quick status checks
Generate HTML report (default):
.\Windows-Security-Audit.ps1JSON only (automation):
.\Windows-Security-Audit.ps1 -OutputFormat JSONCSV only (Excel analysis):
.\Windows-Security-Audit.ps1 -OutputFormat CSVXML for SIEM ingestion:
.\Windows-Security-Audit.ps1 -OutputFormat XMLConsole output only (no file):
.\Windows-Security-Audit.ps1 -OutputFormat ConsoleSpecify custom output path:
.\Windows-Security-Audit.ps1 -OutputPath "C:\SecurityAudits\$(Get-Date -Format 'yyyy-MM')\report.html"Network share:
.\Windows-Security-Audit.ps1 -OutputPath "\\FileServer\AuditReports\$env:COMPUTERNAME\report.html"Create timestamped folders:
$timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
.\Windows-Security-Audit.ps1 -OutputPath "C:\Audits\$timestamp\SecurityAudit.html"The script offers multiple remediation modes to address security findings:
Remediate all issues with prompts:
.\Windows-Security-Audit.ps1 -RemediateIssues- Prompts for each remediation (Y/N/S=Skip remaining)
- Allows review before applying changes
- Generates remediation log
- Safest option for initial remediations
Remediate only critical failures:
.\Windows-Security-Audit.ps1 -RemediateIssues_Fail- Only addresses FAIL status findings
- Best for focusing on critical issues
- Still prompts for confirmation
Remediate warnings only:
.\Windows-Security-Audit.ps1 -RemediateIssues_Warning- Addresses WARNING status findings
- Useful for incremental improvements
Remediate informational items:
.\Windows-Security-Audit.ps1 -RemediateIssues_Info- Addresses INFO status findings
- For optimizing configurations
Auto-remediate with safety confirmations:
.\Windows-Security-Audit.ps1 -RemediateIssues_Fail -AutoRemediate- Requires TWO confirmations before proceeding
- First: Type 'YES' to continue
- Second: Type 'CONFIRM' within 10 seconds
- Shows list of all changes to be made
- Creates detailed remediation log
- Cannot be bypassed or scripted
Example Auto-Remediation Session:
+--------------------------------------------------------------------------------------------------+
| WARNING - AUTO-REMEDIATION |
+--------------------------------------------------------------------------------------------------+
| |
| This will automatically apply 15 remediation(s) WITHOUT prompting for each one. |
| |
| RISKS: |
| - System configuration will be modified automatically |
| - Changes may affect system functionality or applications |
| - Some changes may require system restart |
| |
+--------------------------------------------------------------------------------------------------+
Issues to be remediated:
- [Fail] STIG - Guest account is enabled
- [Fail] Core - SMBv1 protocol is enabled
...
Do you want to proceed with AUTO-REMEDIATION? YES
Final confirmation required. Type 'CONFIRM' within 10 seconds to proceed: CONFIRM
[AUTO] Applying remediations...
Step 1: Generate audit and review HTML report
.\Windows-Security-Audit.ps1Step 2: Select specific issues in HTML report
- Check boxes next to findings you want to remediate
- Click "Export Selected" button
- Choose "JSON" format
- Save as
Selected-Issues.json
Step 3: Apply targeted remediations
.\Windows-Security-Audit.ps1 -AutoRemediate -RemediationFile "Selected-Issues.json"Benefits:
- Surgical precision - only fixes what you selected
- Review and approve specific changes
- Perfect for phased remediation
- Ideal for production environments
- Audit trail of exactly what was changed
Recommended Approach:
- Initial Audit - Run without remediation
.\Windows-Security-Audit.ps1-
Review HTML Report - Examine all findings carefully
- Sort by severity (Status column)
- Filter by module or category
- Read details and remediation commands
-
Test Environment First - Start with non-production
.\Windows-Security-Audit.ps1 -RemediateIssues_Fail- Verify Changes - Run audit again to confirm
.\Windows-Security-Audit.ps1- Production Deployment - Use targeted approach
# Export selected issues from HTML
.\Windows-Security-Audit.ps1 -AutoRemediate -RemediationFile "Approved-Changes.json"All remediation operations create a detailed log file:
Log Location:
.\Remediation-Log-[timestamp].json
Log Contents:
- Timestamp of each remediation attempt
- Module, status, category, and message
- Remediation command executed
- Success or failure status
- Error messages (if failed)
Example Log Entry:
{
"Timestamp": "2024-12-30 14:30:45",
"Module": "STIG",
"Status": "Fail",
"Category": "STIG - V-220929 (CAT I)",
"Message": "Guest account is ENABLED",
"Remediation": "Disable-LocalUser -Name Guest",
"Result": "SUCCESS",
"Error": ""
}The interactive HTML report includes comprehensive export functionality:
Located at the top of the results section:
Export All
- Exports all findings from all modules
- Includes all visible (non-filtered) results
- Supports all export formats
Export Selected
- Exports only checked rows across all modules
- Perfect for creating targeted reports
- Can be used for remediation planning
Each module section has its own export buttons:
Export Module
- Exports all findings from that specific module
- Respects current filters
- Includes module statistics
Export Selected from Module
- Exports only checked rows from that module
- Useful for module-specific reporting
When you click any export button, a modal dialog appears with format options:
| Format | Use Case | Features |
|---|---|---|
| CSV | Excel import, data analysis | Tab/comma delimited, preserves line breaks |
| Excel | Formatted reports | Styled tables, colored headers, HTML formatting |
| JSON | Automation, remediation | Machine-readable, can be used with -RemediationFile
|
| XML | SIEM integration | Standards-compliant, hierarchical structure |
| TXT | Plain text reports | Fixed-width columns, human-readable |
Scenario 1: Export Failed Checks for Management
- Open HTML report
- Click "Status" column header to sort
- Use filter to show only "Fail" status
- Click "Export All" → "Excel"
- Result: Formatted Excel report with only failures
Scenario 2: Create Remediation File
- Open HTML report
- Review findings
- Check boxes for issues you want to fix
- Click "Export Selected" → "JSON"
- Save as
remediation-plan.json - Run:
.\Windows-Security-Audit.ps1 -AutoRemediate -RemediationFile "remediation-plan.json"
Scenario 3: SIEM Integration
- Run audit:
.\Windows-Security-Audit.ps1 -OutputFormat XML - Or from HTML: Click "Export All" → "XML"
- Import XML into SIEM platform
- Create correlation rules and alerts
- Toggle button in top-right corner
- Preference saved in browser
- Easy on the eyes for long review sessions
- Click any column header to sort
- Click again to reverse sort
- Visual indicators (arrows) show sort direction
- Type in filter boxes under each column header
- Real-time filtering as you type
- Case-insensitive search
- Works across all data fields
- Checkboxes for individual rows
- "Select All" checkbox in header
- Select across filtered results
- Selected rows highlighted
- Click module header to collapse/expand
- Arrow icon indicates state
- Makes navigation easier in large reports
Scenario: New system or never-audited environment
# Run comprehensive audit
.\Windows-Security-Audit.ps1
# Review HTML report
# Focus on FAIL status items
# Prioritize CAT I (STIG) findingsNext steps:
- Review executive summary for overall posture
- Filter by "Fail" status in each module
- Create remediation plan prioritizing critical issues
- Document baseline for future comparisons
Scenario: NIST 800-53 compliance assessment
# Run NIST module
.\Windows-Security-Audit.ps1 -Modules NIST -OutputFormat HTML,JSON
# Generate evidence package
$date = Get-Date -Format "yyyy-MM-dd"
Compress-Archive -Path ".\Security-Audit-Report-*.html", ".\Security-Audit-Report-*.json" -DestinationPath "NIST_Compliance_$date.zip"For different frameworks:
# DISA STIG compliance
.\Windows-Security-Audit.ps1 -Modules STIG
# CIS Benchmarks compliance
.\Windows-Security-Audit.ps1 -Modules CIS
# CISA Performance Goals
.\Windows-Security-Audit.ps1 -Modules CISAScenario: Validate gold image or template before deployment
# Run all modules for comprehensive validation
.\Windows-Security-Audit.ps1
# Open HTML report and review findings
# Export only failed checks
# Create remediation plan
# Apply remediations interactively
.\Windows-Security-Audit.ps1 -RemediateIssues_Fail
# Verify all checks pass
.\Windows-Security-Audit.ps1Automated validation script:
# Audit and check for failures
.\Windows-Security-Audit.ps1 -OutputFormat JSON -OutputPath ".\audit-result.json"
$results = Get-Content ".\audit-result.json" | ConvertFrom-Json
$failures = $results.Results | Where-Object { $_.Status -eq "Fail" }
if ($failures.Count -eq 0) {
Write-Host "✓ Gold image passed all security checks" -ForegroundColor Green
exit 0
} else {
Write-Host "✗ $($failures.Count) security issues found" -ForegroundColor Red
$failures | Format-Table Module, Category, Message
exit 1
}Scenario: Weekly security posture monitoring
# Create scheduled task
$action = New-ScheduledTaskAction `
-Execute "PowerShell.exe" `
-Argument "-NoProfile -ExecutionPolicy Bypass -File C:\SecurityAudit\Windows-Security-Audit.ps1 -OutputFormat HTML,JSON -OutputPath C:\AuditReports\Weekly-Report.html"
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At 2AM
$principal = New-ScheduledTaskPrincipal `
-UserId "SYSTEM" `
-LogonType ServiceAccount `
-RunLevel Highest
Register-ScheduledTask `
-TaskName "Weekly Security Audit" `
-Action $action `
-Trigger $trigger `
-Principal $principal `
-Description "Automated security compliance audit"Scenario: Verify fixes after remediation
# Run audit before remediation (baseline)
.\Windows-Security-Audit.ps1 -OutputPath "C:\Audits\Before\audit.html"
# Review report and select issues to fix
# Export selected issues to JSON
# Apply targeted remediation
.\Windows-Security-Audit.ps1 -AutoRemediate -RemediationFile "C:\Audits\selected-issues.json"
# Run audit after remediation
.\Windows-Security-Audit.ps1 -OutputPath "C:\Audits\After\audit.html"
# Compare results
$before = Get-Content "C:\Audits\Before\audit.json" | ConvertFrom-Json
$after = Get-Content "C:\Audits\After\audit.json" | ConvertFrom-Json
$beforeFail = ($before.Results | Where-Object { $_.Status -eq "Fail" }).Count
$afterFail = ($after.Results | Where-Object { $_.Status -eq "Fail" }).Count
Write-Host "Failed checks before: $beforeFail"
Write-Host "Failed checks after: $afterFail"
Write-Host "Improvement: $($beforeFail - $afterFail) issues resolved"Scenario: Assess compromised or suspicious system
# Quick focused assessment
.\Windows-Security-Audit.ps1 `
-Modules Core,STIG,NSA `
-OutputPath "C:\IR\$env:COMPUTERNAME\forensic-audit.html"
# Look for:
# - Disabled security features (Defender, Firewall, UAC)
# - Weak authentication settings
# - Logging disabled
# - Unauthorized accounts
# - Suspicious service configurations
# Export all findings to JSON for analysis
# From HTML report: Export All → JSONScenario: Send audit results to SIEM
# Generate XML output for SIEM ingestion
.\Windows-Security-Audit.ps1 `
-OutputFormat XML `
-OutputPath "C:\SIEM\Ingest\security-audit-$env:COMPUTERNAME.xml"
# XML can be ingested by:
# - Splunk (via HTTP Event Collector or file monitoring)
# - ELK Stack (via Filebeat)
# - Microsoft Sentinel (via Log Analytics)
# - QRadar (via Universal REST API)
# - Any SIEM supporting XML ingestionAutomated SIEM forwarding:
# Run audit and forward to SIEM
.\Windows-Security-Audit.ps1 -OutputFormat XML -OutputPath ".\audit.xml"
# Upload to SIEM (example using REST API)
$xmlContent = Get-Content ".\audit.xml" -Raw
$headers = @{
"Content-Type" = "application/xml"
"Authorization" = "Bearer $SIEMToken"
}
Invoke-RestMethod -Uri "https://siem.company.com/api/ingest" -Method Post -Headers $headers -Body $xmlContentScenario: Audit multiple systems and aggregate results
# Create audit script for remote execution
$systems = @("Server01", "Server02", "Workstation01")
$results = @()
foreach ($system in $systems) {
Write-Host "Auditing $system..." -ForegroundColor Cyan
# Copy script to remote system
$session = New-PSSession -ComputerName $system
Copy-Item -ToSession $session -Path ".\Windows-Security-Audit.ps1" -Destination "C:\Temp\"
Copy-Item -ToSession $session -Path ".\Modules" -Destination "C:\Temp\" -Recurse
# Run audit remotely
Invoke-Command -Session $session -ScriptBlock {
Set-Location C:\Temp
.\Windows-Security-Audit.ps1 -OutputFormat JSON -OutputPath "C:\Temp\audit-result.json"
}
# Retrieve results
Copy-Item -FromSession $session -Path "C:\Temp\audit-result.json" -Destination ".\Reports\$system-audit.json"
# Cleanup
Invoke-Command -Session $session -ScriptBlock { Remove-Item C:\Temp\*.ps1, C:\Temp\Modules -Recurse -Force }
Remove-PSSession $session
}
Write-Host "All audits complete. Results in .\Reports\"
# Generate consolidated report
$allResults = Get-ChildItem ".\Reports\*-audit.json" | ForEach-Object {
$data = Get-Content $_.FullName | ConvertFrom-Json
$data.Results | Add-Member -NotePropertyName "ComputerName" -NotePropertyValue $data.ExecutionInfo.ComputerName -PassThru
}
$allResults | Export-Csv ".\Reports\Consolidated-Audit-$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformationScenario: Large-scale remediation across multiple systems
Phase 1: Discovery and Planning
# Audit all systems
.\Windows-Security-Audit.ps1
# Review HTML report
# Group issues by:
# - Severity (Fail, Warning, Info)
# - Impact (requires restart, affects applications, etc.)
# - Module (STIG, CIS, etc.)
# Export critical failures to JSON
# From HTML: Filter Status=Fail, Export Selected → JSONPhase 2: Test Environment
# Apply remediations in test
.\Windows-Security-Audit.ps1 -AutoRemediate -RemediationFile "critical-fixes.json"
# Test for 1-2 weeks
# Monitor for issues
# Run audit again to verify
.\Windows-Security-Audit.ps1Phase 3: Production Pilot
# Select pilot systems
$pilotSystems = @("PROD-WEB01", "PROD-APP01")
foreach ($system in $pilotSystems) {
# Run on pilot system
Invoke-Command -ComputerName $system -FilePath ".\Windows-Security-Audit.ps1" -ArgumentList "-AutoRemediate", "-RemediationFile critical-fixes.json"
# Verify
Invoke-Command -ComputerName $system -FilePath ".\Windows-Security-Audit.ps1" -ArgumentList "-OutputFormat JSON"
}Phase 4: Full Deployment
# Deploy to all production systems
# Use Configuration Management tools:
# - GPO for registry/policy changes
# - SCCM/Intune for system configurations
# - Puppet/Chef/Ansible for server fleets| Status | Symbol | Meaning | Priority | Action Required |
|---|---|---|---|---|
| Pass | ✅ | Compliant with security requirement | N/A | None |
| Fail | ❌ | Non-compliant, security issue | High | Immediate remediation |
| Warning | Potential issue or best practice deviation | Medium | Review and consider fix | |
| Info | ℹ️ | Informational, for awareness | Low | Note for reference |
| Error | 🔴 | Check could not complete | Variable | Investigate cause |
| Category | Severity | Risk | Examples |
|---|---|---|---|
| CAT I | High | System is vulnerable to immediate attack | Guest account enabled, UAC disabled, Firewall off |
| CAT II | Medium | Configuration weakness that could be exploited | Weak password policy, logging disabled, SMBv1 enabled |
| CAT III | Low | Configuration that slightly increases risk | Aesthetic settings, non-critical features |
Executive Summary:
- Overall compliance percentage
- Total checks run vs. passed
- Module-by-module statistics
- Visual status breakdown
System Information:
- Computer name and domain
- Windows version and build
- Last boot time
- Audit timestamp
- Execution duration
Module Results:
- Organized by framework (STIG, NIST, CIS, etc.)
- Color-coded status indicators
- Expandable detail sections
- Inline remediation commands
- Interactive filtering and sorting
Export Options:
- Global exports (all data)
- Module-specific exports
- Selected row exports
- Multiple format support
Standard JSON Structure:
{
"ExecutionInfo": {
"ComputerName": "WORKSTATION01",
"OSVersion": "Microsoft Windows 10 Pro",
"ScanDate": "2024-12-30 14:30:22",
"Duration": "00:05:34",
"ModulesRun": ["Core", "STIG", "NIST"],
"TotalChecks": 3199,
"PassCount": 487,
"FailCount": 34,
"WarningCount": 21,
"InfoCount": 5,
"ErrorCount": 3
},
"Results": [
{
"Module": "STIG",
"Category": "STIG - V-220929 (CAT I)",
"Status": "Fail",
"Message": "Guest account is ENABLED",
"Details": "STIG CAT I: Guest account must be disabled...",
"Remediation": "Disable-LocalUser -Name Guest",
"Timestamp": "2024-12-30 14:30:25"
}
]
}Remediation File JSON Structure:
{
"exportDate": "2024-12-30T14:30:22Z",
"modules": [
{
"moduleName": "STIG",
"results": [
{
"Status": "Fail",
"Category": "STIG - V-220929 (CAT I)",
"Finding": "Guest account is ENABLED"
}
]
}
]
}SIEM-Optimized Format:
<?xml version="1.0" encoding="UTF-8"?>
<security_audit>
<metadata>
<export_date>2024-12-30T14:30:22Z</export_date>
<computer_name>WORKSTATION01</computer_name>
<operating_system>Microsoft Windows 10 Pro</operating_system>
<scan_date>2024-12-30 14:30:22</scan_date>
<duration>00:05:34</duration>
<total_checks>3199</total_checks>
<pass_count>487</pass_count>
<fail_count>34</fail_count>
</metadata>
<events>
<event>
<timestamp>2024-12-30T14:30:25Z</timestamp>
<module>STIG</module>
<status>Fail</status>
<category>STIG - V-220929 (CAT I)</category>
<message>Guest account is ENABLED</message>
<details>STIG CAT I: Guest account must be disabled...</details>
<remediation>Disable-LocalUser -Name Guest</remediation>
</event>
</events>
</security_audit>High Priority (Fix Immediately):
1. CAT I STIG findings
2. FAIL status items in critical areas:
- Firewall disabled
- Antivirus disabled
- UAC disabled
- Guest account enabled
- SMBv1 enabled
Medium Priority (Fix Soon):
1. CAT II STIG findings
2. FAIL status in authentication/audit areas
3. WARNING status in critical areas
Low Priority (Address Over Time):
1. CAT III STIG findings
2. WARNING status in non-critical areas
3. INFO items for future planning
# Start interactive remediation for failures
.\Windows-Security-Audit.ps1 -RemediateIssues_Fail
# Review each finding
# Press Y to apply, N to skip, S to skip all remaining
# System will prompt before each change# Step 1: Generate audit
.\Windows-Security-Audit.ps1
# Step 2: Review HTML report
# - Check boxes next to issues you want to fix
# - Click "Export Selected"
# - Choose JSON format
# - Save as "approved-fixes.json"
# Step 3: Apply selected remediations
.\Windows-Security-Audit.ps1 -AutoRemediate -RemediationFile "approved-fixes.json"
# Requires two confirmations before proceeding# Auto-remediate critical failures
# Requires two confirmations
.\Windows-Security-Audit.ps1 -RemediateIssues_Fail -AutoRemediate
# This will:
# 1. Show all changes to be made
# 2. Require typing 'YES' to proceed
# 3. Require typing 'CONFIRM' within 10 seconds
# 4. Apply all remediations automatically
# 5. Generate detailed log file# Re-run audit to verify remediations
.\Windows-Security-Audit.ps1
# Check specific findings in HTML report
# Compare before/after statistics
# Or programmatically:
$results = Get-Content ".\Security-Audit-Report-*.json" | ConvertFrom-Json
$remainingFails = ($results.Results | Where-Object { $_.Status -eq "Fail" }).Count
Write-Host "Remaining failures: $remainingFails"Review Remediation Log:
# Remediation log is automatically created
Get-Content ".\Remediation-Log-*.json" | ConvertFrom-Json | Format-Table
# Create change report
$log = Get-Content ".\Remediation-Log-*.json" | ConvertFrom-Json
$log | Where-Object { $_.Result -eq "SUCCESS" } | Export-Csv "Changes-Applied.csv" -NoTypeInformationCreate Change Ticket:
$changeLog = @"
CHANGE RECORD
=============
Date: $(Get-Date)
System: $env:COMPUTERNAME
Performed By: $env:USERNAME
Changes Applied:
$(Get-Content ".\Remediation-Log-*.json" | ConvertFrom-Json |
Where-Object { $_.Result -eq "SUCCESS" } |
ForEach-Object { "- [$($_.Module)] $($_.Message)" })
Verification:
- Re-ran security audit
- Confirmed all changes successful
- No system issues detected
Restart Required: [YES/NO]
"@
$changeLog | Out-File "Change-Record-$(Get-Date -Format 'yyyyMMdd').txt"If remediation causes issues, you can roll back changes:
For Registry Changes:
# Export registry before remediation
reg export "HKLM\SYSTEM\CurrentControlSet" ".\Backup\system-before.reg"
# If rollback needed
reg import ".\Backup\system-before.reg"For Service Changes:
# Document original service states before remediation
Get-Service | Select-Object Name, Status, StartType |
Export-Csv ".\Backup\services-before.csv"
# Restore if needed
$original = Import-Csv ".\Backup\services-before.csv"
foreach ($svc in $original) {
Set-Service -Name $svc.Name -StartupType $svc.StartType
}System Restore:
# Create restore point before major changes
Checkpoint-Computer -Description "Before Security Remediation" -RestorePointType "MODIFY_SETTINGS"
# Restore if needed
# Use System Restore UI or:
Get-ComputerRestorePoint | Format-Table
Restore-Computer -RestorePoint <SequenceNumber>- Open Task Scheduler (
taskschd.msc) - Create Basic Task
- Name: "Security Audit"
- Trigger: Weekly (Monday, 2:00 AM)
- Action: Start a program
- Program:
PowerShell.exe - Arguments:
-NoProfile -ExecutionPolicy Bypass -File "C:\SecurityAudit\Windows-Security-Audit.ps1" -OutputFormat HTML
- Program:
- Run with highest privileges
Weekly Audit:
$action = New-ScheduledTaskAction `
-Execute "PowerShell.exe" `
-Argument '-NoProfile -ExecutionPolicy Bypass -File "C:\SecurityAudit\Windows-Security-Audit.ps1" -OutputFormat HTML,JSON'
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At 2AM
$principal = New-ScheduledTaskPrincipal `
-UserId "SYSTEM" `
-RunLevel Highest
$settings = New-ScheduledTaskSettingsSet `
-AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries `
-StartWhenAvailable
Register-ScheduledTask `
-TaskName "Weekly Security Audit" `
-Action $action `
-Trigger $trigger `
-Principal $principal `
-Settings $settingsDaily Quick Check:
$action = New-ScheduledTaskAction `
-Execute "PowerShell.exe" `
-Argument '-NoProfile -ExecutionPolicy Bypass -File "C:\SecurityAudit\Windows-Security-Audit.ps1" -Modules Core -OutputFormat JSON'
$trigger = New-ScheduledTaskTrigger -Daily -At 6AM
Register-ScheduledTask `
-TaskName "Daily Security Check" `
-Action $action `
-Trigger $trigger `
-Principal (New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest)Send Results via Email:
# Run audit
.\Windows-Security-Audit.ps1
# Get latest report
$report = Get-ChildItem ".\Security-Audit-Report-*.html" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
# Read summary from JSON
$json = Get-ChildItem ".\Security-Audit-Report-*.json" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
$summary = Get-Content $json.FullName | ConvertFrom-Json
$emailBody = @"
Security Audit Report for $env:COMPUTERNAME
Summary:
- Total Checks: $($summary.ExecutionInfo.TotalChecks)
- Passed: $($summary.ExecutionInfo.PassCount)
- Failed: $($summary.ExecutionInfo.FailCount)
- Warnings: $($summary.ExecutionInfo.WarningCount)
Full report attached.
"@
Send-MailMessage `
-To "security-team@company.com" `
-From "security-audit@$env:COMPUTERNAME" `
-Subject "Security Audit - $env:COMPUTERNAME - $(Get-Date -Format 'yyyy-MM-dd')" `
-Body $emailBody `
-Attachments $report.FullName `
-SmtpServer "smtp.company.com"Automated XML Export to SIEM:
# Generate XML for SIEM
.\Windows-Security-Audit.ps1 -OutputFormat XML -OutputPath "C:\SIEM\Ingest\audit-$env:COMPUTERNAME.xml"
# Upload to SIEM (example - adjust for your SIEM)
$xml = Get-Content "C:\SIEM\Ingest\audit-$env:COMPUTERNAME.xml" -Raw
Invoke-RestMethod -Uri "https://siem.company.com/api/ingest" -Method Post -Body $xml -ContentType "application/xml"Scheduled SIEM Forwarding:
$action = New-ScheduledTaskAction `
-Execute "PowerShell.exe" `
-Argument '-NoProfile -ExecutionPolicy Bypass -Command "& { .\Windows-Security-Audit.ps1 -OutputFormat XML -OutputPath temp.xml; Invoke-RestMethod -Uri https://siem/api/ingest -Method Post -Body (Get-Content temp.xml -Raw) -ContentType application/xml }"'
$trigger = New-ScheduledTaskTrigger -Daily -At 3AM
Register-ScheduledTask `
-TaskName "SIEM Security Audit Feed" `
-Action $action `
-Trigger $trigger `
-Principal (New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest)- Weekly: Critical production systems
- Monthly: Standard workstations and servers
- Quarterly: Low-risk systems
- After changes: System updates, configuration changes, patches
Establish Initial Baseline:
.\Windows-Security-Audit.ps1 -OutputPath "C:\Baseline\Baseline-$(Get-Date -Format 'yyyy-MM-dd').html"Monthly Comparisons:
# Track trends over time
# Create folder structure: C:\Audits\2024-01, 2024-02, etc.
# Compare month-over-month improvements
# Example comparison script:
$thisMonth = Import-Csv ".\Audits\2024-12\audit.csv"
$lastMonth = Import-Csv ".\Audits\2024-11\audit.csv"
$improvement = ($lastMonth | Where-Object Status -eq "Fail").Count - ($thisMonth | Where-Object Status -eq "Fail").Count
Write-Host "Month-over-month improvement: $improvement fewer failures"Pre-Change Audit:
.\Windows-Security-Audit.ps1 -OutputPath "C:\Changes\CHG001-Before.html"Post-Change Verification:
.\Windows-Security-Audit.ps1 -OutputPath "C:\Changes\CHG001-After.html"
# Compare to ensure no security regressionsEncrypt Sensitive Reports:
# Reports contain sensitive system information
# Store in secured location with access controls
# Option 1: EFS encryption
cipher /e ".\Reports"
# Option 2: CMS encryption
$report = Get-Item ".\Security-Audit-Report-*.html"
Protect-CmsMessage -To "CN=SecurityTeam" -Path $report.FullName -OutFile "$($report.FullName).cms"
# Option 3: ZIP with password
Compress-Archive -Path ".\Reports\*" -DestinationPath "Audit-$(Get-Date -Format 'yyyyMMdd').zip"
# Then use 7-Zip or similar to add password- Don't rely solely on automated results
- Review findings with qualified personnel
- Consider context and business requirements
- Some "failures" may be acceptable risks
- Document exceptions and approvals
Always test in non-production:
# Test environment
.\Windows-Security-Audit.ps1 -RemediateIssues_Fail
# Monitor for 24-48 hours
# Test applications
# Verify no adverse impacts
# Then proceed to production with targeted approach
.\Windows-Security-Audit.ps1 -AutoRemediate -RemediationFile "approved-changes.json"Keep Historical Records:
# Archive old reports
$archivePath = "\\FileServer\AuditArchive\$env:COMPUTERNAME"
Copy-Item ".\Security-Audit-Report-*.html" -Destination $archivePath
# Maintain for compliance periods:
# - SOX: 7 years
# - HIPAA: 6 years
# - GDPR: Varies by data type
# - PCI DSS: 1 year minimum
# - SOC 2: Per audit period
# - PCI DSS: 1 year (3 months immediately available)# Check for updates on GitHub
# https://github.com/Sandler73/Windows-Security-Audit-Project
# Review changelog for new features
# Test updates in non-production first
# Update scheduled tasks with new versionCreate Runbook:
SECURITY AUDIT RUNBOOK
=====================
1. Schedule:
- Weekly: Production servers (Monday 2 AM)
- Monthly: Workstations (First Sunday 1 AM)
2. Review Process:
- Open HTML report
- Review failed checks
- Create remediation plan
- Get approvals
3. Remediation:
- Test in lab environment
- Apply to pilot group
- Roll out to production
4. Verification:
- Re-run audit
- Compare results
- Document changes
5. Reporting:
- Email summary to security team
- Export to compliance management system
- Archive reports
6. Escalation:
- CAT I failures: Immediate notification
- New vulnerabilities: Emergency change process
Combine with Other Tools:
# Run security audit
.\Windows-Security-Audit.ps1 -OutputFormat JSON
# Import into vulnerability management
Import-SecurityFindings -Source ".\audit.json" -System "VulnMgmt"
# Create tickets for failures
$findings = Get-Content ".\audit.json" | ConvertFrom-Json
$findings.Results | Where-Object Status -eq "Fail" | ForEach-Object {
New-ServiceNowTicket -Title $_.Message -Description $_.Details -Priority "High"
}
# Update CMDB
Update-CMDBSecurityPosture -System $env:COMPUTERNAME -Audit $findings- 📖 Framework Reference - Detailed framework information
- 🛠️ Troubleshooting Guide - Common issues and solutions
- 📚 Module Documentation - Deep dive into each module
- 👨💻 Development Guide - Contribute to the project