Read CMLogs with Powershell and Hello World!

Hi everyone!

My name is Matt Benninge (@matbg on Twitter) and I have gotten the great honor to use Deployment Research to write blogs on. Thank you Johan! My day to day work involves design and implementation of Configuration Manager, Windows clients and servers for a Swedish Government (so yes I am a Swede just like Johan). I also do a lot of PowerShell and C# to automate and develop tools that help my organization to be more efficient. Since the ConfigMgr community has always been so great at sharing nice stuff and solutions, I try to give back some whenever it is possible and I have some time to spare.

As a ConfigMgr admin I have used CMTrace for many years but I recently had the need to get some data from the logs with PowerShell, so I developed a function for reading logs in the CMTrace format. While testing my script I found that there are actually two different log formats in the SCCM logs. The first one is the "good" one:

<![LOG[{logmessage}]LOG]!><time="" date="" component="" context="" type="" thread="" file="">

This format is the full format and "type" in the above string tells the severity where 1=Informational, 2=Warning and 3=Error, this format seems to be used on all the log files on the client (ccmlogs).

The other format is simpler and does not contain any type or severity so when reading these kind of logs the parameter "LogLevel" won't work. The server side logs seems to be a mix of full and simple log format. The simpler log format is constructed in the following way:

{logmessage} $$<{component}><{date and time}><thread={thread}>

The function will work when reading simple logs but severity will be set to 0=None by the script.

The script can be used in 3 different ways.

  1. Default:
    .\Read-CMLog.ps1 -path 'C:\Windows\CCM\logs\CcmExec.log'

    This will output a formatted table in the PowerShell Console

  2. Using the switch parameter -Gridview
    .\Read-CMLog.ps1 -path 'C:\Windows\CCM\logs\CcmExec.log' -Gridview

    This will create a GridView from the output. From within the GridView you can do additional filtering or sorting.

  3. Using the switch parameter -passthru
    .\Read-CMLog.ps1 -path 'C:\Windows\CCM\logs\CcmExec.log' -passthru     

    This will output an array without any formatting. Use this if you want to use the output in PowerShell as part of you own function. For example of you want to search for a specific string in the logtext or something similar.

You can also apply the parameter -LogLevel to all three methods, when using the LogLevel parameter it specifies the lowest severity that will be outputted. For example if you specify "-LogLevel Warning" it will output both warnings and errors, specifying "-LogLevel Error" will output only errors.

Example: Read multiple logs, just separate each path with a comma:

.\Read-CMLog.ps1 -path "E:\Program Files\Microsoft Configuration Manager\Logs\ccm.log",'C:\Windows\CCM\logs\CcmExec.log' -Gridview

Example: Find all errors in all logs from the ConfigMgr client:  
.\Read-CMLog.ps1 -path (Get-ChildItem -Path 'C:\Windows\CCM\logs' -Filter "*.log").FullName -Gridview -LogLevel Error

This will take some time since the script will load ALL logs into memory before returning any output. On a virtual lab machine it took approximately 70 seconds for me, but this will vary depending on how big logs you have and how good the computer is.

The script can be found on my GitHub page: Read-CMLog.ps1

Thanks for reading!


About the author

Mattias Benninge

0 0 votes
Article Rating
Notify of
1 Comment
Oldest Most Voted
Inline Feedbacks
View all comments
Francis René
Francis René
3 years ago

Thx very usefull
i will try to find a way to execute it remotely with psexec or something else