Windows Services Analyzer Tool

<#
.SYNOPSIS
Windows Services Analyzer Tool

.DESCRIPTION
This script analyzes and audits Windows services on local or remote systems,
providing insights into service configurations, startup types, and potential issues.

.NOTES
File Name      : ServicesAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, administrator rights
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\ServicesAnalyzer.ps1
#>

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Windows Services Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "Current Target: $global:targetComputer"
    Write-Host "1. Set Target Computer"
    Write-Host "2. Analyze All Services"
    Write-Host "3. Check Automatic Services Not Running"
    Write-Host "4. Identify Manual Services Running"
    Write-Host "5. Analyze Service Dependencies"
    Write-Host "6. Check Services with Non-Standard Accounts"
    Write-Host "7. Identify Services with No Description"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Sets the target computer for analysis.
#>
function Set-TargetComputer {
    $computer = Read-Host "Enter the name of the target computer (or press Enter for local machine)"
    if ([string]::IsNullOrWhiteSpace($computer)) {
        $global:targetComputer = $env:COMPUTERNAME
    } else {
        $global:targetComputer = $computer
    }
    Write-Host "Target computer set to: $global:targetComputer" -ForegroundColor Green
}

<#
.SYNOPSIS
Analyzes all services on the target computer.

.OUTPUTS
Array of PSObjects containing service details.
#>
function Analyze-AllServices {
    Write-Host "`nAnalyzing All Services..." -ForegroundColor Yellow
    try {
        $services = Get-WmiObject -Class Win32_Service -ComputerName $global:targetComputer
        $results = @()
        foreach ($service in $services) {
            $results += [PSCustomObject]@{
                Name = $service.Name
                DisplayName = $service.DisplayName
                State = $service.State
                StartMode = $service.StartMode
                StartName = $service.StartName
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error analyzing services: $_" -ForegroundColor Red
        return $null
    }
}

<#
.SYNOPSIS
Checks for automatic services that are not running.

.OUTPUTS
Array of PSObjects containing details of automatic services not running.
#>
function Check-AutomaticServicesNotRunning {
    Write-Host "`nChecking Automatic Services Not Running..." -ForegroundColor Yellow
    try {
        $services = Get-WmiObject -Class Win32_Service -ComputerName $global:targetComputer |
                    Where-Object { $_.StartMode -eq "Auto" -and $_.State -ne "Running" }
        $results = @()
        foreach ($service in $services) {
            $results += [PSCustomObject]@{
                Name = $service.Name
                DisplayName = $service.DisplayName
                State = $service.State
                StartMode = $service.StartMode
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error checking automatic services: $_" -ForegroundColor Red
        return $null
    }
}

<#
.SYNOPSIS
Identifies manual services that are running.

.OUTPUTS
Array of PSObjects containing details of manual services running.
#>
function Identify-ManualServicesRunning {
    Write-Host "`nIdentifying Manual Services Running..." -ForegroundColor Yellow
    try {
        $services = Get-WmiObject -Class Win32_Service -ComputerName $global:targetComputer |
                    Where-Object { $_.StartMode -eq "Manual" -and $_.State -eq "Running" }
        $results = @()
        foreach ($service in $services) {
            $results += [PSCustomObject]@{
                Name = $service.Name
                DisplayName = $service.DisplayName
                State = $service.State
                StartMode = $service.StartMode
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error identifying manual services: $_" -ForegroundColor Red
        return $null
    }
}

<#
.SYNOPSIS
Analyzes service dependencies.

.OUTPUTS
Array of PSObjects containing service dependency details.
#>
function Analyze-ServiceDependencies {
    Write-Host "`nAnalyzing Service Dependencies..." -ForegroundColor Yellow
    try {
        $services = Get-WmiObject -Class Win32_Service -ComputerName $global:targetComputer
        $results = @()
        foreach ($service in $services) {
            if ($service.DependentServices) {
                $results += [PSCustomObject]@{
                    Name = $service.Name
                    DisplayName = $service.DisplayName
                    DependentServices = $service.DependentServices -join ", "
                }
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error analyzing service dependencies: $_" -ForegroundColor Red
        return $null
    }
}

<#
.SYNOPSIS
Checks for services with non-standard accounts.

.OUTPUTS
Array of PSObjects containing details of services with non-standard accounts.
#>
function Check-ServicesWithNonStandardAccounts {
    Write-Host "`nChecking Services with Non-Standard Accounts..." -ForegroundColor Yellow
    try {
        $standardAccounts = @("LocalSystem", "NT AUTHORITY\LocalService", "NT AUTHORITY\NetworkService")
        $services = Get-WmiObject -Class Win32_Service -ComputerName $global:targetComputer |
                    Where-Object { $standardAccounts -notcontains $_.StartName }
        $results = @()
        foreach ($service in $services) {
            $results += [PSCustomObject]@{
                Name = $service.Name
                DisplayName = $service.DisplayName
                StartName = $service.StartName
                State = $service.State
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error checking services with non-standard accounts: $_" -ForegroundColor Red
        return $null
    }
}

<#
.SYNOPSIS
Identifies services with no description.

.OUTPUTS
Array of PSObjects containing details of services with no description.
#>
function Identify-ServicesWithNoDescription {
    Write-Host "`nIdentifying Services with No Description..." -ForegroundColor Yellow
    try {
        $services = Get-WmiObject -Class Win32_Service -ComputerName $global:targetComputer |
                    Where-Object { [string]::IsNullOrWhiteSpace($_.Description) }
        $results = @()
        foreach ($service in $services) {
            $results += [PSCustomObject]@{
                Name = $service.Name
                DisplayName = $service.DisplayName
                State = $service.State
                StartMode = $service.StartMode
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error identifying services with no description: $_" -ForegroundColor Red
        return $null
    }
}

<#
.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 Services 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 Services Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>
    <p>Target Computer: $global:targetComputer</p>

    <h2>All Services</h2>
    $($AllResults.AllServices | ConvertTo-Html -Fragment)

    <h2>Automatic Services Not Running</h2>
    $($AllResults.AutomaticNotRunning | ConvertTo-Html -Fragment)

    <h2>Manual Services Running</h2>
    $($AllResults.ManualRunning | ConvertTo-Html -Fragment)

    <h2>Service Dependencies</h2>
    $($AllResults.ServiceDependencies | ConvertTo-Html -Fragment)

    <h2>Services with Non-Standard Accounts</h2>
    $($AllResults.NonStandardAccounts | ConvertTo-Html -Fragment)

    <h2>Services with No Description</h2>
    $($AllResults.NoDescription | 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" { Set-TargetComputer }
        "2" { $allResults.AllServices = Analyze-AllServices }
        "3" { $allResults.AutomaticNotRunning = Check-AutomaticServicesNotRunning }
        "4" { $allResults.ManualRunning = Identify-ManualServicesRunning }
        "5" { $allResults.ServiceDependencies = Analyze-ServiceDependencies }
        "6" { $allResults.NonStandardAccounts = Check-ServicesWithNonStandardAccounts }
        "7" { $allResults.NoDescription = Identify-ServicesWithNoDescription }
        "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 Windows Services Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of Windows services:
    • Analysis of all services
    • Check for automatic services not running
    • Identification of manual services running
    • Analysis of service dependencies
    • Check for services with non-standard accounts
    • Identification of services with no description
  3. Ability to set a target computer for remote analysis.
  4. Comprehensive error handling for each analysis function.
  5. A function to generate an HTML report of all collected data.

Key features:

  • Detailed analysis of all services on the target system
  • Identification of potential issues like automatic services not running
  • Detection of manual services that are running (which might be unnecessary)
  • Analysis of service dependencies to understand the impact of service failures
  • Identification of services using non-standard accounts (potential security concern)
  • Detection of services lacking descriptions (which might indicate unauthorized or suspicious services)
  • Comprehensive HTML report generation

This tool is particularly useful for:

  • System administrators managing Windows services
  • Security professionals auditing service configurations
  • IT professionals troubleshooting service-related issues
  • Compliance officers ensuring proper service configurations

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to query services on the target computer
  3. Be cautious when analyzing services on production systems

This script provides a comprehensive overview of Windows services, making it easier to audit and maintain proper service configurations, identify potential security issues, and ensure the correct setup of services across Windows systems.

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 *