How do I use PowerShell to create an event in a Windows log?
Table of Contents
I. Introduction
In this tutorial, we'll use PowerShell to create a custom log and custom events in the Windows or Windows Server Event Viewer, using two cmdlets: New-EventLog and Write-EventLog. In addition, we'll look at how to use the .NET "EventLog" class to create advanced entries.
On Windows, the operating system, components and applications can generate events that are recorded in the various logs centralized in the Event Viewer. These logs are a mine of information for system administrators, but also for security teams: a suspicious action can be recorded in an event, which then represents an interesting trace.
The next step is to collect these events in a log sink or SIEM, in order to analyze them and detect suspicious behavior or anomalies on an infrastructure.
Thanks to the Write-EventLog command, or the use of the EventLog class, we can feed Windows logs with customized events which, in turn, can be exploited by a solution such as a SIEM. In other words, your PowerShell script can create events containing the information of your choice.
Note : before Write-EventLog was available, this action was possible under Windows using the command-line utility EVENTCREATE.exe.
II. Using the New-EventLog cmdlet
Within the Event Viewer, you can create a custom log, associated with the name of your choice, provided it is not already in use. This step is optional, as we can create records in certain native logs, such as the Windows "Applications" log.
However, by creating a custom log and then recording our own events in it, we can "isolate" our custom events. This may also mean adapting the configuration of your log collection tool to support this new log.
The following command creates a log named "PowerShell-Demo", which accepts two sources: "Script-1" and "Script-2". You can add as many as you like, and you can add additional sources to an existing log. This is essential, as each log event must be associated with a source.
New-EventLog -LogName "PowerShell-Demo" -Source "Script-1","Script-2"
This log will be immediately visible in the Event Viewer under "Application and service logs".

To add an additional source, simply run New-EventLog again, specifying the name of the log and the name of the additional source to be added. Here's an example of how to add the "Script-3" source:
New-EventLog -LogName "PowerShell-Demo" -Source "Script-3"
If you make a mistake, for example, in the name of your log, you can delete it with this command:
Remove-EventLog -LogName "PowerShell-Demo"
To find out more about using this cmdlet, please consult this page:
III. Using the Write-EventLog cmdlet
Now we'll look at how to write a new event to the event log we've just created. We could also add it to another log (beware, some of them are protected), as the "-LogName" parameter of the Write-EventLog command is used to specify the target log.
As with other PowerShell cmdlets, you can specify the name of the cmdlet, followed by each parameter and its value, but in this case, the writing suggested below makes it easier to read.
$Event = @{
LogName = "PowerShell-Demo"
Source = "Script-1"
EntryType = "Error"
EventId = 10000
Message = "This alert was generated from PowerShell"
}
Write-EventLog @Event
This piece of code will create an "Error" event in our log, associated with source "Script-1" and ID "10000". It will contain the message "This alert was generated from PowerShell", as you can see in the image below. Try to use different IDs for your event types, and avoid using IDs already used by Windows.

Instead of the "Error" type, which generates an error, you can use the following values: Warning, Informational, SuccessAudit and FailureAudit. Please note that this command supports the "-ComputerName" parameter, allowing you to create an event in the log of a remote computer.
To view this custom log, or any other log, you can use the "Get-EventLog" PowerShell cmdlet. Although this cmdlet is very handy, it doesn't give you access to all logs, so be aware that there's also a second cmdlet for viewing logs: "Get-WinEvent".
Here is the command to use to retrieve our logs:
Get-EventLog -LogName "PowerShell-Demo"
To find out more about using these cmdlets, take a look at these pages:
IV. Using the EventLog class in PowerShell
To go a step further in writing events to a Windows log, we need to exploit the EventLog class directly from PowerShell. This will enable us to add better-structured data to our event, notably in the "EventData" section visible from the XML view. This is useful for storing multiple pieces of information, while allowing each piece of information to be retrieved independently.
Here's an example:

This complicates the registration of a new event, as we have to create our own objects and dispense with the use of Write-EventLog. A first "System.Diagnostics.EventInstance" object will be used to indicate the ID number and event type, while a second "System.Diagnostics.EventLog" object will be used to specify the event data.
However, to keep things simple, we suggest you use this function:
function Write-EventLogV2 {
<#
.SYNOPSIS
Creates an event in the event viewer
.DESCRIPTION
The function uses CmdLet WriteEvent to create an event from the input parameters.
.PARAMETER dataUser
User name to be entered in the content of the event to be created
.PARAMETER dataDescription
Content of the description to be entered in the content of the event to be created
.PARAMETER ID
Event ID of the event to be created
.PARAMETER evtLog
Event diary to be created
.PARAMETER evtSource
Source of the event to be created
.EXAMPLE
New-EventLog -dataUser "John" -dataDescription "nouvelle description"
.OUTPUTS
None
#>
param(
[Parameter(Mandatory=$true)]$dataUser,
$dataDescription="",
$ID=10000,
$evtLog="PowerShell-Demo",
$evtSource="Script-2"
)
# Loads the event source into the log if it is not already loaded.
# This operation will fail if the event source is already assigned to another log.
if ([System.Diagnostics.EventLog]::SourceExists($evtSource) -eq $false) {
[System.Diagnostics.EventLog]::CreateEventSource($evtSource, $evtLog)
}
# Build and record the event
$evtID = New-Object System.Diagnostics.EventInstance($ID,1)
$evtObject = New-Object System.Diagnostics.EventLog
$evtObject.Log = $evtLog
$evtObject.Source = $evtSource
$evtObject.WriteEvent($evtID, @($dataUser,"Description : $dataDescription"))
}
As input, this function accepts two messages ($dataUser and $dataDescription - you can rename these parameters whose name has been chosen with respect to the original script), an ID number (by default, this will be 10000), the name of an event log (by default, this will be "PowerShell-Demo") and a source (by default, this will be "Script-2").
Furthermore, by default, this function generates "Information" type events. If you wish to change the event type, you must adjust the value on this line:
$evtID = New-Object System.Diagnostics.EventInstance($ID,1)
The first value corresponds to the desired ID, here associated with the variable $ID, while the second value corresponds to the event type. The 1 corresponds to the "Information" type.
This will generate events similar to this one :


If required, you can add other values in the second part of "$evtObject.WriteEvent" to have additional "<Data>" lines.
V. Conclusion
By following this tutorial, you should be able to create your own custom events in Windows logs, either in an existing log or in your own log using PowerShell! Feel free to use these cmdlets or this function in your scripts, and adapt them to your needs! In any case, this opens up some very interesting possibilities!