Initial Commit
This commit is contained in:
615
CLAUDE.md
Normal file
615
CLAUDE.md
Normal file
@@ -0,0 +1,615 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```csharp
|
||||
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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
IsInstalled=0 and IsHidden=0
|
||||
```
|
||||
|
||||
Use COM interop or dynamic COM access.
|
||||
|
||||
Example direction:
|
||||
|
||||
```csharp
|
||||
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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```json
|
||||
{
|
||||
"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:
|
||||
|
||||
```text
|
||||
PatchProbe.exe scan
|
||||
PatchProbe.exe upload
|
||||
PatchProbe.exe export
|
||||
PatchProbe.exe debug
|
||||
PatchProbe.exe validate
|
||||
```
|
||||
|
||||
Initially only implement:
|
||||
|
||||
```text
|
||||
PatchProbe.exe scan
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Publishing Requirements
|
||||
|
||||
The application should be published as:
|
||||
|
||||
* self-contained
|
||||
* single-file
|
||||
* win-x64 executable
|
||||
|
||||
Example publish command:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```text
|
||||
Collector
|
||||
→ evidence payload
|
||||
|
||||
Backend
|
||||
→ analysis/policy/compliance
|
||||
|
||||
Frontend
|
||||
→ visualization/reporting
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Future Evolution Path
|
||||
|
||||
The architecture should naturally evolve into:
|
||||
|
||||
```text
|
||||
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
|
||||
Reference in New Issue
Block a user