Search code examples
powershellevent-log

Set placeholder %2, %3, ... in Windows Event Log with PowerShell


Background

To write error logs to Windows Event Viewer in PowerShell script, I've found a suitable source Application Error and event ID 1000.

When you call Write-EventLog -LogName "Application" -Source "Application Error" -EventId "1000" -Message "TEST MESSAGE", the event log message will be like this:

Faulting application name: TEST MESSAGE, version: %2, time stamp: 0x%3
Faulting module name: %4, version: %5, time stamp: 0x%6
Exception code: 0x%7
Fault offset: 0x%8
Faulting process id: 0x%9
Faulting application start time: 0x%10
Faulting application path: %11
Faulting module path: %12
Report Id: %13
Faulting package full name: %14
Faulting package-relative application ID: %15

Problem

I couldn't find a way to set parameters %2, %3, ... properly from Write-EventLog.

  • The -Message parameter is set to %1 as a string.
  • The -RawData parameter is set to %2, but it is interpreted as a hex string. For example, when you pass parameter -RawData $utf8Encoding.GetBytes("1.2.7"), the message is shown like version: 312E322E37. I expected the result like version: 1.2.7.

Question

Is there any way to set parameters %2, %3, ... in messages of Windows Event Log with PowerShell?

Edit:

New-WinEvent can't handle more than 8 parameters:

PS C:\> New-WinEvent -ProviderName "Application Error" -Id 1000 -Payload @(
>>         'DummyApp.exe',                            # Application name
>>         '1.2.3.4',                                 # Application version
>>         '12345678',                                # Time stamp
>>         'dummyModule.dll',                         # Faulting module name
>>         '2.3.4.5',                                 # Module version
>>         '87654321',                                # Module time stamp
>>         'c0000005',                                # Exception code
>>         '0000000000012345',                        # Fault offset
>>         '0x1234',                                  # Process ID
>>         '0x5D3E7F22',                              # Application start time
>>         'C:\Program Files\DummyApp\DummyApp.exe',  # Application path
>>         'C:\Windows\System32\dummyModule.dll',     # Module path
>>         'dummy-report-id',                         # Report ID
>>         'dummy-package-name',                      # Faulting package full name
>>         'dummy-app-id'                             # Faulting package-relative application ID
>>     )
New-WinEvent : The number of String parameters must not exceed 8.
Parameter name: eventPayload
At line:1 char:1
+ New-WinEvent -ProviderName "Application Error" -Id 1000 -Payload @(
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [New-WinEvent], ArgumentOutOfRangeException
    + FullyQualifiedErrorId : System.ArgumentOutOfRangeException,Microsoft.PowerShell.Commands.NewWinEventCommand

When you pass just 8 parametes to this event ID, you will get the following error:

PS C:\> New-WinEvent -ProviderName "Application Error" -Id 1000 -Payload @(
>>         'DummyApp.exe',                            # Application name
>>         '1.2.3.4',                                 # Application version
>>         '12345678',                                # Time stamp
>>         'dummyModule.dll',                         # Faulting module name
>>         '2.3.4.5',                                 # Module version
>>         '87654321',                                # Module time stamp
>>         'c0000005',                                # Exception code
>>         '0000000000012345'                         # Fault offset
>> )
WARNING: Provided payload does not match with the template that was defined for event id 1000.
The defined template is following:
<template xmlns="http://schemas.microsoft.com/win/2004/08/events">
  <data name="AppName" inType="win:UnicodeString" outType="xs:string"/>
  <data name="AppVersion" inType="win:UnicodeString" outType="xs:string"/>
  <data name="AppTimeStamp" inType="win:UnicodeString" outType="xs:string"/>
  <data name="ModuleName" inType="win:UnicodeString" outType="xs:string"/>
  <data name="ModuleVersion" inType="win:UnicodeString" outType="xs:string"/>
  <data name="ModuleTimeStamp" inType="win:UnicodeString" outType="xs:string"/>
  <data name="ExceptionCode" inType="win:UnicodeString" outType="xs:string"/>
  <data name="FaultingOffset" inType="win:UnicodeString" outType="xs:string"/>
  <data name="ProcessId" inType="win:HexInt32" outType="win:HexInt32"/>
  <data name="ProcessCreationTime" inType="win:HexInt64" outType="win:HexInt64"/>
  <data name="AppPath" inType="win:UnicodeString" outType="xs:string"/>
  <data name="ModulePath" inType="win:UnicodeString" outType="xs:string"/>
  <data name="IntegratorReportId" inType="win:UnicodeString" outType="xs:string"/>
  <data name="PackageFullName" inType="win:UnicodeString" outType="xs:string"/>
  <data name="PackageRelativeAppId" inType="win:UnicodeString" outType="xs:string"/>
</template>

Solution

  • The Write-EventLog command seems to be limited in regards to passing provider-specific parameters with a message. You can use the .NET API System.Diagnostic.EventLog instead:

    # Create an EventLog instance for the Application log
    $eventLog = [System.Diagnostics.EventLog]::new('Application')
    $eventLog.Source = 'Application Error'
    
    # Write the event with parameters
    $eventLog.WriteEvent(
        [System.Diagnostics.EventInstance]::new(1000, 0, [System.Diagnostics.EventLogEntryType]::Error),
        @(
            'DummyApp.exe',                            # Application name
            '1.2.3.4',                                 # Application version
            '12345678',                                # Time stamp
            'dummyModule.dll',                         # Faulting module name
            '2.3.4.5',                                 # Module version
            '87654321',                                # Module time stamp
            'c0000005',                                # Exception code
            '0000000000012345',                        # Fault offset
            '0x1234',                                  # Process ID
            '0x5D3E7F22',                              # Application start time 
            'C:\Program Files\DummyApp\DummyApp.exe',  # Application path
            'C:\Windows\System32\dummyModule.dll',     # Module path
            'dummy-report-id',                         # Report ID
            'dummy-package-name',                      # Faulting package full name
            'dummy-app-id'                             # Faulting package-relative application ID
        )
    )