# Tanium Sensor: Windows Update Overall Health

This page documents the **Windows\_Update\_OverallHealth** Tanium sensor, which evaluates Windows Update health on an endpoint using multiple indicators such as last update status, CBS corruption counts, pending reboot state, SoftwareDistribution size, and Windows Update service status.

<div contenteditable="false" id="bkmrk-">---

</div>## **Purpose**

This sensor provides a high‑level health result (Healthy / Unhealthy) based on several Windows Update components. It is intended to support:

- Patch health monitoring
- Compliance reporting
- Automated remediation workflows
- Tanium dashboards and investigations

<div contenteditable="false" id="bkmrk--1">---

</div>## **Health Criteria Evaluated**

The sensor determines update health using the following factors:

### **1. Last Windows Update Install Status**

Queried via the Windows Update Session API.

- `Success`
- `Failed`
- `InProgress`
- Fallback: `Unknown`

### **2. CBS Corruption Count**

Scans `C:\Windows\Logs\CBS\CBS.log` for corruption‑related strings:

- `corrupt`
- `error`
- `failed`

A threshold is used to determine severity.

### **3. Pending Reboot State**

Checks:

- Component-Based Servicing reboot flag
- Windows Update reboot requirement

### **4. Windows Update Service Status (wuauserv)**

- Running
- Stopped
- Disabled
- Unknown

### **5. SoftwareDistribution Download Folder Size**

Excessive size may indicate update failures or stuck downloads.

<div contenteditable="false" id="bkmrk--2">---

</div>## **Thresholds Used**

<table id="bkmrk-metric-threshold-mea"><tbody><tr><th>Metric</th><th>Threshold</th><th>Meaning</th></tr><tr><td>CBS corruption count</td><td>**&gt; 50**</td><td>Too many corruption entries</td></tr><tr><td>SoftwareDistribution size</td><td>**&gt; 2048 MB (2 GB)**</td><td>Indicates stuck or oversized update cache</td></tr></tbody></table>

<div contenteditable="false" id="bkmrk--3">---

</div>## **Output**

The sensor returns: **Healthy** or **Unhealthy**

<div contenteditable="false" id="bkmrk--4">---

</div>## **Script Code**

```powershell
####################################################################################### 
# Tanium Sensor: Windows_Update_Health_Status
# Purpose: Detect Windows Update failures, stuck states, and component corruption

# A single sensor return with:
# LastInstallStatus=Failed
# WUService=Running
# CBSCorruptionEntries=124  
# PendingReboot=Yes
# SoftwareDistSizeMB=412.55
# OverallHealth=Unhealthy

# What This Sensor Detects
# 1. Patch install failures
# Reads the last Windows Update result code
# Flags: Failed, InProgress, or Success

# 2. Windows Update service state
# Detects if wuauserv is stopped or stuck

# 3. Component store corruption
# Scans CBS.log for: “corrupt”, “error”, and “failed”
# If entries > 50 → likely broken Windows servicing stack.

# 4. Pending reboot conditions
# Checks: Component-Based Servicing → RebootPending and WindowsUpdate → RebootRequired
# If yes → updates cannot install.

# 5. SoftwareDistribution health
# An oversized or corrupt Download folder indicates: stuck updates, failed downloads, or superseded updates not removed 
###################################################################################################################

$results = @{}

# --- Check 1: Last Update Result ---
try {
    $session = Get-WmiObject -Class "Microsoft.Update.Session" -Namespace "root\cimv2" -ErrorAction Stop
    $searcher = $session.CreateUpdateSearcher()
    $history = $searcher.QueryHistory("", 0, 1)

    switch ($history.ResultCode) {
        2 { $results["LastInstallStatus"] = "Failed" }
        3 { $results["LastInstallStatus"] = "InProgress" }
        default { $results["LastInstallStatus"] = "Success" }
    }
} catch {
    $results["LastInstallStatus"] = "Unknown"
}

# --- Check 2: WU Service Status ---
try {
    $wuService = (Get-Service wuauserv).Status
    $results["WUService"] = $wuService
} catch {
    $results["WUService"] = "Unknown"
}

# --- Check 3: CBS corruption count ---
$CBSLog = "C:\Windows\Logs\CBS\CBS.log"
if (Test-Path $CBSLog) {
    $corruptCount = (Select-String -Path $CBSLog -Pattern "corrupt|error|failed" -SimpleMatch -ErrorAction SilentlyContinue).Count
    $results["CBSCorruptionEntries"] = $corruptCount
} else {
    $results["CBSCorruptionEntries"] = "LogMissing"
}

# --- Check 4: Pending Reboot Detection ---
$pendingCBS = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing" -ErrorAction SilentlyContinue).RebootPending
$pendingWU  = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" -ErrorAction SilentlyContinue)."RebootRequired"

if ($pendingCBS -or $pendingWU) {
    $results["PendingReboot"] = "Yes"
} else {
    $results["PendingReboot"] = "No"
}

# --- Check 5: SoftwareDistribution Download folder size ---
try {
    $sdPath = "C:\Windows\SoftwareDistribution\Download"
    $sdSize = (Get-ChildItem $sdPath -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum
    $results["SoftwareDistSizeMB"] = [math]::Round(($sdSize / 1MB), 2)
} catch {
    $results["SoftwareDistSizeMB"] = "Unknown"
}

# --- Overall Health Score ---
if (
    $results["LastInstallStatus"] -eq "Failed" -or
    ($results["CBSCorruptionEntries"] -is [int] -and $results["CBSCorruptionEntries"] -gt 50) -or
    $results["PendingReboot"] -eq "Yes"
) {
    $results["OverallHealth"] = "Unhealthy"
} else {
    $results["OverallHealth"] = "Healthy"
}

# Output all fields
$results.GetEnumerator() | Sort-Object Name | ForEach-Object { "$($_.Key)=$($_.Value)" }
```

## **Use Cases**

- Daily Windows Update health checks across the enterprise
- Triggered remediation packages (e.g., clear SoftwareDistribution, reset WU, repair CBS)
- Dashboards showing overall patch stability
- Investigating failed patch cycles

<div contenteditable="false" id="bkmrk--5">---

</div>## **Related Sensors / Recommended Pairings**

- **CBSCorruption Count**
- **SoftwareDistribution Size**
- **Pending Reboot Check**
- **Wuauserv Service Status**