Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Archives
Subscribe
December 5, 2025

EventLog Eventing

In this issue:

  • Classic Event Logs
    • Win32_NTEventLogFile
    • Registering a CimIndication Event
    • The Event Log Event
    • Event Queue Reporting
  • Getting Granular
    • Creating a Popup Alert
  • Summary

A few months ago, we spent some time looking at scripting with events in PowerShell. I thought we would return to the subject and look at another specific type of eventing, that of the Windows Event Log. The name gives it away. When something of importance happens on a Windows system, it usually triggers an event which is written to an event log. The act of writing the event log is itself an event, which means you can "handle" it with PowerShell.

Classic Event Logs

Let's start by looking at the classic event logs. These are the Application, System, and Security logs that have been around since the early days of Windows. However, you most likely have other classic event logs on your system as well. To see, you need to run Get-EventLog in a Windows PowerShell session.

PS C:\> Get-Eventlog -List

  Max(K) Retain OverflowAction        Entries Log
  ------ ------ --------------        ------- ---
  20,480      0 OverwriteAsNeeded      32,008 Application
  20,480      0 OverwriteAsNeeded           0 HardwareEvents
     512      7 OverwriteOlder              0 Internet Explorer
  20,480      0 OverwriteAsNeeded           0 Key Management Service
     128      0 OverwriteAsNeeded         104 OAlerts
  20,480      0 OverwriteAsNeeded      22,448 Security
  20,480      0 OverwriteAsNeeded      44,365 System
     512      7 OverwriteOlder              0 Visual Studio
  15,360      0 OverwriteAsNeeded       8,448 Windows PowerShell

You might have a different list.

Win32_NTEventLogFile

These logs are also represented in WMI as instances of the Win32_NTEventLogFile class.

PS C:\>Get-CimInstance Win32_NTEventLogFile -filter "NumberOfRecords>0"

FileSize LogfileName        Name                                                    NumberOfRecords
-------- -----------        ----                                                    ---------------
18944000 Application        C:\Windows\System32\Winevt\Logs\Application.evtx                  32008
   69632 OAlerts            C:\Windows\System32\Winevt\Logs\OAlerts.evtx                        104
20975616 Security           C:\Windows\System32\Winevt\Logs\Security.evtx                     22448
20975616 System             C:\Windows\System32\Winevt\Logs\System.evtx                       44365
15732736 Windows PowerShell C:\Windows\System32\Winevt\Logs\Windows PowerShell.evtx            8441

I decided to filter out logs with no entries.

Registering a CimIndication Event

Because these are items we can query with WMI/CIM, we can also register for events when new entries are created. The class we need to monitor is Win32_NTLogEvent. Here is an example of how to register for such an event.

$query = "Select * from __InstanceCreationEvent within 10 WHERE TargetInstance ISA 'Win32_NTLogEvent'"
Register-CimIndicationEvent -Query $query -MessageData "An event was logged" -SourceIdentifier "WatchEventLog"

This event subscription is watching for a new entry in any of the classic event logs. It won't take very long.

PS C:\> Get-Event | measure | select count

Count
-----
   14

The Event Log Event

Let's take a look at what we get.

PS C:\> $e = Get-Event -SourceIdentifier WatchEventLog | Select-Object -first 1
PS C:\> $e

ComputerName     :
RunspaceId       : 95abc90c-7b43-4361-aecd-f3f48348245f
EventIdentifier  : 1
Sender           : Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationWatcher
SourceEventArgs  : Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationEventInstanceEventArgs
SourceArgs       : {Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationWatcher, }
SourceIdentifier : WatchEventLog
TimeGenerated    : 12/5/2025 8:23:43 AM
MessageData      : An event was logged

This should look familiar.

As before, the SourceEventArgs property contains the actual event data. Let's look at the event itself.

PS C:\> $e.SourceEventArgs

NewEvent                MachineId Bookmark Context
--------                --------- -------- -------
__InstanceCreationEvent

PS C:\> $e.SourceEventArgs.NewEvent

SECURITY_DESCRIPTOR           TIME_CREATED TargetInstance
-------------------           ------------ --------------
{1, 0, 20, 128…}    134094146238642051 Win32_NTLogEvent (Logfile = "Windows PowerShell", RecordNumber = 1522474)

Fortunately, we don't need to translate the TIME_CREATED value because we can use the TimeGenerated property of the event object.

Finally, let's look at the actual event log entry that was created.

PS C:\> $e.SourceEventArgs.NewEvent.TargetInstance

PS C:\> $e.SourceEventArgs.NewEvent.TargetInstance

Category         : 6
CategoryString   : Provider Lifecycle
ComputerName     : Cadenza
Data             :
EventCode        : 600
EventIdentifier  : 600
EventType        : 3
InsertionStrings : {Registry, Started, ProviderName=Registry
                   NewProviderState=Started

                   SequenceNumber=1

                   HostName=ConsoleHost
                   HostVersion=5.1.26100.7309
                   HostId=d2bf3742-a83a-4001-bf3f-18d7c6aeed85
                   HostApplication=C:\Windows\system32\WindowsPowerShell\v1.0\p
                   owershell.exe -ExecutionPolicy Bypass -NoProfile
                   -NonInteractive -File C:\ProgramData\Lenovo\Vantage\Addins\Le
                   novoSystemUpdateAddin\1.0.28.16\resources\DMC_PM\Off_DMC.ps1
                   EngineVersion=
                   RunspaceId=
                   PipelineId=
                   CommandName=
                   CommandType=
                   ScriptName=
                   CommandPath=
                   CommandLine=}
Logfile          : Windows PowerShell
Message          : Provider "Registry" is Started.

                   Details:
                   ProviderName=Registry
                   NewProviderState=Started

                   SequenceNumber=1

                   HostName=ConsoleHost
                   HostVersion=5.1.26100.7309
                   HostId=d2bf3742-a83a-4001-bf3f-18d7c6aeed85
                   HostApplication=C:\Windows\system32\WindowsPowerShell\v1.0\p
                   owershell.exe -ExecutionPolicy Bypass -NoProfile
                   -NonInteractive -File C:\ProgramData\Lenovo\Vantage\Addins\Le
                   novoSystemUpdateAddin\1.0.28.16\resources\DMC_PM\Off_DMC.ps1
                   EngineVersion=
                   RunspaceId=
                   PipelineId=
                   CommandName=
                   CommandType=
                   ScriptName=
                   CommandPath=
                   CommandLine=
RecordNumber     : 1522474
SourceName       : PowerShell
TimeGenerated    : 12/5/2025 8:23:43 AM
TimeWritten      : 12/5/2025 8:23:43 AM
Type             : Information
User             :
PSComputerName   :
Want to read the full issue?
GitHub
Bluesky
LinkedIn
Mastodon
Website favicon
Powered by Buttondown, the easiest way to start and grow your newsletter.