Using a customer application event log to debug a Powershell Script

Often, when I am debugging a developer’s PowerShell script, the only symptom I get is that the script is not working. In general, it is fairly easy to debug a small script even when you have little information but when given complex script, it can be difficult to navigate your way around especially when you are not familiar with its design.

As part of troubleshooting, I would ask for the last successful call or command that was executed, however, in most cases, this information is unavailable as they are executed from a task scheduler where there aren't any user interaction. What would help is if you have a trail that you can follow to identify the first point of failure. This is where I would recommend the developer to add a form of instrumentation to document the status of the code at different points during the script's execution. One of such method is to write information to the Application Event log.

In order to write to the event log, one can use the Write-EventLog cmdlet but there are mandatory parameters needed to write the event log information. These are:

  • LogName
  • Source
  • EventID
  • Message

If you want to create an entry log message “Format was called” into the Application Log and store this into your custom source “MyScript” with a custom event ID like “3001”, you will need to type it as:

   1: Write-EventLog -LogName Application -Source MyScript -EventId 3001 -Message "Format was called"
   2: 

If you have not registered your custom event source, you will encounter an error like below:

 PS C:\windows\system32> Write-EventLog -LogName Application -Source MyScript -EventId 3001 -Message "Format was called"
 Write-EventLog : The source name "MyScript" does not exist on computer "localhost".
 At line:1 char:15
 + Write-EventLog <;<<<  -LogName Application -Source MyScript -EventId 3001 -Message "Format was called"
     + CategoryInfo          : InvalidOperation: (:) [Write-EventLog], InvalidOperationException
     + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteEventLogCommand

In order to register a custom event source, you will need to call the New-EventLog cmdlet like the example below:

   1: New-EventLog -LogName Application -Source MyScript
   2: 

It is only necessary to call New-EventLog once to register the new event source for the target machine where the event logs will be written. Once the event source is registered, you do not have to call this cmdlet again.

You can then sprinkle the Write-EventLog cmdlets throughout your script like so:

   1: .\Format.ps1
   2: Write-EventLog -LogName Application -Source MyScript -EventId 3001 -Message "Format was called"
   3: .\Register.ps1
   4: Write-EventLog -LogName Application -Source MyScript -EventId 3001 -Message "Register was called"
   5: 

Now, when you review your custom event logs, you can easily check and compare them against your script to determine the last successful command that executed. It will help you narrow down where to focus your efforts and hopefully get you closer to solving the problem.

Comments

  • Anonymous
    April 24, 2012
    The comment has been removed

  • Anonymous
    August 25, 2013
    Many thanks for this!

  • Anonymous
    March 25, 2014
    And what if it doesn't work? What if Write-EventLog returns nothing and creates nothing? Any ideas?

  • Anonymous
    August 11, 2014
    James, check to see if your dashes - if they were copied from a web page - haven't been converted into "endashes" (long dashes that Word will autocorrect for you between words, and some web rendering engines). I had a problem where my custom event was silently failing to be written, even after creating the event type per @pamarths link. It was the fact I'd copied my code from our wiki that was the problem. For me, it was the difference between this dash (minus symbol) '-' and this dash (endash) '–'. Effectively, I wasn't passing Write-eventlog any parameters.