Coverage Assessment

The ICS Watch Dog coverage toolchain helps you measure how well your Sysmon configuration fits your actual system, identify gaps, and track changes over time. It consists of three scripts that work together: capture, measure, compare.

The Three Tools

ScriptPurposePS Version
Export-SystemInventory.ps1 Captures what is running on a system (processes, software, ports, services) and writes it to a JSON file. 2.0+ (Console/Markdown), 3.0+ (JSON)
Get-SysmonCoverage.ps1 Measures how much of a system's inventory is covered by a Sysmon configuration. Reports four metrics: process, software, port, and ATT&CK technique coverage. 2.0+ (Console/Markdown), 3.0+ (JSON)
Compare-SystemInventory.ps1 Diffs two inventory JSON files and reports what was added or removed. Useful after patches, software installs, or for comparing two hosts. 3.0+ (requires JSON input)

All three scripts are read-only. They do not modify the system, probe the network, or require external dependencies.

Quick Start

Live system coverage (interactive)

.\Get-SysmonCoverage.ps1 -ConfigPath sysmonconfig-baseline-ot.xml

What-if with additional modules

.\Get-SysmonCoverage.ps1 `
    -ConfigPath sysmonconfig-baseline-ot.xml `
    -AdditionalModules @(
        'modules\vendor-ot\siemens-tia-portal.xml',
        'modules\protocol\modbus-tcp.xml') `
    -OutputFormat Markdown -OutputPath coverage-report.md

Capture inventory for offline analysis

.\Export-SystemInventory.ps1 -OutputPath my-system.json

Analyze a captured inventory on another machine

.\Get-SysmonCoverage.ps1 -ConfigPath sysmonconfig-baseline-ot.xml -InventoryPath my-system.json

The Workflow

  1. Baseline -- Run Get-SysmonCoverage.ps1 against your current config. Record the coverage percentages.
  2. Identify gaps -- Review the gap report: unmonitored processes, uncovered OT software, unmatched industrial ports.
  3. Try modules -- Use -AdditionalModules to project what coverage would look like with specific modules added. No config changes needed.
  4. Merge -- When satisfied, use Merge-SysmonModules.ps1 to build your deployment config.
  5. Re-measure -- Run coverage again against the merged config to confirm gaps closed.

For locked-down OT hosts, use the offline workflow: capture inventory with Export-SystemInventory.ps1 on the target host, transfer the JSON file, and run Get-SysmonCoverage.ps1 -InventoryPath on your analysis workstation.

Reading the Coverage Report

Process Coverage

Fraction of running processes matched by at least one rule in the config. A low percentage on baseline-ot is expected -- the baseline intentionally avoids vendor-specific rules to minimize false positives. Adding vendor modules (Siemens, Rockwell, etc.) increases process coverage for systems running that software.

OT Software Coverage

Fraction of installed OT-relevant software (matched by vendor name) that has a corresponding module. The gap report suggests which module to add for each uncovered vendor.

Industrial Port Coverage

Fraction of listening industrial protocol ports (Modbus 502, OPC-UA 4840, etc.) matched by a protocol detection rule. Adding protocol modules closes these gaps.

ATT&CK Technique Coverage

Count of distinct MITRE ATT&CK technique IDs found in the deployed rules. Not a percentage -- there is no universal denominator. More techniques means broader detection.

Honest Interpretation

Coverage percentages are fit indicators, not grades.

Output Formats

All three scripts support -OutputFormat Console (default), JSON, and Markdown.

FormatUse CasePS 2.0
ConsoleInteractive review in a terminalYes
JSONAutomation, pipelines, SIEM ingestPS 3.0+ only
MarkdownAI analysis, tickets, documentationYes

Use -OutputPath to write to a file instead of the screen.

Comparing Inventories

Compare-SystemInventory.ps1 diffs two inventory JSON files and reports only the changes (added and removed items per category).

.\Compare-SystemInventory.ps1 -ReferencePath before.json -DifferencePath after.json

Use cases: tracking changes after a patch, comparing a lab host to a production host, reviewing a community-submitted inventory against your reference.

Contributing Inventories

Sanitized system inventories help the project build better modules and configs for real OT environments. To submit an inventory:

  1. Export with redaction: .\Export-SystemInventory.ps1 -OutputPath my-system.json -Redact
  2. Review the JSON manually. The -Redact flag strips usernames from paths and omits the hostname, but cannot catch everything (project names, custom service names, license keys in display names).
  3. Submit via GitHub issue as a feature request, or include with a pull request for a new module.

For building new detection modules based on your coverage gaps, see the Build Your Own Module guide (coming soon).

Limitations

Troubleshooting

IssueCauseFix
"JSON output requires PowerShell 3.0 or later" Running on Windows 7 / PS 2.0 Use -OutputFormat Console or Markdown
0 processes found Insufficient privileges to enumerate processes Run as Administrator or a user with process-read permissions
0 listening ports Get-NetTCPConnection unavailable and netstat fallback failed Ensure the script can run netstat -ano
ExecutionPolicy error Script execution is restricted Run with -ExecutionPolicy Bypass or set policy to RemoteSigned

Next: Found gaps? Build your own module to close them, or browse the Module Library for existing modules. Validate your detection with Efficacy Testing.