Library / SDK
EvotecIT/EventViewerX avatar
EvotecIT/EventViewerX

EventViewerX and the two ways to read a Windows Event Log

Windows Event Log tooling for PowerShell and .NET: typed queries, reporting, export, WEC, automation, and the PSEventViewer module.

732 stars69 forksC#MIT

At a glance

What is it?
EventViewerX is a reusable C# engine for Windows Event Log work with a thin PowerShell surface on top, PSEventViewer, and it has recently absorbed the PSWinReporting lines into one repository. The interesting engineering is in how it handles files that were saved rather than streamed, where a portable adapter trades fidelity of provider messages for running on Linux and macOS.
Who is it for?
EventViewerX fits a Windows operations team that needs typed, filterable event queries, bounded export and reproducible investigation sessions, and a team that has been carrying PSWinReportingV2 forward and wants it to land in one maintained place. It is the wrong tool if you only want to read a log with Get-WinEvent, and the wrong tool for a Linux-only shop that has no need for the Windows Event Log semantics at all.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 12 days ago.
What is it written in?
Mainly C#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One engine, one thin PowerShell layer

The project's own framing is the clearest description of the design. PSEventViewer is the thin PowerShell surface, EventViewerX is the reusable C# engine underneath it, and the two layers sit on the Windows Event Log APIs for live channels, remote sessions, WEC, provider messages and Windows configuration.

That separation is the point. A PowerShell module that wraps a .NET library can be used by PowerShell users and by .NET developers at the same time, and the PowerShell function names and the library types do not have to drift apart, because the module is a surface over the engine rather than a parallel implementation. The package names state the same thing: PowerShell users install `PSEventViewer`, and .NET users reference the `EventViewerX` packages.

The feature list in the readme shows what the engine exposes. It streams local channels, remote channels, offline EVTX files, or structured QueryList XML without accumulating the complete result, which is the difference between a tool you can point at a busy server and one that exhausts memory. Filtering by event ID, provider, time, record ID, level, keyword, user and event data is pushed into the Windows query engine rather than applied in managed code after the fact.

The projection is granular as well. You can choose exactly how much work each record needs: metadata, a formatted message, a structured payload, or the complete projection. That is a meaningful choice on a production server where formatting a provider message for every record in a Security channel is expensive and often unnecessary.

There is also a multi-host path. Several hosts, channels or files can be queried concurrently and the results merged in a deterministic order with bounded memory, which is what a monitoring job across a domain actually needs.

Saved EVTX files are where the interesting decisions are

The readme defines its terms carefully, and the definition is worth repeating because it determines what you get.

In this project, offline means reading a saved `.evtx` file instead of an active channel. The default saved-file path still uses Windows Eventing APIs. So a saved file is not automatically the portable path; the portable path is a separate, explicitly selected adapter.

That adapter is `EventViewerX.Evtx`, an optional dependency-backed adapter for Linux, macOS and Windows. It plugs into the core `ISavedEventReader` contract, which means it feeds the same typed projection, detection, reporting and storage pipeline as the Windows path. The separate package exists because it adds a third-party `evtx` parser and its dependencies, and there is no `EventViewerX.Offline` package, a naming decision the readme explains in one line.

The cost of that portability is stated with unusual precision. Both portable adapters omit provider-formatted messages and support standard XPath 1.0 rather than every Windows Event Log XPath extension. So if your query relies on the full Windows XPath dialect, or your workflow reads the rendered message text, the portable path is not equivalent.

There is also a managed alternative, `EvtxSavedEventReader`, which requires no external executable. It is opt-in because its current allocation cost misses the production performance gate. On a 31.5 MB Security fixture it preserved all 62,031 records and reached 100% identity parity with Windows, but processed about 5,364 events per second with roughly 720 KB allocated per event, against 41,719 events per second and 3.5 KB per event for the Windows path.

So the managed adapter is faithful and slow, and the Windows path is fast and native. The readme also notes that the larger fixture measurements describe the earlier baseline, and that the managed adapter remains opt-in.

Templates, XML contracts and the cost of a formatting pass

The document format deserves a note because it is where a surprising amount of allocation goes.

Managed template records use compact XML with the original event namespace. The guidance is to use namespace-aware XML queries or the normalized `Data` and metadata fields, and to treat raw XML whitespace and namespace declarations as not a stable serialization contract. The stated reason is concrete: avoiding an additional XML formatting pass reduced allocation by about 40% on the retained 184-record fixture.

That is a design decision with a user visible consequence. A consumer that parses the raw XML of a managed template record and depends on the exact whitespace or on the presence of particular namespace declarations will break, because those are explicitly not part of the contract. The supported surface is the structured fields.

There is also a deliberate choice about content fidelity. The adapter preserves special characters and XML-valid whitespace instead of applying the dependency's display-oriented string cleanup, which is the right call for an evidence tool and the wrong call if you want text formatted for reading.

Two further adapters exist for the harder cases. The managed adapter recognizes literal BinXML records produced by rendered WEC subscriptions and routes them through a bounded, spec-aligned EVX reader, preserving all 653 records from the archived ForwardedEvents fidelity fixture with complete identity parity. `EvtxDumpSavedEventReader` remains an explicit alternate parser that executes a caller-owned `evtx_dump` path, never downloads or updates the tool, and normalises streaming JSONL into the same EVX contracts. Its timestamps are precise to one microsecond rather than the final 100-nanosecond FILETIME digit, and the retained truncated fixture is handled only by the managed adapter.

The instruction that follows from all this is to keep diagnostics enabled for either engine.

Two projects folded into one repository in August 2026

The repository's structure is the result of a consolidation, and understanding it explains the naming you will encounter in existing deployments.

PSWinReporting began as an Active Directory event-reporting module. Its second generation, PSWinReportingV2, broadened that work, while PSEventViewer grew into the focused PowerShell module and reusable EventViewerX .NET engine used for modern Windows Event Log automation. The readme states plainly that those projects increasingly solved the same problems from different starting points.

In August 2026, the PSWinReporting and PSWinReportingV2 lines were frozen and folded into the PSEventViewer and EventViewerX home. Two details about how that was done matter for anyone with existing automation. The Git histories were preserved rather than copied as a source-only snapshot, so the history of the old projects is still navigable. And the former `EvotecIT/PSWinReporting` repository was renamed to `EvotecIT/EventViewerX`, with the old PSWinReporting URL redirecting to it, while the former PSEventViewer repository is now an archive that points here.

The installed names did not change, which was clearly deliberate. PowerShell users still install `PSEventViewer`, .NET users still reference the `EventViewerX` packages, and `PSWinReporting` and `PSWinReportingV2` remain available as frozen packages for existing deployments, with new development belonging in the consolidated repository.

The final frozen sources stay reachable on dedicated branches. The `PSWinReporting` branch holds the final 1.x release, version 1.8.1.7, and the `PSWinReportingV2` branch holds the final 2.x release, version 2.0.24. The `master` branch is the active home of PSEventViewer and EventViewerX.

So the migration story for an existing user is: nothing breaks, the packages keep their names, and the code you are missing now lives in one place.

What the engine adds beyond the built-in Windows tooling

The readme lists a set of capabilities that go past what a query cmdlet gives you, and they cluster around investigation work rather than around reading logs.

Export is the first. You can export directly to CSV, JSON Lines, XML or native EVTX without passing one PowerShell object per event through a file pipeline. That is a throughput difference rather than a formatting preference, since the alternative is turning every event into as a PowerShell object before it is written.

The second cluster is state and lifecycle: native bookmarks, durable record checkpoints, subscriptions, watchers, provider and channel catalogs, classic log management, WEC subscription management, and both classic and manifest event writing. Checkpoints and watchers are what make a long running collection possible, and they are the pieces that let a session resume where it left off rather than re-reading from the beginning.

The third is built-in typed event definitions and composite workflows for things like failed logons, lockouts, group changes, Kerberos failures, AAD Connect health, IIS failures and OS crashes. These are detections expressed as data rather than as a script you write each time, and the project talks about versioned native detections and rule-change previews.

The repository also carries a separate document, INVESTIGATIONS.md, which covers portable evidence sessions, bounded detection checkpoints, coverage-aware absence, watcher draining, rule-change previews and clock uncertainty. That title, coverage-aware absence, is the kind of thing a general log viewer does not think about. Knowing that a thing did not happen, and being able to say so, requires knowing what you looked at and when, which is a different question from finding a record.

There is a second document, `Docs/Endpoint-Investigations.md`, for captured endpoint investigations, which combines bounded CMTrace and IME log reading, contextual error-code interpretation, application-attempt analysis, DSRegCmd triage and evidence-backed next checks in one verified session format.

Where the tooling stops being the right tool

Two boundaries are worth being clear about, one of them a cost and one of them a design choice.

The first is that most of this only makes sense on Windows. The engine drives the Windows Event Log APIs for live channels, remote sessions, WEC, provider messages and Windows configuration, and the default saved-file path still uses Windows Eventing APIs. The portable adapters exist to read saved files on Linux and macOS, and they are explicitly a reduced version: no provider-formatted messages, standard XPath 1.0 only. So a Linux shop with no Windows estate has no use for the majority of this, and a mixed shop has to decide which adapter each job uses.

The second is the fidelity versus speed trade, and it is not free in either direction. The managed saved-file reader is faithful and misses the production performance gate by a wide margin, roughly 5,364 events per second and 720 KB per event against 41,719 and 3.5 KB. The portable parser is faster in the sense that it runs anywhere, but it drops the provider messages. The `evtx_dump` alternate trades the last digit of timestamp precision for a different operational model, an external executable you have to supply and that the tool will never download or update for you.

There is a third practical limit, and it is the one that decides whether a team keeps the tool. The managed template record format is not a stable serialisation contract for raw XML, so anything downstream that parses the XML directly, rather than using the typed fields, will need to change. That is a one-time migration cost, but it is a real one, and it applies to a pipeline that is otherwise happy.

For a one-off question about a log file, none of this is worth it. `Get-WinEvent` answers that. This tooling earns its place when the questions are about evidence, coverage and reproducibility over time.

Against the built-in cmdlets, the difference is the session model

The alternative is the Windows tooling that ships with the operating system, and the difference in approach is about what a query means.

The built-in cmdlets give you records. A filter, a pipeline, some formatting. That model is fine for looking at an event and terrible for building a case, because a pipeline has no notion of what you looked at, when you looked at it, or what you did not find. If you are investigating whether a particular thing happened, a pipeline cannot tell you that the absence of a record is meaningful, because it has no record of the search itself.

EventViewerX is built around the session. Bookmarks, durable record checkpoints, watchers, subscriptions, coverage-aware absence, rule-change previews. Each of those says something about the state of an investigation rather than about the content of a log, and that is a different kind of artefact from a list of events.

The export story is the second difference. Direct export to CSV, JSON Lines, XML or native EVTX avoids routing every event through a PowerShell object, which is both faster and produces output that another tool can consume without a translation step. For evidence work, a native EVTX export that re-opens in the standard tools is worth a lot.

The cost of choosing this over the built-ins is a dependency on a project with a consolidation in its recent history and a recently consolidated module family in the middle of it. The PSWinReporting freeze was a merge rather than a rewrite, and the frozen branches still exist for anyone who needs to stay where they were. That is a well-managed consolidation, but it is also a signal that the surface area is larger than one focused tool.

The honest summary is that the built-in cmdlets are the right answer for reading events, and this is the right answer for investigating them.

Editorial conclusion

EventViewerX fits a Windows operations team that needs typed, filterable event queries, bounded export and reproducible investigation sessions, and a team that has been carrying PSWinReportingV2 forward and wants it to land in one maintained place. It is the wrong tool if you only want to read a log with Get-WinEvent, and the wrong tool for a Linux-only shop that has no need for the Windows Event Log semantics at all. Before adopting, verify three things: which adapter you are actually getting, since the managed saved-file reader is opt-in because it misses the production performance gate, whether your workflow depends on provider-formatted messages, which the portable adapters omit, and what XPath dialect you need, since the adapters support standard XPath 1.0 rather than every Windows Event Log extension. The code is MIT licensed, the last push was on 2026-10-11, and the PSEventViewer release is 4.0.1 from 2026-09-29.

Frequently asked questions

What is the difference between PSEventViewer and EventViewerX?

PSEventViewer is the thin PowerShell surface and EventViewerX is the reusable C# engine underneath it. PowerShell users install `PSEventViewer` and .NET users reference the `EventViewerX` packages, and both drive the same Windows Event Log APIs.

What happened to PSWinReporting and PSWinReportingV2?

In August 2026 the PSWinReporting and PSWinReportingV2 lines were frozen and folded into the PSEventViewer and EventViewerX home, with their Git histories preserved rather than copied. The old package names remain available as frozen packages for existing deployments, and the final 1.x and 2.x sources stay on dedicated branches.

Can EventViewerX read saved EVTX files on Linux and macOS?

Yes, through the optional `EventViewerX.Evtx` adapter, which plugs into the core `ISavedEventReader` contract. The portable adapters omit provider-formatted messages and support standard XPath 1.0 rather than every Windows Event Log XPath extension.

Why is the managed saved-file reader opt-in?

Because its current allocation cost misses the production performance gate. On a 31.5 MB Security fixture it preserved all 62,031 records with 100% identity parity with Windows but processed about 5,364 events per second with roughly 720 KB allocated per event, against 41,719 events per second and 3.5 KB per event for the Windows path.

What does EventViewerX export to?

You can export directly to CSV, JSON Lines, XML or native EVTX, without passing one PowerShell object per event through a file pipeline. The engine also supports native bookmarks, durable record checkpoints, subscriptions, watchers, provider and channel catalogs, and WEC subscription management.

Official sources

  1. EvotecIT/EventViewerX on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/evotecit-eventviewerx.svg)](https://hysenlabs.com/projects/evotecit-eventviewerx)

Was this useful?