SCCM Log Parser

Anyone who has ever worked with SCCM loves and adores CMTrace.exe for it's ability to parse the System Center logs. Countless headaches have been adverted in it's name.  Still, it leaves quite a bit to be desired.  To address some of the short-comings, Microsoft has released CMLogViewer.exe.  This new tool supports quick filters, merging log files, and advanced filters.  Even with the added features, it still lacks the flexibility that PowerShell can offer.

I started my adventure to do more by searching online for anything that met my needs:
  • Read logs in the SCCM format
  • Parse a single log or multiple logs (must provide filename as a property)
  • Provide either local or UTC timestamps for global troubleshooting
  • Accepts logs directly or via pipeline

After not finding anything suitable, I set about writing my own.  Thankfully the fields in the log file are self-explanatory as key=value pairs and we can use basic regex to capture them.
  • Message
  • Time
  • Date
  • Component
  • Context
  • Type
  • Thread
  • File

To satisfy the local and UTC timestamps requirement, I had to add some additional regex capture groups that were then passed to the [DateTime]::ParseExact .Net method.  I then added the fields into a [PSCustomObject].  The regex and object were then wrapped in a foreach loop that processes log lines read in via Get-Content.  Since I also had a requirement of passing in multiple files and showing which line came from which log, I captured the current file name via Split-Path and also added that as a property to the object.  And to support the ability to specify logs through the pipeline, a Process block was added and then a loop to read in each file.

Meeting these requirements allow us to do fun stuff like the following:

Show me the log entries in SMSTS.log
   Get-CMLog smsts.log

Show me all log entries for CM logs and sort them by date
   Get-ChildItem -Path C:\Windows\CCM\Logs | Get-CMLog | Sort-Object UTCTime
Show me any log entry with "Error" in the message text
   Get-CMLog -Path .\SMSTS.log | ?{$_.Message -match 'Error'}

Show me all log entries for logs that contain an error
   Get-ChildItem -Path C:\Windows\CCM\Logs | Select-String -Pattern 'error' | Select -Unique Path | Get-CMLog

The full code is available below and on Github.