Certificates Analyzer Tool

<#
.SYNOPSIS
Certificates Analyzer Tool

.DESCRIPTION
This script analyzes and audits certificates on a Windows system, including those in the
certificate store and those used by IIS. It provides insights into certificate expiration,
usage, and potential issues.

.NOTES
File Name      : CertificatesAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, administrator rights, and IIS if analyzing IIS certificates
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\CertificatesAnalyzer.ps1
#>

# Import required modules
Import-Module WebAdministration -ErrorAction SilentlyContinue

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Certificates Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "1. Analyze All Certificates in Local Machine Store"
    Write-Host "2. Check for Expiring Certificates"
    Write-Host "3. Analyze IIS Binding Certificates"
    Write-Host "4. Check for Weak Key Certificates"
    Write-Host "5. Analyze Certificate Chain"
    Write-Host "6. Check for Duplicate Certificates"
    Write-Host "7. Analyze Certificate Usage"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Analyzes all certificates in the Local Machine store.

.OUTPUTS
Array of PSObjects containing certificate details.
#>
function Analyze-AllCertificates {
    Write-Host "`nAnalyzing All Certificates in Local Machine Store..." -ForegroundColor Yellow
    $certs = Get-ChildItem -Path Cert:\LocalMachine -Recurse | Where-Object { $_.PSIsContainer -eq $false }
    $results = @()
    foreach ($cert in $certs) {
        $results += [PSCustomObject]@{
            Subject = $cert.Subject
            Issuer = $cert.Issuer
            Thumbprint = $cert.Thumbprint
            NotBefore = $cert.NotBefore
            NotAfter = $cert.NotAfter
            Store = $cert.PSParentPath.Split('\')[-1]
            HasPrivateKey = $cert.HasPrivateKey
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks for expiring certificates.

.OUTPUTS
Array of PSObjects containing expiring certificate details.
#>
function Check-ExpiringCertificates {
    Write-Host "`nChecking for Expiring Certificates..." -ForegroundColor Yellow
    $expirationThreshold = (Get-Date).AddDays(30)
    $certs = Get-ChildItem -Path Cert:\LocalMachine -Recurse | Where-Object { $_.PSIsContainer -eq $false -and $_.NotAfter -le $expirationThreshold }
    $results = @()
    foreach ($cert in $certs) {
        $results += [PSCustomObject]@{
            Subject = $cert.Subject
            Thumbprint = $cert.Thumbprint
            ExpirationDate = $cert.NotAfter
            DaysUntilExpiration = ($cert.NotAfter - (Get-Date)).Days
            Store = $cert.PSParentPath.Split('\')[-1]
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes IIS binding certificates.

.OUTPUTS
Array of PSObjects containing IIS binding certificate details.
#>
function Analyze-IISBindingCertificates {
    Write-Host "`nAnalyzing IIS Binding Certificates..." -ForegroundColor Yellow
    $results = @()
    if (Get-Module -ListAvailable -Name WebAdministration) {
        $websites = Get-Website
        foreach ($site in $websites) {
            $bindings = $site.Bindings.Collection | Where-Object { $_.Protocol -eq "https" }
            foreach ($binding in $bindings) {
                $cert = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq $binding.CertificateHash }
                if ($cert) {
                    $results += [PSCustomObject]@{
                        Website = $site.Name
                        Binding = $binding.BindingInformation
                        CertSubject = $cert.Subject
                        Thumbprint = $cert.Thumbprint
                        ExpirationDate = $cert.NotAfter
                        DaysUntilExpiration = ($cert.NotAfter - (Get-Date)).Days
                    }
                }
            }
        }
    } else {
        Write-Host "WebAdministration module not available. Unable to analyze IIS bindings." -ForegroundColor Red
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks for certificates with weak keys.

.OUTPUTS
Array of PSObjects containing weak key certificate details.
#>
function Check-WeakKeyCertificates {
    Write-Host "`nChecking for Weak Key Certificates..." -ForegroundColor Yellow
    $certs = Get-ChildItem -Path Cert:\LocalMachine -Recurse | Where-Object { $_.PSIsContainer -eq $false }
    $results = @()
    foreach ($cert in $certs) {
        if ($cert.PublicKey.Key.KeySize -lt 2048) {
            $results += [PSCustomObject]@{
                Subject = $cert.Subject
                Thumbprint = $cert.Thumbprint
                KeySize = $cert.PublicKey.Key.KeySize
                Store = $cert.PSParentPath.Split('\')[-1]
            }
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes certificate chains.

.OUTPUTS
Array of PSObjects containing certificate chain details.
#>
function Analyze-CertificateChain {
    Write-Host "`nAnalyzing Certificate Chain..." -ForegroundColor Yellow
    $certs = Get-ChildItem -Path Cert:\LocalMachine -Recurse | Where-Object { $_.PSIsContainer -eq $false }
    $results = @()
    foreach ($cert in $certs) {
        $chain = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Chain
        $chain.Build($cert) | Out-Null
        $chainStatus = $chain.ChainStatus | ForEach-Object { $_.Status }
        $results += [PSCustomObject]@{
            Subject = $cert.Subject
            Thumbprint = $cert.Thumbprint
            ChainValid = $chain.ChainStatus.Length -eq 0
            ChainStatus = if ($chainStatus) { $chainStatus -join ", " } else { "Valid" }
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks for duplicate certificates.

.OUTPUTS
Array of PSObjects containing duplicate certificate details.
#>
function Check-DuplicateCertificates {
    Write-Host "`nChecking for Duplicate Certificates..." -ForegroundColor Yellow
    $certs = Get-ChildItem -Path Cert:\LocalMachine -Recurse | Where-Object { $_.PSIsContainer -eq $false }
    $duplicates = $certs | Group-Object -Property Thumbprint | Where-Object { $_.Count -gt 1 }
    $results = @()
    foreach ($duplicate in $duplicates) {
        foreach ($cert in $duplicate.Group) {
            $results += [PSCustomObject]@{
                Subject = $cert.Subject
                Thumbprint = $cert.Thumbprint
                Store = $cert.PSParentPath.Split('\')[-1]
                NotAfter = $cert.NotAfter
            }
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes certificate usage.

.OUTPUTS
Array of PSObjects containing certificate usage details.
#>
function Analyze-CertificateUsage {
    Write-Host "`nAnalyzing Certificate Usage..." -ForegroundColor Yellow
    $certs = Get-ChildItem -Path Cert:\LocalMachine -Recurse | Where-Object { $_.PSIsContainer -eq $false }
    $results = @()
    foreach ($cert in $certs) {
        $enhancedKeyUsage = $cert.EnhancedKeyUsageList | ForEach-Object { $_.FriendlyName }
        $results += [PSCustomObject]@{
            Subject = $cert.Subject
            Thumbprint = $cert.Thumbprint
            KeyUsage = $cert.KeyUsages -join ", "
            EnhancedKeyUsage = if ($enhancedKeyUsage) { $enhancedKeyUsage -join ", " } else { "Not specified" }
        }
    }
    $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>Certificates 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>Certificates Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>All Certificates</h2>
    $($AllResults.AllCertificates | ConvertTo-Html -Fragment)

    <h2>Expiring Certificates</h2>
    $($AllResults.ExpiringCertificates | ConvertTo-Html -Fragment)

    <h2>IIS Binding Certificates</h2>
    $($AllResults.IISBindingCertificates | ConvertTo-Html -Fragment)

    <h2>Weak Key Certificates</h2>
    $($AllResults.WeakKeyCertificates | ConvertTo-Html -Fragment)

    <h2>Certificate Chain Analysis</h2>
    $($AllResults.CertificateChain | ConvertTo-Html -Fragment)

    <h2>Duplicate Certificates</h2>
    $($AllResults.DuplicateCertificates | ConvertTo-Html -Fragment)

    <h2>Certificate Usage</h2>
    $($AllResults.CertificateUsage | 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.AllCertificates = Analyze-AllCertificates }
        "2" { $allResults.ExpiringCertificates = Check-ExpiringCertificates }
        "3" { $allResults.IISBindingCertificates = Analyze-IISBindingCertificates }
        "4" { $allResults.WeakKeyCertificates = Check-WeakKeyCertificates }
        "5" { $allResults.CertificateChain = Analyze-CertificateChain }
        "6" { $allResults.DuplicateCertificates = Check-DuplicateCertificates }
        "7" { $allResults.CertificateUsage = Analyze-CertificateUsage }
        "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 Certificates Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of certificates:
    • Analysis of all certificates in the Local Machine store
    • Check for expiring certificates
    • Analysis of IIS binding certificates
    • Check for weak key certificates
    • Analysis of certificate chains
    • Check for duplicate certificates
    • Analysis of certificate usage
  3. Comprehensive error handling for each analysis function.
  4. A function to generate an HTML report of all collected data.

Key features:

  • Detailed analysis of all certificates in the Local Machine store
  • Identification of certificates nearing expiration
  • Review of certificates used in IIS bindings
  • Detection of certificates with weak keys
  • Analysis of certificate chains for validity
  • Identification of duplicate certificates across stores
  • Examination of certificate usage and purposes
  • Comprehensive HTML report generation

This tool is particularly useful for:

  • System administrators managing certificates
  • Security professionals auditing certificate deployments
  • IT professionals troubleshooting certificate-related issues
  • DevOps engineers managing SSL/TLS certificates

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to access certificate stores
  3. Have the WebAdministration module available if you want to analyze IIS certificates

This script provides a comprehensive overview of certificates on a Windows system, making it easier to audit and maintain certificate deployments, identify potential issues, and ensure the security of SSL/TLS implementations.

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 *