feat(guru-scan): fix exit code capture, add GURUSCAN_RESULT_JSON reporting, pre-scan hardening

Exit code fix: add $proc.Handle caching after Start-Process -PassThru to prevent
the handle from being released before ExitCode is readable (known PS5.1 bug).

GuruRMM reporting: launcher now finds results.json after each scan and emits
GURUSCAN_RESULT_JSON:<compressed> to stdout. Agent CommandResult captures it;
server stores it in commands.stdout for retrieval via GET /api/commands/:id.

Pre-scan hardening:
- Pre-flight EXE check: warns about missing scanner binaries before run starts
- Windows Defender exclusions added for scanner/log paths before scan, removed after

AdwCleaner: add /path {LOG_ROOT} arg so logs write directly to scan log root;
update log_src to {LOG_ROOT}\Logs to match.

HitmanPro: add /quiet to scan and clean args to suppress GUI in headless runs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 00:13:16 -07:00
parent a8ee927db0
commit 40e090c95a
4 changed files with 113 additions and 64 deletions

View File

@@ -28,7 +28,7 @@ Scanners run in this order. Each stage hands off to the next regardless of findi
| # | Scanner | Category | Notes |
|---|---------|----------|-------|
| 1 | **RKill** | process-killer | Kills malware-related processes before scanners run. Exit 1 = processes were killed (not a threat indicator). |
| 2 | **AdwCleaner** | adware | Removes adware, PUPs, and browser hijackers. |
| 2 | **AdwCleaner** | adware | Removes adware, PUPs, and browser hijackers. **Requires an interactive user session** (GUI app; no headless/SYSTEM mode). Skipped automatically when running as SYSTEM with no desktop. To include AdwCleaner, dispatch via GuruRMM with `context: user_session`. |
| 3 | **Emsisoft Command Line Scanner** | antimalware | Two-step: NSIS installer extracts to `C:\EmsisoftCmd\`, then `/update` fetches latest definitions, then scans. |
| 4 | **HitmanPro** | antimalware | Cloud-assisted second-opinion scanner. Trial registry is reset before each run via `Invoke-HitmanProTrialReset`. |
@@ -75,6 +75,11 @@ To run cleanup immediately without waiting (e.g. if the task was missed):
- `-Headless` passes `NoNewWindow` to all scanner launches, suppressing UI windows.
Use this when dispatching from an RMM agent that has no interactive desktop.
- Scanners with `session0_compatible: false` in `scanners.json` are automatically skipped
when the module detects it is running as SYSTEM (Session 0). Currently: **AdwCleaner**.
The result record shows `SKIPPED (requires user session)` rather than a failure.
- To run AdwCleaner via GuruRMM, dispatch with `context: user_session` so it runs in
the active user's desktop session (requires a logged-in user on the target machine).
---
@@ -156,6 +161,7 @@ guru-scan\
Invoke-Remediation.ps1 # Thin launcher -> Invoke-Remediation
Get-ScanSummary.ps1 # Thin launcher -> Get-ScanSummary
Invoke-PostRebootCleanup.ps1 # Thin launcher -> Invoke-PostRebootCleanup (manual cleanup trigger)
Invoke-ScannerCleanup.ps1 # Post-reboot cleanup script; copied to C:\GuruScan\ when reboot is needed
Download-Scanners.ps1 # Downloads scanner EXEs from scanners.json URLs
downloads\ # Scanner EXEs (gitignored)
```