Skip to content

Contributing

Ryan edited this page Apr 25, 2026 · 1 revision

Contributing

Thank you for considering contributing to the Windows Security Audit Project! This page provides a guided overview; the canonical contributing document is CONTRIBUTING.md.

Version: 6.1.2

Table of Contents

  1. Code of Conduct
  2. Ways to Contribute
  3. Development Setup
  4. Coding Standards
  5. Testing Requirements
  6. Submission Process
  7. Module Development
  8. Documentation Standards

Code of Conduct

Our Pledge

We are committed to providing a welcoming and inclusive experience for everyone. We expect all contributors to:

  • Use welcoming and inclusive language
  • Be respectful of differing viewpoints and experiences
  • Gracefully accept constructive criticism
  • Focus on what is best for the community
  • Show empathy towards other community members

Unacceptable Behavior

  • Trolling, insulting/derogatory comments, and personal attacks
  • Public or private harassment
  • Publishing others' private information without explicit permission
  • Other conduct that could be considered inappropriate in a professional setting

Enforcement

Project maintainers will remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that don't align with this Code of Conduct.


Ways to Contribute

🐛 Reporting Bugs

When reporting a bug, include:

  • Windows version (e.g., Windows 11 Pro 23H2)
  • PowerShell version ($PSVersionTable.PSVersion)
  • Script version (e.g., 6.1.2)
  • Module(s) affected
  • Steps to reproduce (with the exact command line used)
  • Expected behavior
  • Actual behavior
  • Relevant log excerpts from .\logs\audit-yyyyMMdd-HHmmss.log (run with -LogLevel Debug -Verbose for maximum detail)

Use the Issue Tracker and select the Bug Report template.

💡 Feature Requests

When proposing a feature:

  • Use case: what problem does this solve?
  • Proposed approach: how should it work?
  • Compatibility considerations: which OS/PowerShell versions?
  • Compliance framework alignment: which framework(s) does it support?

📝 Documentation Improvements

Doc improvements are highly welcome — typos, clarifications, expanded examples, missing edge cases. Edit any .md file under docs/ and submit a PR.

🔍 Adding New Compliance Modules

See Module Development below.

🛠️ Bug Fixes

Pick an issue, follow the Submission Process, and submit a PR.


Development Setup

Prerequisites

  • Git
  • PowerShell 5.1+ (or PowerShell 7.x)
  • A test Windows environment (10/11, Server 2016+) for runtime testing
  • (Optional but recommended) Pester 5.x for test execution
  • (Optional but recommended) PSScriptAnalyzer for static linting

Clone and Set Up

# Clone the repository
git clone https://github.com/Sandler73/Windows-Security-Audit-Project.git
cd Windows-Security-Audit-Project\Windows-Security-Audit

# Install development tools
Install-Module -Name Pester -RequiredVersion 5.7.1 -Force -Scope CurrentUser
Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser

# Verify installation
.\Windows-Security-Audit.ps1 -Help
.\Windows-Security-Audit.ps1 -ListModules

# Run a quick smoke test
.\Windows-Security-Audit.ps1 -Modules Core -OutputFormat Console -Quiet

Recommended Editor

  • Visual Studio Code with PowerShell extension
  • PowerShell ISE (built into Windows)

Coding Standards

Module File Header (MANDATORY)

Every .ps1 file must have a comment-based help block:

<#
.SYNOPSIS
    One-line description of what this module/script does.
.DESCRIPTION
    Detailed description, usage context, dependencies, design notes.
.NOTES
    Author: Your Name
    Version: 6.1.2
    Last Updated: 2026-04-25
.EXAMPLE
    .\module-cis.ps1
.EXAMPLE
    .\module-cis.ps1 | Where-Object { $_.Severity -eq 'Critical' }
#>

PowerShell Conventions

  • Use [CmdletBinding()] on every function for consistent behavior
  • Use approved verbs (Get-, Set-, Test-, New-, Remove-, etc.)
  • Use PascalCase for function names; camelCase for variables
  • Use try/catch around external system calls; catch should populate Status=Error result
  • Avoid Write-Host in modules; use Add-Result and Write-AuditLog
  • Avoid $null on the right side of comparisons; use $null -eq $var not $var -eq $null
  • No external dependencies — pure PowerShell stdlib only
  • No BOM characters — files must be UTF-8 without BOM
  • No non-ASCII characters — use plain ASCII; no smart quotes, em-dashes, or special characters
  • Balanced braces — every { must have a matching }
  • Exactly one return $results per module file

Coding Rule Reference

Rule Why
[CmdletBinding()] on every function Consistent error handling, common parameters
Comment-based help on every file Get-Help integration
Try/catch with specific exception types Predictable error behavior
Cache-aware via -Cache $SharedData.Cache Performance
9-field result objects Schema consistency
CrossReferences populated Multi-framework correlation
Severity rated on every check Risk prioritization
Cross-platform path handling Use Join-Path, never hard-code \ separators
ASCII-only source code Cross-locale compatibility

Testing Requirements

Local Pre-Submit Tests

Before submitting a PR, run all of these:

# 1. Lint with PSScriptAnalyzer
Invoke-ScriptAnalyzer -Path .\ -Recurse -ExcludeRule PSAvoidUsingWriteHost,PSUseShouldProcessForStateChangingFunctions

# 2. Verify all modules execute and return results
Get-ChildItem .\modules\*.ps1 | ForEach-Object {
    Write-Host "Testing: $($_.Name)"
    $r = & $_.FullName
    if (-not $r) { Write-Error "Module returned no results" }
    Write-Host "  $($r.Count) checks emitted"
}

# 3. Run full audit
.\Windows-Security-Audit.ps1 -Modules All -OutputFormat JSON -OutputPath .\test.json -Quiet

# 4. Validate result schema
$data = Get-Content .\test.json | ConvertFrom-Json
$data.Results | ForEach-Object {
    foreach ($field in 'Module','Category','Status','Severity','Message','Details','Remediation','CrossReferences','Timestamp') {
        if (-not $_.PSObject.Properties.Name.Contains($field)) {
            Write-Error "Missing field: $field on $($_.Module)/$($_.Category)"
        }
    }
}

# 5. Run Pester tests (if you've added them)
Invoke-Pester -Path .\tests\ -Output Detailed

Brace Balance Check

Get-ChildItem -Recurse -Include *.ps1 | ForEach-Object {
    $content = Get-Content $_.FullName -Raw
    $open  = ([regex]::Matches($content, '\{')).Count
    $close = ([regex]::Matches($content, '\}')).Count
    if ($open -ne $close) {
        Write-Error "$($_.Name): brace imbalance ($open vs $close, delta=$($open - $close))"
    }
}

Non-ASCII / BOM Check

Get-ChildItem -Recurse -Include *.ps1 | ForEach-Object {
    $bytes = [System.IO.File]::ReadAllBytes($_.FullName)
    $hasBom = $bytes.Length -ge 3 -and $bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF
    $hasNonAscii = ($bytes | Where-Object { $_ -gt 127 }).Count -gt 0
    if ($hasBom)      { Write-Error "$($_.Name): contains BOM" }
    if ($hasNonAscii) { Write-Error "$($_.Name): contains non-ASCII characters" }
}

Adding Pester Tests

Tests live in .\tests\test_<feature>.ps1. Use Pester 5.x syntax:

BeforeAll {
    . $PSScriptRoot\..\shared_components\audit-common.ps1
}

Describe "ConvertTo-SafeInt" {
    It "Returns 0 for 'None'" {
        ConvertTo-SafeInt "None" | Should -Be 0
    }
    It "Converts numeric string to int" {
        ConvertTo-SafeInt "42" | Should -Be 42
    }
}

For comprehensive test suite design, see Future Compatibility and Testing.


Submission Process

1. Fork the Repository

Fork Sandler73/Windows-Security-Audit-Project to your account.

2. Create a Feature Branch

git checkout -b feature/your-feature-name
# or
git checkout -b fix/issue-123-description

3. Commit With Clear Messages

Add IPv6 RA filtering check to Core module

- New check: Core - Network Protection / IPv6 RA filter state
- Severity: Medium
- CrossReferences: NIST=SC-8, CIS=4.5
- Documented in Module Documentation wiki page

Fixes #123

4. Update Documentation

5. Submit Pull Request

  • Reference the issue (e.g., "Fixes #123")
  • Describe what changed and why
  • List the testing you performed (Windows version, PS version, command lines)
  • Include screenshots if HTML report changed

6. Address Review Feedback

Maintainers will review and may request changes. Respond promptly and update the PR.


Module Development

Anatomy of a Module

Every module follows the same structure:

<#
.SYNOPSIS
    Brief description of the module's framework focus.
.DESCRIPTION
    Detailed module description.
.NOTES
    Version: 6.1.2
#>

param(
    [hashtable]$SharedData = @{}
)

# Module variables
$moduleName = "MyFramework"
$moduleVersion = "6.1.2"

# Module banner
Write-Host ""
Write-Host "=== $moduleName Module v$moduleVersion ===" -ForegroundColor Cyan

# Initialize results array and helper closures
$results = @()
function Add-Result {
    param(
        [string]$Category, [string]$Status, [string]$Severity,
        [string]$Message, [string]$Details, [string]$Remediation,
        [hashtable]$CrossReferences = @{}
    )
    $script:results += [PSCustomObject]@{
        Module          = $moduleName
        Category        = $Category
        Status          = $Status
        Severity        = $Severity
        Message         = $Message
        Details         = $Details
        Remediation     = $Remediation
        CrossReferences = $CrossReferences
        Timestamp       = (Get-Date)
    }
}

# ============== Check Section: Account Policy ==============
try {
    $minLen = ConvertTo-SafeInt (Get-CachedPasswordPolicy -Cache $SharedData.Cache).MinimumPasswordLength
    if ($minLen -ge 14) {
        Add-Result -Category "MyFramework - Account Policy" `
            -Status "Pass" -Severity "Medium" `
            -Message "Minimum password length adequate ($minLen chars)" `
            -CrossReferences @{ NIST="IA-5"; CIS="5.4" }
    } else {
        Add-Result -Category "MyFramework - Account Policy" `
            -Status "Fail" -Severity "High" `
            -Message "Minimum password length insufficient ($minLen chars; need 14+)" `
            -Remediation "net accounts /minpwlen:14" `
            -CrossReferences @{ NIST="IA-5"; CIS="5.4"; STIG="V-220903" }
    }
}
catch {
    Add-Result -Category "MyFramework - Account Policy" `
        -Status "Error" -Severity "Medium" `
        -Message "Failed to check password policy: $_"
}

# ... more check sections ...

# Module summary
$total = $results.Count
$pass  = ($results | Where-Object Status -eq 'Pass').Count
$fail  = ($results | Where-Object Status -eq 'Fail').Count
Write-Host "  Module $moduleName complete: $total checks ($pass pass, $fail fail)" -ForegroundColor Green

return $results

Module Submission Checklist

  • Module file named module-<name>.ps1 (lowercase)
  • Located in modules/ directory
  • Comment-based help present
  • param([hashtable]$SharedData = @{}) block present
  • $moduleVersion = "6.1.2" declared
  • Results array initialized as @()
  • Add-Result helper function defined
  • All checks wrapped in try/catch
  • Every check has -Severity rating
  • Every check has -CrossReferences mapping
  • Module summary printed
  • Exactly one return $results statement
  • Brace-balanced
  • No BOM, no non-ASCII characters
  • Tested standalone: .\modules\module-yourname.ps1
  • Tested via orchestrator: .\Windows-Security-Audit.ps1 -Modules YourName
  • Documented in Module Documentation wiki

Documentation Standards

Wiki Pages

  • Every page starts with # Page Title
  • Include **Version:** 6.1.2 near the top
  • Use ## Table of Contents for any page over 200 lines
  • Cross-reference related pages: [Page Name](Page-Name)
  • Include code examples for any user-facing feature
  • Update the Footer page version stamp when making structural changes

Project Files

  • README.md — overview and quick reference
  • CHANGELOG.md — release history
  • CONTRIBUTING.md — contribution guidelines (this page mirrors)
  • LICENSE.md — MIT license text
  • SECURITY.md — security policy and disclosure

Recognition

All contributors are listed in CONTRIBUTORS.md (when present) and in commit history.


Questions?


Canonical contributing file: docs/project/CONTRIBUTING.md

Windows Security Audit

Version 6.1.2 · 16 modules · 3,994 checks


🚀 Getting Started


📚 Reference


🏗️ Architecture


🛠️ Operations


📦 Release Information


🔍 Quick Reference

Frameworks Covered

ACSC · CIS · CISA · CMMC · Core · ENISA · GDPR · HIPAA · ISO 27001 · MS · MS-DefenderATP · NIST · NSA · PCI-DSS · SOC 2 · STIG

Output Formats

HTML · JSON · CSV · XML · Console · 6 browser exports

Status Values

Pass · Fail · Warning · Info · Error

Severity Levels

Critical · High · Medium · Low · Informational


🔗 External Links

Clone this wiki locally