#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
$scanStart = Get-Date
Invoke-GuruScan @PSBoundParameters -OutputSink Disk

# Emit structured JSON to stdout for GuruRMM CommandResult capture.
# Read from results.json written during this run (newer than $scanStart).
$resultsFile = Get-ChildItem -Path 'C:\ScanLogs' -Recurse -Filter 'results.json' -ErrorAction SilentlyContinue |
    Where-Object { $_.LastWriteTime -gt $scanStart } |
    Sort-Object LastWriteTime -Descending |
    Select-Object -First 1

if ($resultsFile) {
    $json = Get-Content -Path $resultsFile.FullName -Raw -Encoding UTF8 -ErrorAction SilentlyContinue
    if ($json) {
        # Compress to single line so the agent's stdout parser sees it as one line
        $compressed = ($json | ConvertFrom-Json | ConvertTo-Json -Depth 10 -Compress)
        Write-Output ''
        Write-Output "GURUSCAN_RESULT_JSON:$compressed"
    }
}
