Headlines

SCCM Health Check PowerShell Script: Complete MECM Audit Tool 2025

This SCCM health check PowerShell script provides a complete audit of your Microsoft Endpoint Configuration Manager environment..

In the previous article i have explained how to solve the issue of SCCM server stuck at Checking Prerequisites during update of the branch or version where administrator needs to check date of release and delete records from the database and recheck updates again. Here you will be learning, how to perform your server health check using PowerShell with an executive and impressive html report.

This script is clean and usable in production environment.

Copy the below script

# ==========================================================
# MSERVERPRO – SCCM HEALTH CHECK REPORT v3.0
# Author: Habib
# Practice: Infrastructure & EUC Practice
# Company: MServerPro
# ==========================================================

# ===================== CONFIGURATION ======================
param(
    [switch]$OpenReport
)

$CompanyInfo = @{
    Name = "MServerPro"
    Practice = "Infrastructure & EUC Practice"
    Author = "Habib"
    Version = "3.1"
    SupportEmail = "habibnp01@gmail.com"
}

# Performance Thresholds
$Thresholds = @{
    CPU_Green = 60
    CPU_Yellow = 80
    MEM_Green = 70
    MEM_Yellow = 85
    DISK_Green = 20
    DISK_Yellow = 10
    MaxUptimeDays = 90
}

# ===================== USER INTERFACE FUNCTIONS ======================
function Show-ScriptHeader {
    Clear-Host
    Write-Host "`n" + "="*60 -ForegroundColor Cyan
    Write-Host "  SCCM HEALTH CHECK REPORT GENERATOR v$($CompanyInfo.Version)" -ForegroundColor Cyan
    Write-Host "  Company: $($CompanyInfo.Name)" -ForegroundColor Yellow
    Write-Host "  Practice: $($CompanyInfo.Practice)" -ForegroundColor Yellow
    Write-Host "  Author: $($CompanyInfo.Author)" -ForegroundColor Yellow
    Write-Host "="*60 -ForegroundColor Cyan
    Write-Host "`n"
}

function Get-UserInput {
    param(
        [string]$Title,
        [string]$Message,
        [string]$DefaultValue = "",
        [switch]$Password
    )
    
    Show-ScriptHeader
    Write-Host " $Title" -ForegroundColor Green
    Write-Host " " + ("-" * ($Title.Length + 2)) -ForegroundColor Green
    
    if ($Password) {
        $secureInput = Read-Host " $Message" -AsSecureString
        $inputValue = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureInput))
    } else {
        if ($DefaultValue) {
            $inputValue = Read-Host " $Message" -DefaultValue $DefaultValue
        } else {
            $inputValue = Read-Host " $Message"
        }
    }
    
    return $inputValue
}

function Show-Progress {
    param(
        [string]$Message,
        [string]$Status = "Processing..."
    )
    
    Write-Host "`n [$Status]" -ForegroundColor Cyan -NoNewline
    Write-Host " $Message" -ForegroundColor White
}

function Show-Success {
    param([string]$Message)
    Write-Host "   [✓] " -ForegroundColor Green -NoNewline
    Write-Host $Message -ForegroundColor White
}

function Show-Warning {
    param([string]$Message)
    Write-Host "   [!] " -ForegroundColor Yellow -NoNewline
    Write-Host $Message -ForegroundColor White
}

function Show-Error {
    param([string]$Message)
    Write-Host "   [✗] " -ForegroundColor Red -NoNewline
    Write-Host $Message -ForegroundColor White
}

function Get-SCCMCredentials {
    Show-ScriptHeader
    Write-Host " CREDENTIALS REQUIRED" -ForegroundColor Green
    Write-Host " --------------------" -ForegroundColor Green
    Write-Host "`n To perform SCCM health checks, you need administrative credentials." -ForegroundColor Yellow
    Write-Host " Please enter credentials with SCCM administrator privileges." -ForegroundColor Yellow
    Write-Host ""
    
    $username = Get-UserInput -Title "CREDENTIALS" -Message "Enter username (DOMAIN\Username):"
    $password = Get-UserInput -Title "CREDENTIALS" -Message "Enter password:" -Password
    
    if ([string]::IsNullOrEmpty($username) -or [string]::IsNullOrEmpty($password)) {
        Show-Error "Credentials are required to continue."
        return $null
    }
    
    try {
        $securePassword = ConvertTo-SecureString $password -AsPlainText -Force
        $credential = New-Object System.Management.Automation.PSCredential($username, $securePassword)
        Show-Success "Credentials captured successfully"
        return $credential
    }
    catch {
        Show-Error "Failed to create credentials object: $($_.Exception.Message)"
        return $null
    }
}

function Get-SCCMServerInfo {
    Show-ScriptHeader
    Write-Host " SCCM SERVER INFORMATION" -ForegroundColor Green
    Write-Host " -----------------------" -ForegroundColor Green
    Write-Host "`n Please provide information about your SCCM environment." -ForegroundColor Yellow
    Write-Host ""
    
    # Get SCCM Server Name
    $sccmServer = Get-UserInput -Title "SCCM SERVER" -Message "Enter SCCM Primary Server Name:" -DefaultValue $env:COMPUTERNAME
    
    # Get SMS Provider
    $smsProvider = Get-UserInput -Title "SMS PROVIDER" -Message "Enter SMS Provider Server Name:" -DefaultValue $sccmServer
    
    # Get Site Code (try to detect automatically)
    Show-Progress "Attempting to detect SCCM site code..."
    $siteCode = $null
    try {
        # Try to read from registry
        $regPath = "HKLM:\SOFTWARE\Microsoft\SMS\Identification"
        if (Test-Path $regPath) {
            $siteCode = (Get-ItemProperty -Path $regPath -Name "Site Code" -ErrorAction SilentlyContinue)."Site Code"
            if ($siteCode) {
                Show-Success "Detected site code from registry: $siteCode"
            }
        }
    } catch {}
    
    if (-not $siteCode) {
        $siteCode = Get-UserInput -Title "SITE CODE" -Message "Enter SCCM Site Code (3 characters):"
        if ($siteCode.Length -ne 3) {
            Show-Warning "Site code should typically be 3 characters (e.g., ABC, XYZ)"
        }
    }
    
    # Get Output Path
    $defaultOutput = "C:\Reports\SCCMHealth_$(Get-Date -Format 'yyyyMMdd')"
    $outputPath = Get-UserInput -Title "REPORT LOCATION" -Message "Enter output directory for reports:" -DefaultValue $defaultOutput
    
    return @{
        SCCMServer = $sccmServer
        SMSProvider = $smsProvider
        SiteCode = $siteCode
        OutputPath = $outputPath
    }
}

# ===================== INITIALIZATION ======================
function Initialize-Script {
    param($OutputPath)
    
    Show-Progress "Initializing SCCM Health Check..."
    
    # Create output directory
    if (!(Test-Path $OutputPath)) {
        try {
            New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null
            Show-Success "Created output directory: $OutputPath"
        }
        catch {
            Show-Error "Failed to create output directory: $($_.Exception.Message)"
            return $false
        }
    } else {
        Show-Success "Output directory already exists: $OutputPath"
    }
    
    # Import required modules
    Show-Progress "Checking for required PowerShell modules..."
    
    # Check for CimCmdlets module
    if (-not (Get-Module -Name CimCmdlets -ListAvailable)) {
        Show-Error "CimCmdlets module is not available. This module is required for SCCM health checks."
        Write-Host "`n Please install the module using:" -ForegroundColor Yellow
        Write-Host "   Install-WindowsFeature -Name RSAT" -ForegroundColor White
        return $false
    } else {
        Show-Success "CimCmdlets module is available"
    }
    
    try {
        Import-Module -Name CimCmdlets -ErrorAction Stop -Force
        Show-Success "Imported required modules"
        return $true
    }
    catch {
        Show-Error "Failed to import required modules: $($_.Exception.Message)"
        return $false
    }
}

# ===================== HTML FUNCTIONS ======================
function Get-HTMLHeader {
    param($HostName, $SCCMServer, $SiteCode)
    
    $ReportDate = Get-Date -Format "dddd, MMMM dd, yyyy"
    $ReportTime = Get-Date -Format "HH:mm:ss"
    
    return @"
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SCCM Health Check Report - $HostName</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #f5f7fa;
            color: #333;
            line-height: 1.6;
            padding: 20px;
        }
        .container {
            max-width: 1400px;
            margin: 0 auto;
        }
        .report-header {
            background: linear-gradient(135deg, #0b5394 0%, #083e6b 100%);
            color: white;
            padding: 30px;
            border-radius: 10px;
            margin-bottom: 30px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        }
        .company-info {
            margin-bottom: 15px;
        }
        .company-name {
            font-size: 1.8rem;
            font-weight: 700;
            color: white;
        }
        .company-practice {
            font-size: 1rem;
            opacity: 0.9;
            font-style: italic;
        }
        .report-title {
            font-size: 2.2rem;
            font-weight: 600;
            margin: 10px 0;
            color: white;
        }
        .report-meta {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
            margin-top: 25px;
            background: rgba(255, 255, 255, 0.1);
            padding: 20px;
            border-radius: 8px;
        }
        .meta-item {
            display: flex;
            flex-direction: column;
        }
        .meta-label {
            font-size: 0.85rem;
            opacity: 0.9;
            text-transform: uppercase;
            letter-spacing: 0.5px;
            margin-bottom: 5px;
        }
        .meta-value {
            font-size: 1.1rem;
            font-weight: 600;
        }
        .card {
            background: white;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            margin-bottom: 25px;
            overflow: hidden;
            border: 1px solid #dee2e6;
        }
        .card-header {
            background: linear-gradient(to right, #e6f2ff, white);
            padding: 15px 20px;
            border-bottom: 2px solid #dee2e6;
        }
        .card-header h2 {
            margin: 0;
            color: #0b5394;
            font-size: 1.3rem;
            font-weight: 600;
        }
        .card-body {
            padding: 20px;
        }
        .summary-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            margin: 20px 0;
        }
        .summary-card {
            text-align: center;
            padding: 25px;
            border-radius: 8px;
            background: white;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            border-top: 4px solid;
            transition: transform 0.3s ease;
        }
        .summary-card:hover {
            transform: translateY(-5px);
        }
        .summary-card.total { border-top-color: #0b5394; }
        .summary-card.healthy { border-top-color: #28a745; }
        .summary-card.warning { border-top-color: #ffc107; }
        .summary-card.critical { border-top-color: #dc3545; }
        .summary-card .count {
            font-size: 2.5rem;
            font-weight: 700;
            margin: 10px 0;
        }
        .summary-card.total .count { color: #0b5394; }
        .summary-card.healthy .count { color: #28a745; }
        .summary-card.warning .count { color: #ffc107; }
        .summary-card.critical .count { color: #dc3545; }
        .summary-card .label {
            font-size: 0.9rem;
            color: #6c757d;
            text-transform: uppercase;
            letter-spacing: 1px;
        }
        .data-table {
            width: 100%;
            border-collapse: collapse;
            font-size: 0.95rem;
        }
        .data-table th {
            background-color: #e9ecef;
            color: #495057;
            font-weight: 600;
            padding: 12px 15px;
            text-align: left;
            border-bottom: 2px solid #dee2e6;
        }
        .data-table td {
            padding: 10px 15px;
            border-bottom: 1px solid #dee2e6;
            vertical-align: middle;
        }
        .data-table tr:hover {
            background-color: #f8f9fa;
        }
        .status {
            display: inline-block;
            padding: 4px 12px;
            border-radius: 20px;
            font-size: 0.8rem;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }
        .status-ok {
            background-color: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }
        .status-warning {
            background-color: #fff3cd;
            color: #856404;
            border: 1px solid #ffeaa7;
        }
        .status-critical {
            background-color: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }
        .progress-container {
            width: 100%;
            background-color: #e9ecef;
            border-radius: 10px;
            overflow: hidden;
            height: 20px;
        }
        .progress-bar {
            height: 100%;
            border-radius: 10px;
            transition: width 0.3s ease;
        }
        .progress-cpu {
            background: linear-gradient(90deg, #28a745, #17a2b8);
        }
        .progress-memory {
            background: linear-gradient(90deg, #28a745, #ffc107);
        }
        .progress-disk {
            background: linear-gradient(90deg, #28a745, #dc3545);
        }
        .recommendation {
            background: #f8f9fa;
            border-left: 4px solid #0b5394;
            padding: 15px;
            margin: 10px 0;
            border-radius: 4px;
        }
        .recommendation h4 {
            color: #0b5394;
            margin-bottom: 8px;
        }
        .report-footer {
            background: #343a40;
            color: white;
            padding: 25px;
            margin-top: 40px;
            border-radius: 8px;
            text-align: center;
        }
        .company-footer {
            margin-bottom: 15px;
            font-size: 1.1rem;
            font-weight: 600;
            color: #ffc107;
        }
        @media print {
            body { background: white; }
            .card { box-shadow: none; border: 1px solid #ddd; }
            .report-footer { background: white; color: black; border-top: 2px solid #ddd; }
        }
    </style>
</head>
<body>
<div class="container">
<div class="report-header">
    <div class="company-info">
        <div class="company-name">$($CompanyInfo.Name)</div>
        <div class="company-practice">$($CompanyInfo.Practice)</div>
    </div>
    <div class="report-title">SCCM Health Check Report</div>
    <div class="author-info">Prepared by: $($CompanyInfo.Author) | Version: $($CompanyInfo.Version)</div>
    <div class="report-meta">
        <div class="meta-item">
            <div class="meta-label">SCCM Server</div>
            <div class="meta-value">$SCCMServer</div>
        </div>
        <div class="meta-item">
            <div class="meta-label">Site Code</div>
            <div class="meta-value">$SiteCode</div>
        </div>
        <div class="meta-item">
            <div class="meta-label">Report Date</div>
            <div class="meta-value">$ReportDate</div>
        </div>
        <div class="meta-item">
            <div class="meta-label">Report Time</div>
            <div class="meta-value">$ReportTime</div>
        </div>
        <div class="meta-item">
            <div class="meta-label">Generated From</div>
            <div class="meta-value">$HostName</div>
        </div>
    </div>
</div>
"@
}

function Get-HTMLFooter {
    return @"
<div class="report-footer">
    <div class="container">
        <div class="company-footer">$($CompanyInfo.Name)</div>
        <small>Report generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | SCCM Health Check v$($CompanyInfo.Version)</small><br>
        <small>Prepared by: $($CompanyInfo.Author) | $($CompanyInfo.Practice)</small><br>
        <small>Contact: $($CompanyInfo.SupportEmail)</small><br>
        <small>This report contains confidential information for authorized personnel only.</small>
    </div>
</div>
<script>
    // Interactive features
    document.addEventListener('DOMContentLoaded', function() {
        // Highlight critical rows
        document.querySelectorAll('.status-critical').forEach(element => {
            const row = element.closest('tr');
            if (row) {
                row.style.backgroundColor = 'rgba(220, 53, 69, 0.05)';
            }
        });
        
        // Toggle recommendations on mobile
        if (window.innerWidth <= 768) {
            document.querySelectorAll('.card-header').forEach(header => {
                header.style.cursor = 'pointer';
                header.addEventListener('click', function() {
                    const cardBody = this.nextElementSibling;
                    cardBody.style.display = cardBody.style.display === 'none' ? 'block' : 'none';
                });
            });
        }
    });
</script>
</body>
</html>
"@
}

# ===================== HEALTH CHECK FUNCTIONS ======================
function Get-ServerPerformance {
    param($ComputerName, $Credential)
    
    Show-Progress "Checking server performance metrics..." -Status "PERFORMANCE"
    
    try {
        # CPU Usage
        Show-Progress "Checking CPU utilization..." -Status "CPU"
        $CPU = [math]::Round((Get-Counter '\Processor(_Total)\% Processor Time' -ComputerName $ComputerName -ErrorAction Stop).CounterSamples.CookedValue, 2)
        
        # Memory Usage
        Show-Progress "Checking memory utilization..." -Status "MEMORY"
        $OS = Get-CimInstance Win32_OperatingSystem -ComputerName $ComputerName -ErrorAction Stop
        $TotalMemoryGB = [math]::Round($OS.TotalVisibleMemorySize / 1GB, 2)
        $FreeMemoryGB = [math]::Round($OS.FreePhysicalMemory / 1GB, 2)
        $UsedMemoryGB = $TotalMemoryGB - $FreeMemoryGB
        
        # Calculate memory usage percentage
        if ($TotalMemoryGB -gt 0) {
            $MemUsage = [math]::Round(($UsedMemoryGB / $TotalMemoryGB) * 100, 2)
        } else {
            $MemUsage = 0
            Show-Warning "Could not calculate memory percentage accurately"
        }
        
        # Disk Usage
        Show-Progress "Checking disk usage..." -Status "DISK"
        $Disks = @()
        $DiskDrives = Get-CimInstance Win32_LogicalDisk -ComputerName $ComputerName -Filter "DriveType=3" -ErrorAction Stop
        
        foreach ($Disk in $DiskDrives) {
            $FreeGB = [math]::Round($Disk.FreeSpace / 1GB, 2)
            $TotalGB = [math]::Round($Disk.Size / 1GB, 2)
            if ($TotalGB -gt 0) {
                $FreePct = [math]::Round(($FreeGB / $TotalGB) * 100, 2)
            } else {
                $FreePct = 0
            }
            
            $Disks += [PSCustomObject]@{
                Drive = $Disk.DeviceID
                Label = $Disk.VolumeName
                TotalGB = $TotalGB
                FreeGB = $FreeGB
                FreePct = $FreePct
                DiskStatus = if ($FreePct -ge $Thresholds.DISK_Green) { "Healthy" }
                            elseif ($FreePct -ge $Thresholds.DISK_Yellow) { "Warning" }
                            else { "Critical" }
            }
        }
        
        # Uptime
        Show-Progress "Checking system uptime..." -Status "UPTIME"
        $LastBoot = $OS.LastBootUpTime
        $UptimeDays = (New-TimeSpan -Start $LastBoot -End (Get-Date)).Days
        $UptimeHours = (New-TimeSpan -Start $LastBoot -End (Get-Date)).Hours
        
        # Determine status
        $CPUStatus = if ($CPU -le $Thresholds.CPU_Green) { "Healthy" }
                    elseif ($CPU -le $Thresholds.CPU_Yellow) { "Warning" }
                    else { "Critical" }
        
        $MemStatus = if ($MemUsage -le $Thresholds.MEM_Green) { "Healthy" }
                    elseif ($MemUsage -le $Thresholds.MEM_Yellow) { "Warning" }
                    else { "Critical" }
        
        Show-Success "CPU: $CPU% ($CPUStatus)"
        Show-Success "Memory: $MemUsage% ($MemStatus)"
        Show-Success "Uptime: $UptimeDays days, $UptimeHours hours"
        
        return [PSCustomObject]@{
            CPU = $CPU
            CPUStatus = $CPUStatus
            Memory = $MemUsage
            MemStatus = $MemStatus
            TotalMemoryGB = $TotalMemoryGB
            UsedMemoryGB = $UsedMemoryGB
            FreeMemoryGB = $FreeMemoryGB
            Disks = $Disks
            UptimeDays = $UptimeDays
            UptimeHours = $UptimeHours
            LastBoot = $LastBoot
        }
    }
    catch {
        Show-Error "Failed to get server performance: $($_.Exception.Message)"
        return $null
    }
}

function Get-SCCMComponents {
    param($CimSession, $SiteCode)
    
    Show-Progress "Checking SCCM components..." -Status "COMPONENTS"
    
    try {
        $Components = Get-CimInstance -CimSession $CimSession `
            -Namespace "root\sms\site_$SiteCode" `
            -ClassName SMS_ComponentSummarizer `
            -ErrorAction Stop |
            Group-Object ComponentName |
            ForEach-Object {
                $maxStatus = ($_.Group | Measure-Object Status -Maximum).Maximum
                [PSCustomObject]@{
                    Component = $_.Name
                    Status = $maxStatus
                    StatusText = switch ($maxStatus) {
                        0 { "Healthy"; break }
                        1 { "Warning"; break }
                        2 { "Critical"; break }
                        default { "Unknown" }
                    }
                    StatusClass = switch ($maxStatus) {
                        0 { "status-ok"; break }
                        1 { "status-warning"; break }
                        2 { "status-critical"; break }
                        default { "status-warning" }
                    }
                }
            }
        
        Show-Success "Found $($Components.Count) SCCM components"
        
        return $Components
    }
    catch {
        Show-Error "Failed to get SCCM components: $($_.Exception.Message)"
        return $null
    }
}

function Get-SCCMServices {
    param($ComputerName, $Credential)
    
    Show-Progress "Checking SCCM services..." -Status "SERVICES"
    
    $Services = @(
        @{Name="SMS_EXECUTIVE"; DisplayName="SMS Executive"; Critical=$true},
        @{Name="SMS_SITE_COMPONENT_MANAGER"; DisplayName="Site Component Manager"; Critical=$true},
        @{Name="SMS_NOTIFICATION_SERVER"; DisplayName="Notification Server"; Critical=$true},
        @{Name="SMS_SQL_MONITOR"; DisplayName="SQL Monitor"; Critical=$true},
        @{Name="CmRcService"; DisplayName="SMS Agent Host"; Critical=$false},
        @{Name="wuauserv"; DisplayName="Windows Update"; Critical=$false},
        @{Name="BITS"; DisplayName="Background Intelligent Transfer"; Critical=$false},
        @{Name="Winmgmt"; DisplayName="Windows Management Instrumentation"; Critical=$true}
    )
    
    $ServiceResults = @()
    
    foreach ($svc in $Services) {
        try {
            $Service = Get-Service -ComputerName $ComputerName -Name $svc.Name -ErrorAction Stop
            
            $status = if ($Service.Status -eq "Running") { "Running" } else { "Stopped" }
            $statusClass = if ($Service.Status -eq "Running") { "status-ok" } else { 
                if ($svc.Critical) { "status-critical" } else { "status-warning" }
            }
            
            $ServiceResults += [PSCustomObject]@{
                Name = $svc.DisplayName
                ServiceName = $svc.Name
                Status = $status
                StatusClass = $statusClass
                Critical = $svc.Critical
            }
            
            if ($Service.Status -eq "Running") {
                Show-Success "$($svc.DisplayName): Running"
            } else {
                if ($svc.Critical) {
                    Show-Error "$($svc.DisplayName): Stopped (CRITICAL)"
                } else {
                    Show-Warning "$($svc.DisplayName): Stopped"
                }
            }
        }
        catch {
            Show-Warning "$($svc.DisplayName): Not found"
            $ServiceResults += [PSCustomObject]@{
                Name = $svc.DisplayName
                ServiceName = $svc.Name
                Status = "Not Found"
                StatusClass = "status-warning"
                Critical = $svc.Critical
            }
        }
    }
    
    return $ServiceResults
}

function Get-SCCMDatabaseInfo {
    param($CimSession, $SiteCode)
    
    Show-Progress "Checking SCCM database information..." -Status "DATABASE"
    
    try {
        # Method 1: Try to get database info from SMS_Site class
        $DatabaseInfo = Get-CimInstance -CimSession $CimSession `
            -Namespace "root\sms\site_$SiteCode" `
            -ClassName SMS_Site `
            -ErrorAction Stop
        
        if ($DatabaseInfo) {
            # Create a custom object with the correct properties
            $dbInfo = [PSCustomObject]@{
                SiteCode = $DatabaseInfo.SiteCode
                Version = $DatabaseInfo.Version
                DatabaseName = $DatabaseInfo.DatabaseName
                DatabaseServer = $DatabaseInfo.ServerName
                ReportingServer = $DatabaseInfo.ReportingServerName
                ReportingDatabase = $DatabaseInfo.ReportingDatabaseName
            }
            
            Show-Success "Site Code: $($dbInfo.SiteCode)"
            Show-Success "SCCM Version: $($dbInfo.Version)"
            
            if ($dbInfo.DatabaseServer -and $dbInfo.DatabaseName) {
                Show-Success "Database: $($dbInfo.DatabaseName) on $($dbInfo.DatabaseServer)"
            } else {
                Show-Warning "Could not retrieve complete database information"
            }
            
            if ($dbInfo.ReportingServer) {
                Show-Success "Reporting: $($dbInfo.ReportingDatabase) on $($dbInfo.ReportingServer)"
            }
            
            return $dbInfo
        }
        
        return $null
    }
    catch {
        Show-Warning "Could not retrieve database information: $($_.Exception.Message)"
        
        # Fallback: Try to get basic site info using alternative method
        try {
            $SiteInfo = Get-CimInstance -CimSession $CimSession `
                -Namespace "root\sms\site_$SiteCode" `
                -ClassName SMS_Identification `
                -ErrorAction Stop
            
            if ($SiteInfo) {
                $dbInfo = [PSCustomObject]@{
                    SiteCode = $SiteInfo.SiteCode
                    Version = $SiteInfo.SMSVersion
                    DatabaseName = "Unknown"
                    DatabaseServer = "Unknown"
                    ReportingServer = "Unknown"
                    ReportingDatabase = "Unknown"
                }
                
                Show-Success "Site Code: $($dbInfo.SiteCode)"
                Show-Success "SCCM Version: $($dbInfo.Version)"
                Show-Warning "Could not retrieve database server details"
                
                return $dbInfo
            }
        }
        catch {
            # Last resort: Create minimal info object
            $dbInfo = [PSCustomObject]@{
                SiteCode = $SiteCode
                Version = "Unknown"
                DatabaseName = "Unknown"
                DatabaseServer = "Unknown"
                ReportingServer = "Unknown"
                ReportingDatabase = "Unknown"
            }
            
            Show-Success "Site Code: $SiteCode"
            Show-Warning "SCCM Version: Unknown"
            
            return $dbInfo
        }
    }
}

function Test-SCCMConnectivity {
    param($SCCMServer, $Credential)
    
    Show-Progress "Testing connectivity to SCCM server..." -Status "CONNECTIVITY"
    
    # Test basic network connectivity
    try {
        if (Test-Connection -ComputerName $SCCMServer -Count 2 -Quiet -ErrorAction Stop) {
            Show-Success "Network connectivity: SUCCESS"
        } else {
            Show-Error "Network connectivity: FAILED"
            return $false
        }
    }
    catch {
        Show-Error "Network connectivity test failed: $($_.Exception.Message)"
        return $false
    }
    
    # Test WinRM connectivity
    try {
        $session = New-PSSession -ComputerName $SCCMServer -Credential $Credential -ErrorAction Stop
        Remove-PSSession $session
        Show-Success "WinRM connectivity: SUCCESS"
        return $true
    }
    catch {
        Show-Warning "WinRM connectivity test failed. Trying alternative methods..."
        
        # Try alternative connectivity methods
        try {
            # Try CIM connection
            $cim = New-CimSession -ComputerName $SCCMServer -Credential $Credential -ErrorAction Stop
            Remove-CimSession $cim
            Show-Success "CIM connectivity: SUCCESS"
            return $true
        }
        catch {
            Show-Error "All connectivity tests failed. Please verify:"
            Show-Error "  1. Server name is correct"
            Show-Error "  2. Credentials have administrative privileges"
            Show-Error "  3. WinRM is enabled on the SCCM server"
            return $false
        }
    }
}

# ===================== MAIN EXECUTION ======================
try {
    # Show script header
    Show-ScriptHeader
    
    # Step 1: Get SCCM Server Information
    Write-Host "`n STEP 1: SCCM SERVER CONFIGURATION" -ForegroundColor Green
    Write-Host " ----------------------------------" -ForegroundColor Green
    $serverInfo = Get-SCCMServerInfo
    
    if (-not $serverInfo) {
        Show-Error "Server information is required to continue."
        exit 1
    }
    
    $SCCMServer = $serverInfo.SCCMServer
    $SMSProvider = $serverInfo.SMSProvider
    $SiteCode = $serverInfo.SiteCode.ToUpper()
    $OutputPath = $serverInfo.OutputPath
    
    # Step 2: Get Credentials
    Write-Host "`n STEP 2: CREDENTIALS" -ForegroundColor Green
    Write-Host " --------------------" -ForegroundColor Green
    $Credential = Get-SCCMCredentials
    
    if (-not $Credential) {
        Show-Error "Credentials are required to continue."
        exit 1
    }
    
    # Step 3: Initialize Script
    Write-Host "`n STEP 3: INITIALIZATION" -ForegroundColor Green
    Write-Host " -----------------------" -ForegroundColor Green
    if (-not (Initialize-Script -OutputPath $OutputPath)) {
        Show-Error "Initialization failed. Exiting."
        exit 1
    }
    
    # Step 4: Test Connectivity
    Write-Host "`n STEP 4: CONNECTIVITY TEST" -ForegroundColor Green
    Write-Host " --------------------------" -ForegroundColor Green
    if (-not (Test-SCCMConnectivity -SCCMServer $SCCMServer -Credential $Credential)) {
        Show-Error "Connectivity test failed. Exiting."
        exit 1
    }
    
    # Step 5: Run Health Checks
    Write-Host "`n STEP 5: RUNNING HEALTH CHECKS" -ForegroundColor Green
    Write-Host " ------------------------------" -ForegroundColor Green
    
    # Create CIM session for SCCM queries
    Show-Progress "Connecting to SCCM SMS Provider..." -Status "CONNECTING"
    try {
        $CimSession = New-CimSession -ComputerName $SMSProvider -Credential $Credential -ErrorAction Stop
        Show-Success "Connected to SCCM SMS Provider: $SMSProvider"
    }
    catch {
        Show-Error "Failed to connect to SCCM SMS Provider: $($_.Exception.Message)"
        Show-Error "Please verify the SMS Provider server name and credentials."
        exit 1
    }
    
    # Run comprehensive health checks
    $healthChecks = @()
    
    # 1. Server Performance
    $ServerPerf = Get-ServerPerformance -ComputerName $SCCMServer -Credential $Credential
    
    # 2. SCCM Components
    $Components = Get-SCCMComponents -CimSession $CimSession -SiteCode $SiteCode
    
    # 3. SCCM Services
    $Services = Get-SCCMServices -ComputerName $SCCMServer -Credential $Credential
    
    # 4. Database Info
    $DatabaseInfo = Get-SCCMDatabaseInfo -CimSession $CimSession -SiteCode $SiteCode
    
    # Calculate summary
    $CriticalComponents = if ($Components) { ($Components | Where-Object { $_.Status -eq 2 }).Count } else { 0 }
    $WarningComponents = if ($Components) { ($Components | Where-Object { $_.Status -eq 1 }).Count } else { 0 }
    $HealthyComponents = if ($Components) { ($Components | Where-Object { $_.Status -eq 0 }).Count } else { 0 }
    
    $StoppedServices = if ($Services) { ($Services | Where-Object { $_.Status -ne "Running" -and $_.Critical -eq $true }).Count } else { 0 }
    
    # Step 6: Generate Report
    Write-Host "`n STEP 6: GENERATING REPORT" -ForegroundColor Green
    Write-Host " --------------------------" -ForegroundColor Green
    
    $ReportFile = "$OutputPath\SCCM_HealthCheck_$SCCMServer`_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
    
    Show-Progress "Generating HTML report..." -Status "REPORT"
    
    # Start HTML content
    $HTML = Get-HTMLHeader -HostName $env:COMPUTERNAME -SCCMServer $SCCMServer -SiteCode $SiteCode
    
    # ================= EXECUTIVE SUMMARY =================
    $HTML += "<div class='card'><div class='card-header'><h2>Executive Summary</h2></div><div class='card-body'>"
    $HTML += "<p>This report provides a comprehensive health assessment of the SCCM environment at <strong>$SCCMServer</strong>.</p>"
    
    $HTML += "<div class='summary-grid'>"
    $HTML += "<div class='summary-card total'><div class='count'>$($Components.Count)</div><div class='label'>Total Components</div></div>"
    $HTML += "<div class='summary-card $(if($CriticalComponents -eq 0){'healthy'}else{'critical'})'><div class='count'>$CriticalComponents</div><div class='label'>Critical Components</div></div>"
    $HTML += "<div class='summary-card $(if($WarningComponents -eq 0){'healthy'}else{'warning'})'><div class='count'>$WarningComponents</div><div class='label'>Warning Components</div></div>"
    $HTML += "<div class='summary-card $(if($StoppedServices -eq 0){'healthy'}else{'critical'})'><div class='count'>$StoppedServices</div><div class='label'>Stopped Services</div></div>"
    $HTML += "</div>"
    
    $HTML += "<div class='recommendation'><h4>Key Findings</h4><ul>"
    
    if ($CriticalComponents -gt 0) { 
        $HTML += "<li><strong>CRITICAL:</strong> $CriticalComponents component(s) require immediate attention</li>" 
    }
    
    if ($WarningComponents -gt 0) { 
        $HTML += "<li><strong>WARNING:</strong> $WarningComponents component(s) need monitoring</li>" 
    }
    
    if ($StoppedServices -gt 0) { 
        $HTML += "<li><strong>CRITICAL:</strong> $StoppedServices critical service(s) are stopped</li>" 
    }
    
    if ($ServerPerf.CPUStatus -eq "Critical") { 
        $HTML += "<li><strong>PERFORMANCE:</strong> High CPU utilization detected</li>" 
    }
    
    if ($ServerPerf.MemStatus -eq "Critical") { 
        $HTML += "<li><strong>PERFORMANCE:</strong> High memory utilization detected</li>" 
    }
    
    $CriticalDisks = if ($ServerPerf.Disks) { ($ServerPerf.Disks | Where-Object { $_.DiskStatus -eq "Critical" }).Count } else { 0 }
    if ($CriticalDisks -gt 0) { 
        $HTML += "<li><strong>STORAGE:</strong> Critical disk space issues detected on $CriticalDisks drive(s)</li>" 
    }
    
    if ($CriticalComponents -eq 0 -and $WarningComponents -eq 0 -and $StoppedServices -eq 0) { 
        $HTML += "<li><strong>HEALTHY:</strong> No critical issues detected</li>" 
    }
    
    $HTML += "</ul></div></div></div>"

    # ================= SERVER PERFORMANCE =================
    if ($ServerPerf) {
        $HTML += "<div class='card'><div class='card-header'><h2>Server Performance</h2></div><div class='card-body'>"
        
        $HTML += "<h3>CPU & Memory Utilization</h3><table class='data-table'><thead><tr><th>Metric</th><th>Current Value</th><th>Status</th><th>Details</th></tr></thead><tbody>"
        
        # CPU Row
        $cpuStatusClass = if($ServerPerf.CPUStatus -eq "Healthy"){"status-ok"}elseif($ServerPerf.CPUStatus -eq "Warning"){"status-warning"}else{"status-critical"}
        $HTML += "<tr>
            <td><strong>CPU Utilization</strong></td>
            <td>
                <div class='progress-container'>
                    <div class='progress-bar progress-cpu' style='width: $($ServerPerf.CPU)%'></div>
                </div>
                <span>$($ServerPerf.CPU)%</span>
            </td>
            <td><span class='status $cpuStatusClass'>$($ServerPerf.CPUStatus)</span></td>
            <td>Threshold: &lt; $($Thresholds.CPU_Green)% (Green), &lt; $($Thresholds.CPU_Yellow)% (Yellow)</td>
        </tr>"
        
        # Memory Row
        $memStatusClass = if($ServerPerf.MemStatus -eq "Healthy"){"status-ok"}elseif($ServerPerf.MemStatus -eq "Warning"){"status-warning"}else{"status-critical"}
        $HTML += "<tr>
            <td><strong>Memory Utilization</strong></td>
            <td>
                <div class='progress-container'>
                    <div class='progress-bar progress-memory' style='width: $($ServerPerf.Memory)%'></div>
                </div>
                <span>$($ServerPerf.Memory)% ($($ServerPerf.UsedMemoryGB) GB of $($ServerPerf.TotalMemoryGB) GB)</span>
            </td>
            <td><span class='status $memStatusClass'>$($ServerPerf.MemStatus)</span></td>
            <td>Threshold: &lt; $($Thresholds.MEM_Green)% (Green), &lt; $($Thresholds.MEM_Yellow)% (Yellow)</td>
        </tr>"
        
        # Uptime Row
        $uptimeStatusClass = if($ServerPerf.UptimeDays -le $Thresholds.MaxUptimeDays){"status-ok"}else{"status-warning"}
        $uptimeStatusText = if($ServerPerf.UptimeDays -le $Thresholds.MaxUptimeDays){"OK"}else{"Warning"}
        $HTML += "<tr>
            <td><strong>System Uptime</strong></td>
            <td>$($ServerPerf.UptimeDays) days, $($ServerPerf.UptimeHours) hours</td>
            <td><span class='status $uptimeStatusClass'>$uptimeStatusText</span></td>
            <td>Last reboot: $($ServerPerf.LastBoot.ToString('yyyy-MM-dd HH:mm'))</td>
        </tr>"
        
        $HTML += "</tbody></table>"
        
        # Disk Usage
        if ($ServerPerf.Disks.Count -gt 0) {
            $HTML += "<h3>Disk Usage</h3><table class='data-table'><thead><tr><th>Drive</th><th>Label</th><th>Total Size</th><th>Free Space</th><th>Free %</th><th>Status</th></tr></thead><tbody>"
            
            foreach ($Disk in $ServerPerf.Disks) {
                $diskStatusClass = if($Disk.DiskStatus -eq "Healthy"){"status-ok"}elseif($Disk.DiskStatus -eq "Warning"){"status-warning"}else{"status-critical"}
                $usedPct = 100 - $Disk.FreePct
                
                $HTML += "<tr>
                    <td><strong>$($Disk.Drive)</strong></td>
                    <td>$($Disk.Label)</td>
                    <td>$($Disk.TotalGB) GB</td>
                    <td>$($Disk.FreeGB) GB</td>
                    <td>
                        <div class='progress-container'>
                            <div class='progress-bar progress-disk' style='width: $usedPct%'></div>
                        </div>
                        <span>$($Disk.FreePct)% free</span>
                    </td>
                    <td><span class='status $diskStatusClass'>$($Disk.DiskStatus)</span></td>
                </tr>"
            }
            
            $HTML += "</tbody></table>"
        }
        
        $HTML += "</div></div>"
    }
    
    # ================= SCCM COMPONENTS =================
    if ($Components) {
        $HTML += "<div class='card'><div class='card-header'><h2>SCCM Component Health</h2></div><div class='card-body'>"
        
        $HTML += "<p>Found $($Components.Count) SCCM components. Critical components are highlighted.</p>"
        $HTML += "<table class='data-table'><thead><tr><th>Component Name</th><th>Status</th><th>Recommendation</th></tr></thead><tbody>"
        
        # Sort by status (Critical first)
        $SortedComponents = $Components | Sort-Object @{Expression={$_.Status}; Descending=$true}
        
        foreach ($Comp in $SortedComponents) {
            $Recommendation = switch ($Comp.Status) {
                0 { "No action required" }
                1 { "Monitor component and review related logs" }
                2 { 
                    switch -Wildcard ($Comp.Component) {
                        "*WSUS*" { "Verify WSUS synchronization, IIS health, and review WCM.log, WsyncMgr.log" }
                        "*HIERARCHY*" { "Check site replication status and review hman.log" }
                        "*SITE_COMPONENT_MANAGER*" { "Review sitecomp.log and restart if necessary" }
                        "*DISTRIBUTION*" { "Check distribution points and content availability" }
                        "*SQL*" { "Verify SQL Server connectivity and performance" }
                        "*MP_*" { "Check Management Point connectivity and certificates" }
                        default { "Review component-specific logs for detailed error information" }
                    }
                }
            }
            
            $HTML += "<tr>
                <td>$($Comp.Component)</td>
                <td><span class='status $($Comp.StatusClass)'>$($Comp.StatusText)</span></td>
                <td>$Recommendation</td>
            </tr>"
        }
        
        $HTML += "</tbody></table></div></div>"
    }
    
    # ================= SCCM SERVICES =================
    if ($Services) {
        $HTML += "<div class='card'><div class='card-header'><h2>SCCM Services Status</h2></div><div class='card-body'>"
        
        $HTML += "<table class='data-table'><thead><tr><th>Service Name</th><th>Status</th><th>Critical</th><th>Action Required</th></tr></thead><tbody>"
        
        foreach ($Service in $Services) {
            $ActionRequired = if ($Service.Status -eq "Running") { 
                "No action required" 
            } else { 
                if ($Service.Critical) { 
                    "Immediate action required - restart service and investigate logs" 
                } else { 
                    "Monitor and restart if impacting functionality" 
                }
            }
            
            $criticalText = if($Service.Critical){"Yes"}else{"No"}
            
            $HTML += "<tr>
                <td><strong>$($Service.Name)</strong><br><small>$($Service.ServiceName)</small></td>
                <td><span class='status $($Service.StatusClass)'>$($Service.Status)</span></td>
                <td>$criticalText</td>
                <td>$ActionRequired</td>
            </tr>"
        }
        
        $HTML += "</tbody></table></div></div>"
    }
    
    # ================= DATABASE INFORMATION =================
    if ($DatabaseInfo) {
        $HTML += "<div class='card'><div class='card-header'><h2>Database Information</h2></div><div class='card-body'>"
        
        $HTML += "<table class='data-table'><tbody>"
        
        # Site Code row
        if ($DatabaseInfo.SiteCode) {
            $HTML += "<tr><th>Site Code</th><td>$($DatabaseInfo.SiteCode)</td></tr>"
        }
        
        # SCCM Version row
        if ($DatabaseInfo.Version) {
            $HTML += "<tr><th>SCCM Version</th><td>$($DatabaseInfo.Version)</td></tr>"
        }
        
        # Database Server row
        if ($DatabaseInfo.DatabaseServer -and $DatabaseInfo.DatabaseServer -ne "Unknown") {
            $HTML += "<tr><th>Database Server</th><td>$($DatabaseInfo.DatabaseServer)</td></tr>"
        } else {
            $HTML += "<tr><th>Database Server</th><td><span class='status status-warning'>Not Available</span></td></tr>"
        }
        
        # Database Name row
        if ($DatabaseInfo.DatabaseName -and $DatabaseInfo.DatabaseName -ne "Unknown") {
            $HTML += "<tr><th>Database Name</th><td>$($DatabaseInfo.DatabaseName)</td></tr>"
        } else {
            $HTML += "<tr><th>Database Name</th><td><span class='status status-warning'>Not Available</span></td></tr>"
        }
        
        # Reporting Server (if available)
        if ($DatabaseInfo.ReportingServer -and $DatabaseInfo.ReportingServer -ne "Unknown") {
            $HTML += "<tr><th>Reporting Server</th><td>$($DatabaseInfo.ReportingServer)</td></tr>"
        }
        
        # Reporting Database (if available)
        if ($DatabaseInfo.ReportingDatabase -and $DatabaseInfo.ReportingDatabase -ne "Unknown") {
            $HTML += "<tr><th>Reporting Database</th><td>$($DatabaseInfo.ReportingDatabase)</td></tr>"
        }
        
        $HTML += "</tbody></table>"
        
        # Add a note if database info is incomplete
        if ($DatabaseInfo.DatabaseServer -eq "Unknown" -or $DatabaseInfo.DatabaseName -eq "Unknown") {
            $HTML += "<div class='recommendation' style='margin-top: 15px;'>
                <h4>Note</h4>
                <p>Database server information could not be retrieved automatically. This may require manual verification.</p>
            </div>"
        }
        
        $HTML += "</div></div>"
    }
    
    # ================= RECOMMENDATIONS =================
    $HTML += "<div class='card'><div class='card-header'><h2>Recommendations & Next Steps</h2></div><div class='card-body'>"
    
    $HTML += "<div class='recommendation'><h4>Priority Actions</h4><ul>"
    
    if ($CriticalComponents -gt 0) {
        $HTML += "<li><strong>CRITICAL:</strong> Address $CriticalComponents critical SCCM components immediately</li>"
    }
    
    if ($StoppedServices -gt 0) {
        $HTML += "<li><strong>CRITICAL:</strong> Restart $StoppedServices stopped critical services</li>"
    }
    
    if ($ServerPerf.MemStatus -eq "Critical") {
        $HTML += "<li><strong>MEMORY:</strong> Investigate high memory usage ($($ServerPerf.Memory)%). Check for memory leaks or insufficient RAM</li>"
    }
    
    $CriticalDisks = if ($ServerPerf.Disks) { ($ServerPerf.Disks | Where-Object { $_.DiskStatus -eq "Critical" }).Count } else { 0 }
    if ($CriticalDisks -gt 0) {
        $HTML += "<li><strong>STORAGE:</strong> Free up disk space on $CriticalDisks critical drive(s) immediately</li>"
    }
    
    $HTML += "</ul></div>"
    
    $HTML += "<div class='recommendation'><h4>Service Issues Found</h4><ul>"
    
    $stoppedServiceList = if ($Services) { $Services | Where-Object { $_.Status -ne "Running" } } else { @() }
    foreach ($svc in $stoppedServiceList) {
        $HTML += "<li><strong>$($svc.Name):</strong> $($svc.Status) - $(if($svc.Critical){'CRITICAL'}else{'Warning'})</li>"
    }
    
    $HTML += "</ul></div>"
    
    $HTML += "<div class='recommendation'><h4>Preventive Actions</h4><ul>"
    $HTML += "<li>Review SCCM component logs daily for early warning signs</li>"
    $HTML += "<li>Implement regular SCCM health monitoring automation</li>"
    $HTML += "<li>Schedule monthly SCCM maintenance windows</li>"
    $HTML += "<li>Keep SCCM and SQL Server updated with latest cumulative updates</li>"
    $HTML += "<li>Regularly validate backup and recovery procedures</li>"
    $HTML += "</ul></div>"
    
    $HTML += "<div class='recommendation'><h4>Next Steps</h4><ol>"
    $HTML += "<li>Review this report with the SCCM administration team</li>"
    $HTML += "<li>Create action items for all critical and warning findings</li>"
    $HTML += "<li>Schedule follow-up review in 48 hours for critical items</li>"
    $HTML += "<li>Implement proactive monitoring for key components</li>"
    $HTML += "<li>Document resolution steps for recurring issues</li>"
    $HTML += "</ol></div>"
    
    $HTML += "</div></div>"
    
    # Add footer
    $HTML += Get-HTMLFooter
    
    # Save HTML report
    $HTML | Out-File $ReportFile -Encoding UTF8
    
    # Clean up CIM session
    Remove-CimSession $CimSession
    
    # Step 7: Final Summary
    Show-Progress "Report generation completed!" -Status "COMPLETE"
    
    Write-Host "`n" + "="*60 -ForegroundColor Green
    Write-Host "         SCCM HEALTH CHECK COMPLETED!" -ForegroundColor Green
    Write-Host "="*60 -ForegroundColor Green
    Write-Host ""
    Write-Host "📊 EXECUTIVE SUMMARY:" -ForegroundColor Cyan
    Write-Host "   Server Checked: $SCCMServer" -ForegroundColor White
    Write-Host "   Site Code: $SiteCode" -ForegroundColor White
    Write-Host "   Total Components: $($Components.Count)" -ForegroundColor White
    Write-Host "   Critical Issues: $CriticalComponents" -ForegroundColor $(if ($CriticalComponents -eq 0) { "Green" } else { "Red" })
    Write-Host "   Warnings: $WarningComponents" -ForegroundColor $(if ($WarningComponents -eq 0) { "Green" } else { "Yellow" })
    Write-Host "   Stopped Critical Services: $StoppedServices" -ForegroundColor $(if ($StoppedServices -eq 0) { "Green" } else { "Red" })
    Write-Host ""
    
    if ($CriticalComponents -gt 0 -or $StoppedServices -gt 0 -or $ServerPerf.MemStatus -eq "Critical") {
        Write-Host "⚠️  ISSUES REQUIRING ATTENTION:" -ForegroundColor Yellow
        if ($CriticalComponents -gt 0) {
            Write-Host "   • $CriticalComponents critical SCCM components" -ForegroundColor Red
        }
        if ($StoppedServices -gt 0) {
            Write-Host "   • $StoppedServices critical services stopped" -ForegroundColor Red
        }
        if ($ServerPerf.MemStatus -eq "Critical") {
            Write-Host "   • High memory usage: $($ServerPerf.Memory)%" -ForegroundColor Red
        }
        if ($CriticalDisks -gt 0) {
            Write-Host "   • $CriticalDisks drives with critical disk space" -ForegroundColor Red
        }
    } else {
        Write-Host "✅ NO CRITICAL ISSUES DETECTED" -ForegroundColor Green
    }
    
    Write-Host ""
    Write-Host "📁 REPORT GENERATED:" -ForegroundColor Cyan
    Write-Host "   Location: $ReportFile" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "👤 Prepared by: $($CompanyInfo.Author)" -ForegroundColor Magenta
    Write-Host "🏢 $($CompanyInfo.Name) - $($CompanyInfo.Practice)" -ForegroundColor Magenta
    Write-Host ""
    
    # Open report if requested
    if ($OpenReport) {
        Write-Host "Opening report in default browser..." -ForegroundColor Cyan
        Start-Process $ReportFile
    }
    
    Write-Host "`nPress any key to exit..." -ForegroundColor Gray
    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
catch {
    Show-Error "An unexpected error occurred: $($_.Exception.Message)"
    Show-Error "Script execution failed."
    Write-Host "`nPress any key to exit..." -ForegroundColor Gray
    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    exit 1
} 

paste this script in your server with appropriate name. In my environment i have saved this script with name SCCM_V4.ps1.

Open PowerShell with Administrative privilege and change directory to the folder where script is saved. run the script.

.\SCCMVV4.ps1 ( change as per name of the your script).

The script will ask several details to inputs. in my case details are below
SCCM SERVER Name: mecm
SMS Provider Server Name: mecm
Report location where it will be stored after generating the reports.
SCCM server Username: mecm@mohammed.com.np
password of the user: ********

In your case these details may be different (Please change accordingly).

In the screenshot asked for server name
in my case it is : mecm

Provide the SMS Provider server name: in my case all components are installed in the same server so server name will be SMS provider name: mecm

Provide the location where you want to store the report generated by this script.

provide sccm administrator credential and enter.
In my case, Username will mecm because i have created user in my active directory with this name

provide the password of the mec@mohammed.com.np user.

Details will be displayed in you PowerShell script while it is running.

Go to provided location and check report has been generated or not.

Here is the Sample Report with good looking UI.

download Sample Report from here.

That’s it!

Did you enjoy the article ? share this with other hungry people and comment below your suggestions. also you might be intrested learning more about SCCM server. Here you will learn and understand about Configuring MECM Client Settings.

Leave a Reply

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

Back To Top