MECM: Client check

Updating to a new client and want to check to make sure the client is working correctly.
<#
SCCM Health Check Script
- Validates SCCM client health
- Logging + summary report
- Designed to pair with removal/reinstall scripts
#>
# ============================
# Logging + Summary Functions
# ============================
$Global:LogFile = "C:\Windows\Temp\SCCM_HealthCheck_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
$Global:Summary = @()
function Write-Log {
param(
[string]$Message,
[string]$Level = "INFO"
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$entry = "[$timestamp] [$Level] $Message"
Write-Host $entry
Add-Content -Path $Global:LogFile -Value $entry
}
function Add-Summary {
param([string]$Message)
$Global:Summary += $Message
}
# ============================
# Health Check Function
# ============================
function Test-SCCMHealth {
Write-Log "Starting SCCM health check..."
Add-Summary "Health check started"
# ----------------------------
# 1. Check if SCCM is installed
# ----------------------------
Write-Log "Checking for SCCM installation..."
$ccmExecService = Get-Service -Name CcmExec -ErrorAction SilentlyContinue
if (-not $ccmExecService) {
Write-Log "SCCM client is NOT installed." "WARN"
Add-Summary "Client not installed"
return
}
Add-Summary "Client installed"
# ----------------------------
# 2. Check CcmExec service
# ----------------------------
Write-Log "Checking CcmExec service status..."
if ($ccmExecService.Status -eq "Running") {
Write-Log "CcmExec service is running."
Add-Summary "CcmExec running"
}
else {
Write-Log "CcmExec service is NOT running." "ERROR"
Add-Summary "CcmExec NOT running"
}
# ----------------------------
# 3. Check WMI repository
# ----------------------------
Write-Log "Checking WMI repository consistency..."
$verify = (winmgmt /verifyrepository)
if ($verify -match "consistent") {
Write-Log "WMI repository is consistent."
Add-Summary "WMI healthy"
}
else {
Write-Log "WMI repository is NOT consistent." "ERROR"
Add-Summary "WMI inconsistent"
}
# ----------------------------
# 4. Check SCCM WMI namespaces
# ----------------------------
Write-Log "Checking SCCM WMI namespaces..."
$namespaces = @(
"root\ccm",
"root\ccm\policy",
"root\ccm\softwareinventory",
"root\ccm\hardwareinventory",
"root\ccm\locationservices"
)
foreach ($ns in $namespaces) {
try {
Get-CimInstance -Namespace $ns -ClassName __Namespace -ErrorAction Stop | Out-Null
Write-Log "Namespace OK: $ns"
Add-Summary "WMI OK: $ns"
}
catch {
Write-Log "Namespace missing: $ns" "ERROR"
Add-Summary "WMI missing: $ns"
}
}
# ----------------------------
# 5. Check client assignment
# ----------------------------
Write-Log "Checking client assignment..."
try {
$ls = Get-CimInstance -Namespace "root\ccm\locationservices" -ClassName "SMS_LocationServices" -ErrorAction Stop
$assignedSite = $ls.SMSAssignedSiteCode
$mp = $ls.CurrentManagementPoint
Write-Log "Assigned Site: $assignedSite"
Write-Log "Management Point: $mp"
Add-Summary "Assigned Site: $assignedSite"
Add-Summary "MP: $mp"
}
catch {
Write-Log "Unable to query SMS_LocationServices." "ERROR"
Add-Summary "Client assignment check failed"
}
# ----------------------------
# 6. Check registry keys
# ----------------------------
Write-Log "Checking registry keys..."
$regPath = "HKLM:\SOFTWARE\Microsoft\CCM"
if (Test-Path $regPath) {
Write-Log "Registry key exists: $regPath"
Add-Summary "Registry OK"
}
else {
Write-Log "Registry key missing: $regPath" "ERROR"
Add-Summary "Registry missing"
}
# ----------------------------
# 7. Check certificates
# ----------------------------
Write-Log "Checking SCCM certificates..."
$certs = Get-ChildItem Cert:\LocalMachine\SMS -ErrorAction SilentlyContinue
if ($certs) {
Write-Log "SCCM certificates found."
Add-Summary "Certificates OK"
}
else {
Write-Log "No SCCM certificates found." "WARN"
Add-Summary "Certificates missing"
}
# ----------------------------
# 8. Check CCM folder structure (Completed)
# ----------------------------
Write-Log "Checking CCM folder structure..."
$ccmRoot = "$Env:WinDir\CCM"
if (Test-Path $ccmRoot) {
Write-Log "CCM root folder exists."
Add-Summary "CCM folder OK"
} else {
Write-Log "CCM folder missing." "ERROR"
Add-Summary "CCM folder missing"
return
}
# Required subfolders
$requiredSubfolders = @(
"Logs",
"Cache",
"Inventory",
"ServiceData"
)
foreach ($sub in $requiredSubfolders) {
$path = Join-Path $ccmRoot $sub
if (Test-Path $path) {
Write-Log "Subfolder OK: $sub"
Add-Summary "Subfolder OK: $sub"
} else {
Write-Log "Missing subfolder: $sub" "WARN"
Add-Summary "Missing subfolder: $sub"
}
}
# Required core files
$requiredFiles = @(
"CcmExec.exe",
"CcmRepair.exe",
"CcmRestart.exe",
"CcmEval.exe"
)
foreach ($file in $requiredFiles) {
$path = Join-Path $ccmRoot $file
if (Test-Path $path) {
Write-Log "File OK: $file"
Add-Summary "File OK: $file"
} else {
Write-Log "Missing file: $file" "ERROR"
Add-Summary "Missing file: $file"
}
}
# Check version of CcmExec.exe
$ccmExecPath = Join-Path $ccmRoot "CcmExec.exe"
if (Test-Path $ccmExecPath) {
$version = (Get-Item $ccmExecPath).VersionInfo.FileVersion
Write-Log "CcmExec.exe version: $version"
Add-Summary "CcmExec version: $version"
} else {
Write-Log "CcmExec.exe missing — cannot determine version." "ERROR"
Add-Summary "CcmExec missing"
}
Write-Log "Health check completed."
Add-Summary "Health check completed"
}
# ============================
# Run Health Check
# ============================
Test-SCCMHealth
# ============================
# Summary Report
# ============================
Write-Log "Generating summary report..."
$summaryHeader = "===== SCCM Health Check Summary ====="
Write-Host $summaryHeader
Add-Content -Path $Global:LogFile -Value $summaryHeader
foreach ($item in $Global:Summary) {
Write-Host " - $item"
Add-Content -Path $Global:LogFile -Value " - $item"
}
$summaryFooter = "===== End of Summary ====="
Write-Host $summaryFooter
Add-Content -Path $Global:LogFile -Value $summaryFooter
Write-Log "Summary report completed. Log saved to $Global:LogFile"