Sorry about the lapse in blogging. My workmates attended a 3-day conference and left me, like the step-daughter in fairy tales, hard at work. Then the weekend came along and spring finally arrived in Wisconsin (I have three city lots of yard work). My final excuse is spending the first two days of this week at the CCCP Expo in Green Bay. A big thank you to them for putting on such a great event and even providing suites for us at the wonderful Hyatt.
Now on to business. If you look back in this blog log, you will see an earlier posting about error handling. https://poshlessons.wordpress.com/2017/05/09/erroraction-in-action/. This post is a follow up to that (or maybe the conclusion it should have had). It is a discussion on what to do once you have captured errors in your scripts.
I am not going to talk about formatting data for readability and then writing them to some log file. Just use OUT-FILE for that. But frankly, the last thing we need is more folders to search when troubleshooting issues. Instead of that, we are going to use big boy reporting – sticking the information into the Event Log. It makes sense when you think about it. We go to the event logs all the time to look for messages that may help us understand what is going on with O/S issues. It is the logical place then to put our performance output as well and keep troubleshooting focused in one area.
The basic command to do this is Write-EventLog –Logname –Source –EventId –Message. These parameters are mandatory and if you don’t supply them, the program will ask. -EntryType and possibly -Category are other parameters you may want to include.
There are some quirks in a few of these parameters; –Source has to be a specific term. You cannot specify some random name you just made up for your entries (or can you?). Sources are registered with the operating system. If you are going to use one of them, you will need to find which ones are available.
Just kidding. The command New-EventLog will not only create a new event log but it can also register sources of your own creation. Since we are going to be introducing something new that was unplanned by the original programmers, we will be creating custom sources for Powershell scripts in this blog.
The other non-intuitive parameter is Category. You’d think it would be of type string but it is actually of type [INT16] (a number). What is supposed to happen behind the scenes is that a category dictionary is created that will translate the numbers into string equivalent messages. For instance, the number 100 will mean Routine, etc. If you want to do this, remember that the path to this file will need to be set in the New-EventLog command (use –CategoryResourceFile parameter). However, I am good with just using a number with no translation needed.
Enough background, let’s get started. Since we are capturing Powershell data, it seems logical to store our output in the existing log ‘Windows Powershell’. You can find it in the Event Viewer (eventvwr.exe) under Applications and Service Logs > Windows Powershell however because it is a foundational log, we can just use its name (Windows Powershell) for addressing [To address other logs, you’ll have to provide their path]. To see all the directly accessible logs, use Get-EventLog –List.
While we are using an existing log, we are planning on using a couple of new sources. One will be for script errors and the other for routine messages. (Routine messages can be important so that you are able to document the value of the product and can provide tracking data on when and how much it is being used).
Note that creating new sources is a one-time function so you’ll need to plan where and when to run the command and how to silently continue if the sources already exist. If I haven’t mentioned it before, unless you are using a single server to capture all events in your domain(s), you will need to create these custom sources on each (and every) machine. These are the commands:
New-EventLog -LogName ‘Windows Powershell’ -Source ‘ScriptErrors’
New-EventLog -LogName ‘Windows Powershell’ -Source ‘Scripts’
You can now use ScriptErrors or Scripts as sources.
The other parameters: Unlike sources, you can use any number you want between 0 and 65535 for an EventId (because EventIds are application specific). I know of some programmers that generate random numbers for each entry but the primary use of EventIds is for aggregating/searching so the recommendation is to pick specific numbers to represent specific classes of information. For instance, all informational messages about a script starting/stopping normally get ID 1. Warning messages often use id 999 generically (that’s an old programmer’s trick) or have a list of numbers based on specific exception messages. Use whatever you want, just be consistent.
You should also provide the Entry Type. There are five of them; Information, Warning, Error, Success Audit, and Failure Audit. Warning is a good label for non-terminating errors, saving Error for those scripts that completely bomb-out. Event type Information should be used for messages pertaining to normal script operations. This is where you will capture and save all that ‘justification’ data we talked about earlier.
With all the pieces gathered we can now run our commands ($Lm is the variable I use to hold routine log messages. $e is for errors.):
Write-EventLog -Logname ‘Windows Powershell’ -Source Scripts -EntryType Information -EventId 0 -Message $Lm
Write-EventLog –Logname ‘Windows Powershell’ -Source ScriptErrors –EntryType Warning –EventId 999 –Message $e
Populate your message variables and run the command. Refresh the Event Viewer interface if you have it open and you will now see a new entry in the Windows Powershell event log. Pretty cool, right?!
To finish this up, there will have to be a blog about retrieving information from EventLogs (Get-EventLog maybe?)
#tags: Powershell, Event log, Event Logs, Write-EventLog, Error handling, Errors, New-EventLog