Crypto Prices

Tuesday, May 20, 2025

Inspect the Windows Server MECM Client Logs for Errors

 Powershell Script:

 <#
.SYNOPSIS
    Inspects MECM client logs on a Windows Server for errors and generates a report.

.DESCRIPTION
    This script searches specified MECM client log files for error-related keywords,
    extracts relevant details, and outputs them to the console and optionally to a file.
    It targets logs in the default MECM client log directory (%windir%\CCM\Logs).

.PARAMETER LogPath
    The directory containing MECM client logs. Defaults to $env:windir\CCM\Logs.

.PARAMETER OutputFile
    Optional path to save the error report. If not specified, output is console-only.

.PARAMETER DaysToCheck
    Number of days to look back for log entries. Defaults to 7 days.

.EXAMPLE
    .\Inspect-MECMLogs.ps1 -OutputFile "C:\Logs\MECM_ErrorReport.txt" -DaysToCheck 3
    Inspects logs for errors in the last 3 days and saves the report to C:\Logs\MECM_ErrorReport.txt.

.NOTES
    Ensure the script runs with sufficient permissions to access the MECM log directory.
    Common logs checked include CAS.log, ContentTransferManager.log, DataTransferService.log, and more.
#>

param (
    [string]$LogPath = "$env:windir\CCM\Logs",
    [string]$OutputFile = "",
    [int]$DaysToCheck = 7
)

# Function to check if the log path exists
function Test-LogPath {
    if (-not (Test-Path $LogPath)) {
        Write-Error "Log directory '$LogPath' does not exist. Please verify the path."
        exit 1
    }
}

# Function to get log files
function Get-LogFiles {
    $logFiles = @(
        "CAS.log",                  # Content Access Service
        "ContentTransferManager.log", # Content transfer operations
        "DataTransferService.log",   # Data transfer operations
        "LocationServices.log",      # Boundary and DP location
        "ClientLocation.log",        # Client location and boundary group
        "CcmExec.log",              # Client execution and health
        "smsts.log",                # Task sequence (if applicable)
        "AppDiscovery.log",         # Application discovery
        "AppEnforce.log",           # Application enforcement
        "PatchDownloader.log"       # Patch download operations
    )
    return $logFiles | Where-Object { Test-Path (Join-Path $LogPath $_) }
}

# Function to search logs for errors
function Search-LogsForErrors {
    param (
        [string[]]$LogFiles,
        [DateTime]$StartDate
    )

    $errorKeywords = @("ERROR", "FAILED", "FAILURE", "EXCEPTION", "0x800", "0xC")
    $results = @()

    foreach ($log in $LogFiles) {
        $logFilePath = Join-Path $LogPath $log
        Write-Host "Processing log: $log"

        try {
            # Read log file content
            $logContent = Get-Content -Path $logFilePath -ErrorAction Stop

            # Parse each line
            $lineNumber = 0
            foreach ($line in $logContent) {
                $lineNumber++

                # Check if line contains any error keywords
                if ($errorKeywords | Where-Object { $line -match $_ }) {
                    # Extract timestamp (assuming standard MECM log format: MM-DD-YYYY HH:MM:SS)
                    $timestamp = ""
                    if ($line -match '(\d{2}-\d{2}-\d{4}\s+\d{2}:\d{2}:\d{2})') {
                        $timestamp = $Matches[1]
                        try {
                            $logDate = [DateTime]::ParseExact($timestamp, "MM-dd-yyyy HH:mm:ss", $null)
                            if ($logDate -lt $StartDate) {
                                continue  # Skip entries older than specified days
                            }
                        }
                        catch {
                            $timestamp = "Unknown"
                        }
                    }

                    # Add error details to results
                    $results += [PSCustomObject]@{
                        LogFile     = $log
                        LineNumber  = $lineNumber
                        Timestamp   = $timestamp
                        ErrorMessage = $line
                    }
                }
            }
        }
        catch {
            Write-Warning "Failed to read log file '$log': $_"
            $results += [PSCustomObject]@{
                LogFile     = $log
                LineNumber  = 0
                Timestamp   = "N/A"
                ErrorMessage = "Failed to read log: $_"
            }
        }
    }

    return $results
}

# Function to output results
function Output-Results {
    param (
        [array]$Results,
        [string]$OutputFile
    )

    if ($Results.Count -eq 0) {
        Write-Host "No errors found in the specified logs within the last $DaysToCheck days."
    }
    else {
        Write-Host "`nFound $($Results.Count) error(s) in the logs:`n"
        $Results | Format-Table -Property LogFile, LineNumber, Timestamp, ErrorMessage -AutoSize -Wrap

        # Save to file if specified
        if ($OutputFile) {
            try {
                $Results | Select-Object LogFile, LineNumber, Timestamp, ErrorMessage |
                    Export-Csv -Path $OutputFile -NoTypeInformation -Force
                Write-Host "Error report saved to: $OutputFile"
            }
            catch {
                Write-Error "Failed to save report to '$OutputFile': $_"
            }
        }
    }
}

# Main script
try {
    # Validate log path
    Test-LogPath

    # Calculate start date for filtering
    $startDate = (Get-Date).AddDays(-$DaysToCheck)

    # Get list of log files to process
    $logFiles = Get-LogFiles
    if ($logFiles.Count -eq 0) {
        Write-Warning "No MECM log files found in '$LogPath'."
        exit 1
    }

    # Search logs for errors
    $errorResults = Search-LogsForErrors -LogFiles $logFiles -StartDate $startDate

    # Output results
    Output-Results -Results $errorResults -OutputFile $OutputFile
}
catch {
    Write-Error "An unexpected error occurred: $_"
    exit 1
}

How the Script Works

  1. Parameters:
    • $LogPath: Specifies the MECM client log directory (defaults to %windir%\CCM\Logs).
    • $OutputFile: Optional path to save the error report as a CSV file.
    • $DaysToCheck: Limits the search to log entries from the last N days (default is 7).
  2. Log Files Searched:
    • The script targets key MECM client logs relevant to content distribution and client operations, such as CAS.log, ContentTransferManager.log, DataTransferService.log, and others.
    • Only logs that exist in the specified directory are processed.
  3. Error Detection:
    • Searches for common error-related keywords (e.g., "ERROR", "FAILED", "0x800" error codes).
    • Parses the log timestamp to filter entries within the specified time range.
    • Captures the log file name, line number, timestamp, and error message.
  4. Output:
    • Displays errors in a formatted table on the console.
    • Optionally saves results to a CSV file for further analysis.
    • Reports if no errors are found or if logs are inaccessible.
  5. Error Handling:
    • Checks if the log directory exists.
    • Handles cases where log files are unreadable or corrupted.
    • Provides warnings for issues like missing logs or file access errors.
     

Usage:

Run for the last 3 days and save to a file:

.\Inspect-MECMLogs.ps1 -OutputFile "C:\Logs\MECM_ErrorReport.csv" -DaysToCheck 3

Specify a custom log path:

.\Inspect-MECMLogs.ps1 -LogPath "C:\Windows\CCM\Logs" -OutputFile "C:\Logs\Errors.csv" 

 

 

 

No comments:

 
Free Hit Counter