#Requires -RunAsAdministrator <# .SYNOPSIS GuruScan - multi-engine malware scanning orchestrator (single-file, RMM-ready). .DESCRIPTION Runs a suite of portable malware scanners in sequence, captures logs, and writes a structured results.json plus a zip archive of all logs. Scanner definitions are read from scanners.json in the same directory. By default runs all scanners in clean (remediation) mode. Use -ScanOnly to detect without cleaning. NOTE: MSERT is no longer included in the default scanner list because it takes too long for routine runs. To run MSERT, invoke it directly or add it back to scanners.json. .PARAMETER ScanOnly Use scan args (detect only) instead of clean args for every scanner. .PARAMETER AutoRemediate After a scan-only pass, if threats are found, automatically re-run all scanners in clean mode. .PARAMETER Scanners Run only the named scanners (comma-separated or multiple values). Names must match the Name field in scanners.json exactly. .PARAMETER TimeoutMin Override the per-scanner timeout (in minutes) for all scanners. .PARAMETER SkipScanners Skip one or more named scanners by name. Names must match the Name field in scanners.json exactly. Useful for excluding a single scanner without respecifying the entire list. .PARAMETER Headless Suppress scanner windows (used when dispatching via RMM). .EXAMPLE .\Invoke-GuruScan.ps1 .\Invoke-GuruScan.ps1 -ScanOnly -AutoRemediate .\Invoke-GuruScan.ps1 -SkipScanners Emsisoft .\Invoke-GuruScan.ps1 -Headless #> [CmdletBinding()] param( [switch]$ScanOnly, [switch]$AutoRemediate, [string[]]$Scanners, [int]$TimeoutMin = 0, [string[]]$SkipScanners = @(), [switch]$Headless ) $moduleManifest = Join-Path $PSScriptRoot 'GuruScan.psd1' if (-not (Test-Path $moduleManifest)) { Write-Host "[ERROR] GuruScan module not found: $moduleManifest" -ForegroundColor Red exit 1 } Import-Module $moduleManifest -Force Invoke-GuruScan @PSBoundParameters -OutputSink Disk