Dynamic Windows Event Channels

An automated PowerShell script to dynamically build, scale, and separate your Windows Event Forwarding (WEF) streams.

GitHub

Overview#

If you work in enterprise security, setting up a Windows Event Forwarding (WEF) architecture is one of the best ways to centralize logs without paying a premium for third-party agents. However, standard WEF configurations often force you to dump every forwarded log into a single generic bucket like ForwardedEvents.

When managing dozens or hundreds of critical systems (like Domain Controllers), mixing all their logs into one massive stream is a recipe for performance bottlenecks and search delays.

The ultimate solution? Create custom Windows Event Channels for individual servers dynamically.

In this post, we’ll look at an automated PowerShell script that dynamically builds custom Event Log providers, compiles resource DLLs using the Windows SDK, and automatically scales event channels to separate your WEF streams perfectly.

The Prerequisites: Getting the Right Tools#

Before running a script like this, you need the underlying compilation tools. Windows doesn’t ship with resource compilers by default.

  1. Download and install the Windows SDK.
  2. Go through the standard installation wizard.
  3. Make sure the installation path matches your script’s paths (by default, it installs to C:\Program Files (x86)\Windows Kits\10\bin…).

Behind the Scenes: How the Automation Works#

This PowerShell script relies on a clever combination of dynamic XML generation, the .NET compiler, and native Windows Event utilities to completely bypass built-in OS limitations. Here is exactly how the automation handles the heavy lifting:

  1. Breaking the Legacy 8-Channel Barrier
  1. Sanitizing Internal XML Symbols

A common pitfall when compiling event manifests manually is naming conventions. If a server name starts with a number (like 1NTWIN-server), the Windows compiler will throw a fit and error out. The script includes built-in sanitization logic that detects numeric prefixes and automatically adds an underscore (e.g., _1NTWIN-server) to the internal XML symbol. This keeps the compiler happy while leaving the actual, visible log channel name exactly as you intended.

  1. Evading File Locks during Upgrades If you need to add new servers to your list later, updating an active logging DLL can be incredibly frustrating because the Windows OS aggressively locks the file. To bypass this, the script automatically unregisters the old manifest using wevtutil um before attempting to compile. This forces the operating system to release its file locks, allowing a fresh all-servers.dll to be compiled using the .NET framework (csc.exe) without errors.

⚙️ Post-Deployment Tuning

Once the script registers the new channels with the operating system, it loops through each server log to apply critical enterprise configurations:

🎯 Conclusion

By isolating your server logs into dedicated channels rather than dumping everything into ForwardedEvents, you eliminate indexing bottlenecks and significantly speed up your incident response times.

Best of all, because the infrastructure generation is completely automated into this PowerShell script, expanding your monitoring environment is as simple as adding a new server name to the array and running it again!