Simple Security Analyzer Tool for Windows Server

<#
.SYNOPSIS
Simple Security Analyzer Tool for Windows Server

.DESCRIPTION
This script analyzes basic security settings and configurations on a Windows Server,
providing insights into potential security issues and misconfigurations.

.NOTES
File Name      : WindowsServerSecurityAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, administrator rights on a Windows Server
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\WindowsServerSecurityAnalyzer.ps1
#>

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\WindowsServer_Security_Analysis_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Windows Server Security Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "1. Check Windows Updates Status"
    Write-Host "2. Analyze User Accounts"
    Write-Host "3. Check Firewall Status"
    Write-Host "4. Review Shared Folders"
    Write-Host "5. Check Services Running as SYSTEM"
    Write-Host "6. Analyze Password Policy"
    Write-Host "7. Check for Unquoted Service Paths"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Checks Windows Updates status.

.OUTPUTS
PSObject containing Windows Updates status.
#>
function Check-WindowsUpdates {
    Write-Host "`nChecking Windows Updates Status..." -ForegroundColor Yellow
    $updateSession = New-Object -ComObject Microsoft.Update.Session
    $updateSearcher = $updateSession.CreateUpdateSearcher()
    $pendingUpdates = $updateSearcher.Search("IsInstalled=0")

    $result = [PSCustomObject]@{
        PendingUpdatesCount = $pendingUpdates.Updates.Count
        LastUpdateDate = (Get-HotFix | Sort-Object -Property InstalledOn -Descending | Select-Object -First 1).InstalledOn
    }

    $result | Format-List
    return $result
}

<#
.SYNOPSIS
Analyzes user accounts.

.OUTPUTS
Array of PSObjects containing user account details.
#>
function Analyze-UserAccounts {
    Write-Host "`nAnalyzing User Accounts..." -ForegroundColor Yellow
    $users = Get-LocalUser
    $results = @()
    foreach ($user in $users) {
        $results += [PSCustomObject]@{
            Username = $user.Name
            Enabled = $user.Enabled
            PasswordExpires = $user.PasswordExpires
            LastLogon = $user.LastLogon
            PasswordRequired = $user.PasswordRequired
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks firewall status.

.OUTPUTS
PSObject containing firewall status.
#>
function Check-FirewallStatus {
    Write-Host "`nChecking Firewall Status..." -ForegroundColor Yellow
    $firewallProfiles = Get-NetFirewallProfile
    $result = [PSCustomObject]@{
        DomainProfile = ($firewallProfiles | Where-Object { $_.Name -eq "Domain" }).Enabled
        PrivateProfile = ($firewallProfiles | Where-Object { $_.Name -eq "Private" }).Enabled
        PublicProfile = ($firewallProfiles | Where-Object { $_.Name -eq "Public" }).Enabled
    }
    $result | Format-List
    return $result
}

<#
.SYNOPSIS
Reviews shared folders.

.OUTPUTS
Array of PSObjects containing shared folder details.
#>
function Review-SharedFolders {
    Write-Host "`nReviewing Shared Folders..." -ForegroundColor Yellow
    $shares = Get-SmbShare | Where-Object { $_.Name -notlike "*$" }
    $results = @()
    foreach ($share in $shares) {
        $results += [PSCustomObject]@{
            Name = $share.Name
            Path = $share.Path
            Description = $share.Description
            AccessBasedEnumerationEnabled = $share.FolderEnumerationMode
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks services running as SYSTEM.

.OUTPUTS
Array of PSObjects containing service details.
#>
function Check-SystemServices {
    Write-Host "`nChecking Services Running as SYSTEM..." -ForegroundColor Yellow
    $services = Get-WmiObject Win32_Service | Where-Object { $_.StartName -eq "LocalSystem" }
    $results = @()
    foreach ($service in $services) {
        $results += [PSCustomObject]@{
            Name = $service.Name
            DisplayName = $service.DisplayName
            StartMode = $service.StartMode
            State = $service.State
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes password policy.

.OUTPUTS
PSObject containing password policy details.
#>
function Analyze-PasswordPolicy {
    Write-Host "`nAnalyzing Password Policy..." -ForegroundColor Yellow
    $policy = Get-LocalSecurityPolicy
    $result = [PSCustomObject]@{
        PasswordHistorySize = $policy.'PasswordHistorySize'
        MaximumPasswordAge = $policy.'MaximumPasswordAge'
        MinimumPasswordAge = $policy.'MinimumPasswordAge'
        MinimumPasswordLength = $policy.'MinimumPasswordLength'
        PasswordComplexity = $policy.'PasswordComplexity'
    }
    $result | Format-List
    return $result
}

<#
.SYNOPSIS
Checks for unquoted service paths.

.OUTPUTS
Array of PSObjects containing services with unquoted paths.
#>
function Check-UnquotedServicePaths {
    Write-Host "`nChecking for Unquoted Service Paths..." -ForegroundColor Yellow
    $services = Get-WmiObject Win32_Service | Where-Object { $_.PathName -notlike '"*"' -and $_.PathName -like '* *' }
    $results = @()
    foreach ($service in $services) {
        $results += [PSCustomObject]@{
            Name = $service.Name
            DisplayName = $service.DisplayName
            PathName = $service.PathName
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Generates a comprehensive HTML report of all analyses.

.PARAMETER AllResults
Hashtable containing all analysis results.

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    param([hashtable]$AllResults)

    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Windows Server Security Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
    </style>
</head>
<body>
    <h1>Windows Server Security Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>Windows Updates Status</h2>
    $($AllResults.WindowsUpdates | ConvertTo-Html -Fragment)

    <h2>User Accounts</h2>
    $($AllResults.UserAccounts | ConvertTo-Html -Fragment)

    <h2>Firewall Status</h2>
    $($AllResults.FirewallStatus | ConvertTo-Html -Fragment)

    <h2>Shared Folders</h2>
    $($AllResults.SharedFolders | ConvertTo-Html -Fragment)

    <h2>Services Running as SYSTEM</h2>
    $($AllResults.SystemServices | ConvertTo-Html -Fragment)

    <h2>Password Policy</h2>
    $($AllResults.PasswordPolicy | ConvertTo-Html -Fragment)

    <h2>Unquoted Service Paths</h2>
    $($AllResults.UnquotedServicePaths | ConvertTo-Html -Fragment)
</body>
</html>
"@

    $reportContent | Out-File -FilePath $global:reportPath
    Write-Host "Report generated and saved to: $global:reportPath" -ForegroundColor Green
}

# Main program loop
$allResults = @{}

do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-9)"

    switch ($choice) {
        "1" { $allResults.WindowsUpdates = Check-WindowsUpdates }
        "2" { $allResults.UserAccounts = Analyze-UserAccounts }
        "3" { $allResults.FirewallStatus = Check-FirewallStatus }
        "4" { $allResults.SharedFolders = Review-SharedFolders }
        "5" { $allResults.SystemServices = Check-SystemServices }
        "6" { $allResults.PasswordPolicy = Analyze-PasswordPolicy }
        "7" { $allResults.UnquotedServicePaths = Check-UnquotedServicePaths }
        "8" { Generate-HTMLReport -AllResults $allResults }
        "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "9") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "9")

This Simple Security Analyzer Tool for Windows Server includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various security aspects:
    • Windows Updates status
    • User account analysis
    • Firewall status check
    • Shared folder review
    • Services running as SYSTEM
    • Password policy analysis
    • Check for unquoted service paths
  3. HTML report generation for all collected data.

Key features:

  • Quick overview of pending Windows Updates
  • Analysis of local user accounts and their settings
  • Firewall status check for all profiles
  • Review of non-default shared folders
  • Identification of services running with high privileges (SYSTEM)
  • Password policy review
  • Detection of potential vulnerabilities like unquoted service paths
  • Comprehensive HTML report generation

This tool is particularly useful for:

  • System administrators performing quick security checks
  • IT professionals conducting basic security audits
  • Anyone needing to get a quick overview of a Windows Server’s security posture

To use this script effectively:

  1. Run PowerShell as an administrator on the Windows Server you want to analyze
  2. Ensure you have the necessary permissions to query system information
  3. Review the generated HTML report for a comprehensive overview of the server’s security status

This script provides a simple yet effective way to perform basic security checks on a Windows Server, helping to identify potential security issues and misconfigurations quickly.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *