Public/Invoke-OffsetThreatScanBatch.ps1
|
function Invoke-OffsetThreatScanBatch { <# .SYNOPSIS Runs Invoke-OffsetThreatScan across many files and returns the collected results. .DESCRIPTION Expands the supplied files, directories, and wildcards into a file list, scans each with the selected provider, and returns the OffsetInspect.ThreatScanResult objects. A per-file scan failure does not abort the batch; it is returned as a result with Success = $false. The output pipes directly into Export-OffsetThreatReport. Like the single-file command, provider scanning is Windows-only. .PARAMETER Path One or more files, directories, or wildcard patterns to scan. .PARAMETER Recurse Recurse into subdirectories when a path resolves to a directory. .PARAMETER Filter Wildcard filter applied when enumerating directories (default '*'). .PARAMETER Summary Return a flattened detection matrix (one row per file) instead of the full result objects. .EXAMPLE Invoke-OffsetThreatScanBatch ./payloads -Recurse -Engine AMSI | Export-OffsetThreatReport -Path ./engagement.html -Format Html .EXAMPLE Invoke-OffsetThreatScanBatch ./samples -Summary | Format-Table File, DetectionPrefixLength, Confidence #> [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] [ValidateNotNullOrEmpty()] [string[]]$Path, [switch]$Recurse, [ValidateNotNullOrEmpty()] [string]$Filter = '*', [ValidateSet('Auto', 'AMSI', 'Defender')] [string]$Engine = 'Auto', [ValidateSet('Auto', 'RawBytes', 'Text')] [string]$ScanMode = 'Auto', [ValidateSet('Auto', 'Default', 'UTF8', 'UTF16LE', 'UTF16BE', 'ASCII')] [string]$Encoding = 'Auto', [ValidateRange(1, 10)] [int]$RepeatCount = 2, [ValidateRange(1, 600)] [int]$TimeoutSeconds = 30, [switch]$IncludeProviderOutput, [switch]$NoProgress, [switch]$Summary ) begin { $inputPaths = New-Object 'System.Collections.Generic.List[string]' } process { foreach ($item in $Path) { if (-not [string]::IsNullOrWhiteSpace($item)) { $inputPaths.Add($item) } } } end { if (-not (Test-OIIsWindows)) { throw 'Threat-provider scanning is supported only on Windows. Offset inspection remains cross-platform.' } $targets = @(Resolve-OIBatchTarget -Path $inputPaths.ToArray() -Recurse:$Recurse -Filter $Filter) if ($targets.Count -eq 0) { Write-Warning 'No files matched the batch selection.' return } $results = New-Object 'System.Collections.Generic.List[object]' $index = 0 foreach ($target in $targets) { $index++ if (-not $NoProgress) { Write-Progress -Activity 'Batch threat scan' -Status $target -PercentComplete ([int](100.0 * $index / $targets.Count)) } Write-Verbose "Scanning ($index/$($targets.Count)): $target" $scanParameters = @{ FilePath = $target Engine = $Engine ScanMode = $ScanMode Encoding = $Encoding RepeatCount = $RepeatCount TimeoutSeconds = $TimeoutSeconds NoProgress = $true PassThru = $true } if ($IncludeProviderOutput) { $scanParameters.IncludeProviderOutput = $true } try { $results.Add((Invoke-OffsetThreatScan @scanParameters)) } catch { $failure = [pscustomobject]@{ Success = $false File = $target FileSize = $null FileSha256 = $null ScanTimestampUtc = [DateTime]::UtcNow.ToString('o') Engine = $Engine ScanMode = $ScanMode BoundaryUnit = $null SearchModel = 'MonotonicPrefixTransition' Encoding = $null InitialStatus = $null DetectionPrefixLength = $null DetectionBoundaryOffset = $null DetectionBoundaryHex = $null DetectionCharacterIndex = $null DetectionUtf16CodeUnitIndex = $null KnownCleanPrefixLength = $null Stable = $false Confidence = 'None' ScanCount = 0 SignatureName = $null ProviderResult = $null ProviderHResult = $null ProviderMetadata = $null BoundaryValidation = $null ProviderOutput = $null ProbeLog = @() Inspection = $null DurationMs = 0 Warnings = @() Error = $_.Exception.Message } $failure.PSObject.TypeNames.Insert(0, 'OffsetInspect.ThreatScanResult') $results.Add($failure) } } if (-not $NoProgress) { Write-Progress -Activity 'Batch threat scan' -Completed } $collected = $results.ToArray() if ($Summary) { return @($collected | ForEach-Object { ConvertTo-OIFlatThreatResult -Result $_ }) } return $collected } } |