Tag Archives: Event Log

PowerShell and Security – Presentation at iSense

As mentioned in the previous blog post I was invited to speak at iSense to talk about PowerShell and Security. This event was fully by sponsored by iSense who provided the attendees with a great experience. Before my session I was briefly interviewed and the interview, in Dutch, will be available soon.

Security is a topic that continues to make headlines around the world and as a result, PowerShell is mentioned more often either as an method to exploit or to prevent and secure your system. In this presentation I showed how PowerShell can be configured to provide insights in what scripts and tools are running in your environment and how to secure your PowerShell endpoints using Just Enough Administration, JEA.

The audience after 90 minutes of PowerShell and Security

The audience after 90 minutes of PowerShell and Security

After the presentation I received a lot of questions about PowerShell in general and the Dutch PowerShell User Group, we will soon be holding another PowerShell User Group meeting, for more information visit the following link: 10th DuPSUG Meeting, there are at the time of writing still a few tickets available for this event on the 9th of March.

Furthermore, at the Dutch PowerShell User Group we are working on putting out some events that are a bit more beginner oriented. For anyone who is interested in learning more about PowerShell stay tuned as we have a lot of good interesting stuff in the works.

The presentation deck and the slides are as always available on GitHub:
GitHub – Jaap Brasser – Events – iSense2017

For more information I have provided an overview of all the links in this article:

PowerShell and Security @ iSense
GitHub – Slides and code
Dutch PowerShell User Group
IT Future Lab – PowerShell and Security


Next week: Presenting at iSense on PowerShell and Security

Recently I was invited by iSense to come and speak at one of their technical evenings. On the 16th of February I will be speaking on PowerShell and Security. To quote a short excerpt from the iSense website:

This demo-rich session goes into detail on some best practices on securing PowerShell and highlights and the steps that have been taken in PowerShell 5.0 that allow you to do so. In the first section of this evening we will touch some of the basic concepts of security that we have available to us in PowerShell. Then Jaap will go into detail how you can correctly implement them by demoing the functionality.

For more information on this head over to:
PowerShell and Security – The how, what and why

There are still tickets available, so if you are interested in PowerShell, Security or a combination of both I would be more than happy to meet you there.


Troubleshooting ADFS: Enabling additional logging

I ran into some issues with one of the ADFS setups at one of my clients and I decided to run some troubleshooting. In order to gather more data on what is happening in your ADFS environment additional logging can be configured. My first step in this process was to check the enabled logging on the system:


After confirming that SuccessAudits and FailureAudits were not configured I added those to the logging results for troubleshooting purposes:

Set-AdfsProperties -LogLevel ((Get-AdfsProperties).LogLevel+'SuccessAudits','FailureAudits')


To ensure the audit results are visible in the event logs we need to ensure that ‘Application Generated’ auditing is enabled, to verify and configure this the following commands can be used:

# Verify 
. $env:\systemroot\system32\AUDITPOL.exe /GET /SUBCATEGORY:"Application Generated"  
# Configure
. $env:\systemroot\system32\AUDITPOL.exe /SET /SUBCATEGORY:"Application Generated" /FAILURE:ENABLE /SUCCESS:ENABLE

Now when an ADFS request is processed there will be logging available in the Application Log and it is easier to pinpoint and troubleshoot issues with your ADFS configuration.
For further analysis, I would recommend the ADFS Diagnostics Module created by the ADFS team, it is available here:
ADFS Diagnostics Module
There are a number of useful cmdlets available in this module that can aid in troubleshooting your ADFS configuration. The Test-AdfsServerHealth cmdlet is particularly useful for finding common misconfigurations:



Additionally the Get-AdfsServerTrace cmdlet simplifies tracing a user request for troubleshooting purposes, for example using the following cmdlet:

Get-AdfsServerTrace -ActivityId 00000000-0000-0000-8000-0080000000d4

In order to fully disable logging again the following code can be executed:

. $env:\systemroot\system32\AUDITPOL.exe /SET /SUBCATEGORY:"Application Generated" /FAILURE:DISABLE /SUCCESS:DISABLE
Set-AdfsProperties -LogLevel ((Get-AdfsProperties).LogLevel| Where-Object {$_ -notmatch 'Audits'})

For more information on this subject and to view the links available in this article:

ADFS Logging additional Links
Under the hood tour of Azure AD Connect Health: AD FS Diagnostics Module
ADFS Diagnostics Module


PSBlogweek: PowerShell logging in the Windows Event log

This post is part of the #PSBlogWeek PowerShell blogging series. #PSBlogWeek is a regular event where anyone interested in writing great content about PowerShell is welcome to volunteer for. The purpose is to pool our collective PowerShell knowledge together over a 5-day period and write about a topic that anyone using PowerShell may benefit from. #PSBlogWeek is a Twitter hashtag so feel free to stay up to date on the topic on Twitter at the #PSBlogWeek hashtag. For more information on #PSBlogWeek or if you’d like to volunteer for future sessions, contact Adam Bertram (@adbertram) on Twitter.

Once you’re done getting schooled on everything this post has to offer head on over to the powershell.org announcement for links to the other four past and upcoming #PSBlogWeek articles this week!

An important part of PowerShell scripting is error handling, one of the main differences between a script and a one-liner for me personally is error handling and dealing with exceptions that might occur. For more information on error handling please refer to the previous PSBlogWeek articles where Boe Prox dives into use Try-Catch in order to catch specific errors.

When moving your scripts from into a production environment logging becomes more important, initially using plain text files for logging might be an appropriate solution. Another option however is writing logging information to the Windows Event Log. This has the benefit of being the centralized location where most logging takes place.

Writing to the event log is relatively simple, the Write-EventLog cmdlet can be used for this purpose:


By taking a look at the error message we see that the PowerShell event source is not registered with the application log, in order to resolve this, we can write to the Windows PowerShell event log instead:

Write-EventLog -LogName 'Windows PowerShell' -Source PowerShell -EventId 12345 -EntryType Information -Message 'Script started'


Notice how the command now successfully executes without the error message, this is because it is important for the script

Alternatively, it is also possible to specify a custom event provider, and register this to the correct event log as such:

New-EventLog -Source AwesomeScript -LogName 'Windows PowerShell'
Write-EventLog -LogName 'Windows PowerShell' -Source AwesomeScript -EventId 12345 -EntryType Information -Message 'Script started'


It is also possible to create an entire separate event log for your script logging, also by using the New-EventLog cmdlet:

New-EventLog -LogName 'Scripts' -Source 'Your Script'
Write-EventLog -LogName 'Scripts' -Source 'Your Script' -EventId 12345 -EntryType Information -Message 'Script started'
New-EventLog -LogName 'Scripts' -Source 'Your Script2'
Write-EventLog -LogName 'Scripts' -Source 'Your Script2' -EventId 12345 -EntryType Information -Message 'Script started'


To build upon this, it would be possible to create a script that logs when the script starts, executes an action, when an error occurs and when the script ends.

begin {
    $EventHashInformation = @{
        LogName   = 'Scripts'
        Source    = 'Your Script'
        EventId   = 30000
        EntryType = 'Information'
    $EventHashWarning     = @{
        LogName   = 'Scripts'
        Source    = 'Your Script'
        EventId   = 40000
        EntryType = 'Warning'   
    Write-EventLog @EventHashInformation -Message 'Script started'
process {
    try {
        Get-CimInstance -ClassName Win32_Bios -ErrorAction Stop
        Write-EventLog @EventHashInformation -Message 'Successfully queried Win32_Bios'
    } catch {
        Write-EventLog @EventHashWarning -Message 'Error occurred while  queried Win32_Bios'
end {
    Write-EventLog @EventHashInformation -Message 'Script finished'


Using this method of logging allows for a dynamic form of logging where information such as the timestamp are automatically added to the information. A nice feature of using the event log is that it also allows for exporting the information directory to xml, for example:

Get-WinEvent -FilterHashtable @{
    LogName = 'Scripts'
} | ForEach-Object {$_.ToXml()}


Because this type of logging can quickly fill up the event logs it is important to set the limits and the type of logging the event logs can do. In order to verify the current configuration, we can use the Get-EventLog cmdlet:

Get-EventLog -List | Where-Object {$_.LogDisplayName -eq 'Scripts'} |
Select-Object -Property Log,MaximumKilobytes,MinimumRetentionDays,OverFlowAction


From this we gather that the Minimum retention of this log should be seven days and that only events older than 7 days will be discarded. If the event log is at the maximum size and there are no events older than 7 days to be discarded the latest event will be discarded and will not be written to the script. For more information on this subject please refer to the following MSDN article:

Member name                                                                                                             Description 
DoNotOverwrite Indicates that existing entries are retained when the event log is full and new entries are discarded.
OverwriteAsNeeded Indicates that each new entry overwrites the oldest entry when the event log is full.
OverwriteOlder Indicates that new events overwrite events older than specified by the MinimumRetentionDays property value when the event log is full. New events are discarded if the event log is full and there are no events older than specified by the MinimumRetentionDays property value.

Based on the information in the article, we decide to increase the maximum size of log to 20 MB and to allow overwriting as needed, this is also referred to as circular logging:

Limit-EventLog -Maximumsize 20MB -Logname Scripts -OverflowAction OverwriteAsNeeded
Get-EventLog -List | Where-Object {$_.LogDisplayName -eq 'Scripts'} |
Select-Object -Property Log,MaximumKilobytes,MinimumRetentionDays,OverFlowAction


With the information provided in this article you will be able to:

  • How to write information to the event log
  • How to register an event source to an event log
  • How to create a new event log
  • How to configure an existing event log

I hope this was informative and do not forget to read through the other #PSBlogWeek posts:

Links in this Article
Twitter #PSBlogWeek
#PSBlogWeek Announcement on PowerShell.org
MSDN Article: OverflowAction
Adam Bertram Blog
June Blender Sapien Blog
Jason Wasser Blog
Thom Schumacher Blog
Adam Platt Blog
Matt Johnson Blog