Files
PatchProbe-Server/CLAUDE.md
2026-05-25 10:29:38 +08:00

10 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Build

# Debug build
dotnet build PatchProbe.Cli/PatchProbe.Cli.csproj

# Self-contained single-file win-x64 release
dotnet publish PatchProbe.Cli/PatchProbe.Cli.csproj -c Release
# Output: PatchProbe.Cli/bin/Release/net10.0-windows/win-x64/publish/PatchProbe.exe

Run

# Collect evidence, write JSON to output/ directory
PatchProbe.exe scan

# Write payload to a specific path
PatchProbe.exe scan --output C:\temp\scan.json

# Collect but print JSON to stdout instead of uploading
PatchProbe.exe scan --no-upload

Note: must be run as administrator for full data access (WUA, event logs, WMI).


Project Overview

I am building a Windows patch-management evidence collection and orchestration platform similar in concept to the patch-management component of major RMM tools.

The goal is NOT to replace Windows Update Agent (WUA), CBS, DISM, or the Windows driver-selection stack.

Instead, the platform should act as a centralized control plane that:

  • collects patch-related evidence from endpoints
  • evaluates compliance
  • manages policy/rings/approvals
  • eventually orchestrates installations
  • reports status and failures

Windows itself remains authoritative for:

  • update applicability
  • prerequisites
  • supersedence
  • CBS/component servicing logic
  • driver matching/ranking
  • installation success/failure

The collector should be:

  • portable
  • standalone
  • self-contained
  • executable as administrator
  • non-persistent
  • non-installed
  • safe/read-only initially

The first milestone is NOT patch installation.

The first milestone is proving that a one-shot executable can collect equivalent patch-management evidence to what an RMM platform sees.


Current State

I have already:

  • created a new C# Console App
  • selected .NET 9
  • chosen a self-contained single-file EXE architecture

The collector executable should eventually be called:

PatchProbe.exe

Architecture Requirements

The application should use:

  • C#
  • .NET 9
  • Generic Host
  • Dependency Injection
  • HttpClientFactory
  • Structured logging
  • Clean collector/service architecture

The project should remain a console application.

Do NOT use:

  • WinForms
  • WPF
  • ASP.NET
  • Worker Service
  • MAUI

The collector flow is:

PatchProbe.exe
→ collect evidence
→ serialize to JSON
→ upload to backend
→ exit

The collector should not:

  • install updates
  • download updates
  • modify policy
  • create scheduled tasks
  • register services
  • persist locally beyond optional logs/cache

Desired Solution Structure

The solution should be scaffolded approximately like this:

PatchProbe.sln
│
├── PatchProbe.Cli/
│   ├── Program.cs
│   ├── Collectors/
│   ├── Models/
│   ├── Services/
│   └── Utils/
│
├── PatchProbe.Shared/
│   ├── Models/
│   ├── Contracts/
│   └── Serialization/
│
└── PatchProbe.Engine.Contracts/
    ├── ApiModels/
    └── Versioning/

Even if some projects begin mostly empty.


NuGet Packages To Use

Immediately add:

dotnet add package System.Management
dotnet add package Serilog
dotnet add package Serilog.Sinks.Console
dotnet add package Serilog.Sinks.File
dotnet add package System.CommandLine
dotnet add package Microsoft.Extensions.Hosting
dotnet add package Microsoft.Extensions.DependencyInjection
dotnet add package Microsoft.Extensions.Http

Program.cs Architecture

Use Generic Host architecture.

Example direction:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;

var builder = Host.CreateApplicationBuilder(args);

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .WriteTo.File("logs/patchprobe.log")
    .CreateLogger();

builder.Services.AddSingleton<DeviceCollector>();
builder.Services.AddSingleton<WindowsUpdateCollector>();
builder.Services.AddSingleton<PayloadUploader>();

var host = builder.Build();

var deviceCollector = host.Services.GetRequiredService<DeviceCollector>();
var wuCollector = host.Services.GetRequiredService<WindowsUpdateCollector>();

var device = await deviceCollector.CollectAsync();
var updates = await wuCollector.CollectAsync();

Console.WriteLine("Collection complete.");

Maintain proper layering and separation of concerns.


Core Philosophy

Treat collected data as immutable evidence.

Meaning:

PatchProbe scan = factual snapshot

NOT:

  • interpreted state
  • compliance judgment
  • install decisions

Those belong in the backend engine later.

The backend evaluates:

  • policy
  • compliance
  • approval
  • orchestration
  • ring logic

The collector only gathers evidence.


Windows Patch-Management Philosophy

The engine does NOT replace:

  • Windows Update Agent
  • CBS
  • TrustedInstaller
  • DISM
  • Windows driver ranking

Instead:

The platform provides:
- policy
- scheduling
- approvals
- maintenance windows
- telemetry
- compliance reporting
- failure classification
- orchestration

Windows provides:
- applicability
- prerequisites
- supersedence
- servicing logic
- driver selection
- install success/failure

Required Initial Collectors

Implement collectors in this approximate order.

1. DeviceCollector

Collect:

  • hostname
  • manufacturer
  • model
  • serial number
  • BIOS version
  • BIOS date
  • TPM presence/version
  • RAM
  • domain/workgroup
  • system type

Use:

  • WMI/CIM
  • registry
  • environment info

2. OsCollector

Collect:

  • ProductName
  • EditionID
  • DisplayVersion
  • ReleaseId
  • Build number
  • UBR
  • architecture
  • install date
  • last boot

Registry path:

HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion

3. WindowsUpdateCollector

This is the core component.

Use WUA COM APIs.

Use:

  • Microsoft.Update.Session
  • CreateUpdateSearcher()

Collect:

  • applicable updates
  • update titles
  • KB IDs
  • categories
  • severity
  • reboot requirements
  • WUA result codes
  • update history
  • WU source/policy state

Search criteria:

IsInstalled=0 and IsHidden=0

Use COM interop or dynamic COM access.

Example direction:

Type sessionType = Type.GetTypeFromProgID("Microsoft.Update.Session");
dynamic session = Activator.CreateInstance(sessionType);
dynamic searcher = session.CreateUpdateSearcher();

dynamic result = searcher.Search("IsInstalled=0 and IsHidden=0");

The collector should ask Windows what is applicable rather than attempting to independently determine applicability.


Important Patch-Management Concepts

Windows decides:

  • whether an update is applicable
  • whether prerequisites are met
  • supersedence
  • CBS/component servicing logic
  • driver ranking/matching
  • installation success

The platform should observe and orchestrate, not replace these systems.


4. PendingRebootCollector

Collect pending reboot indicators from:

  • CBS
  • Windows Update
  • Session Manager
  • Computer rename state

Registry locations include:

HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending
HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired
HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager

5. DriverCollector

Collect:

  • device name
  • driver version
  • manufacturer
  • INF name
  • hardware IDs
  • device class
  • driver date

Use:

  • Win32_PnPSignedDriver
  • pnputil where useful

Important: Do NOT attempt to replace Windows driver ranking logic.


6. CBS / DISM Collector

Collect:

  • package state
  • servicing state
  • DISM package output

Use:

dism /online /get-packages /format:table

Treat CBS as the servicing authority.


7. Windows Update Policy Collector

Collect policy/configuration from:

  • WSUS
  • WUfB
  • AU settings
  • deferrals

Registry paths include:

HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate
HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU
HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings

8. Event Collector

Collect recent relevant events from:

  • System
  • Microsoft-Windows-WindowsUpdateClient/Operational
  • Microsoft-Windows-UpdateOrchestrator/Operational

Focus on:

  • failures
  • installs
  • servicing issues
  • reboot events

Payload Design

The collector should produce a JSON payload approximately shaped like:

{
  "schemaVersion": "0.1",
  "collector": {},
  "device": {},
  "os": {},
  "pendingReboot": {},
  "windowsUpdate": {
    "applicableUpdates": [],
    "history": [],
    "policy": {}
  },
  "installedHotfixes": [],
  "cbsPackages": [],
  "drivers": [],
  "recentUpdateEvents": []
}

This payload should be treated as immutable evidence.


CLI Shape

The executable should eventually support:

PatchProbe.exe scan
PatchProbe.exe upload
PatchProbe.exe export
PatchProbe.exe debug
PatchProbe.exe validate

Initially only implement:

PatchProbe.exe scan

Publishing Requirements

The application should be published as:

  • self-contained
  • single-file
  • win-x64 executable

Example publish command:

dotnet publish ^
  -c Release ^
  -r win-x64 ^
  --self-contained true ^
  -p:PublishSingleFile=true ^
  -p:EnableCompressionInSingleFile=true

Result:

  • one EXE
  • no installed runtime dependency

Important Design Constraints

Do NOT:

  • tightly couple collection and analysis
  • tightly couple collection and orchestration
  • make compliance decisions in the collector

Maintain:

Collector
→ evidence payload

Backend
→ analysis/policy/compliance

Frontend
→ visualization/reporting

Future Evolution Path

The architecture should naturally evolve into:

Phase 1:
One-shot evidence collector

Phase 2:
Scheduled execution

Phase 3:
Patch orchestration

Phase 4:
Remediation engine

Phase 5:
Approval rings/policies

Phase 6:
Full RMM-style patch-management platform

Current Request

Based on all of the above:

  • scaffold the initial project architecture
  • implement the first collectors
  • implement payload models
  • implement logging
  • implement WUA scanning
  • implement JSON serialization
  • implement upload abstraction
  • implement clean DI architecture
  • implement a production-quality starting structure suitable for future expansion