Ad Space here

Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Share
Options
Go to last post Go to first unread
Dustin Higgins  
#1 Posted : Monday, December 02, 2019 9:31:01 PM(UTC)
Dustin Higgins

Rank: Advanced Member

Groups: Registered
Joined: 7/1/2018(UTC)
Posts: 64
_United States

Thanks: 1 times
Was thanked: 6 time(s) in 6 post(s)

PowerShell, Windows Patches, and the ReportingEvents.log

With respect to Windows Updates (workstation and server), if you search up the C:\Windows\SoftwareDistribution\ReportingEvents.Log you typically won’t find a lot.  The general theme is to use the WindowsUpdate.log, since there is a lot more information in that file.

I’ve been using the ReportingEvents.Log for a long time to complement reporting from WSUS and SCCM.  I will also admit, if you just view the ReportingEvents.log in a text editor such as Notepad, you can’t make too much sense out of it.  The point of this post is to demonstrate how to build a PowerShell Custom object out of the ReportingEvents.Log that will provide useful information. More specifically, this will provide a summary of what exactly is going on for each endpoint.

The log file is tab delimited, and easy to parse.  There is one regular expression to extract the date and time from the second field.  If you don’t understand the regular expression, I encourage you to figure it out (I’m definitely not a regular expression expert).  I recently started dabbling with regular expressions and $matches mainly because I stumbled across a post that used regular expressions heavily.   It honestly looked like a foreign language to me.   Once I understood $matches, string parsing, and labeling, it was $money!

​​​​​​​

The key to the summary object is tagging key events.  In the code below, I only focused on UpdateOrchestrator.  Feel free to add other components such as patching from the SCCM client.  Once the summary object is built and you start looking across multiple workstations, patterns start to appear.  You can identify machines not syncing with the WSUS server.  Working on patching issues directly from the endpoints does complement enterprise patching solutions and tends to raise compliance percentages.

Code:

# Create the Object $Obj = [PSCustomObject]@{         UpdateOrchestrator_LastSync = $null     UpdateOrchestrator_LastSyncText = $null     UpdateOrchestrator_LastInstall = $null     UpdateOrchestrator_LastInstallText = $null     UpdateOrchestrator_LastFailure = $null     UpdateOrchestrator_LastFailureText = $null     LogEntry = New-Object "System.Collections.Generic.List[psobject]"     ObjTimeStamp = (get-date) } ## Set the Log File $LogFile = "C:\Windows\SoftwareDistribution\ReportingEvents.Log" ## Read the log and process it $LogFileContents = Get-Content $LogFile # Loop through each line in the file foreach ($i in $LogFileContents) {     # Process the each log line     if ($i.StartsWith("{")) {         $LogEntryObj = [PSCustomObject]@{         Field1 = $i.Split("`t")[0]         Field2 = $i.Split("`t")[1]         Field3 = $i.Split("`t")[2]         Field4 = $i.Split("`t")[3]         Field5 = $i.Split("`t")[4]         Field6 = $i.Split("`t")[5]         Field7 = $i.Split("`t")[6]         ErrorCode = $i.Split("`t")[7]         Component = $i.Split("`t")[8] #  UpdateOrchestrator, Windows Defender Antivirus, etc.         ActionResult = $i.Split("`t")[9] # Success, Failure         Action = $i.Split("`t")[10] # Content Download, Content Install, Software Synchronization, etc.         ActionResultText = $i.Split("`t")[11]         Field13 = $i.Split("`t")[12]         Date = $null         }         # Parse out the date with a regex         if ($LogEntryObj.Field2 -match "(?<DateTime>\d\d\d\d-\d\d-\d\d\s\d\d:\d\d:\d\d:\d\d\d).*") {             $LogEntryObj.Date = [datetime]::ParseExact($Matches.DateTime,"yyyy-MM-dd HH:mm:ss:fff",$null)         }         # Get the last UpdateOrchestrator Sync         if ($LogEntryObj.Component -eq "UpdateOrchestrator" -and $LogEntryObj.Action -eq "Software Synchronization" -and $LogEntryObj.ActionResult -eq "Success") {             $Obj.UpdateOrchestrator_LastSync = $LogEntryObj.Date             $Obj.UpdateOrchestrator_LastSyncText = $LogEntryObj.ActionResultText         }         # Get the last UpdateOrchestrator Last Install         if ($LogEntryObj.Component -eq "UpdateOrchestrator" -and $LogEntryObj.Action -eq "Content Install" -and $LogEntryObj.ActionResult -eq "Success") {             $Obj.UpdateOrchestrator_LastInstall = $LogEntryObj.Date             $Obj.UpdateOrchestrator_LastInstallText = $LogEntryObj.ActionResultText         }         # Get the last UpdateOrchestrator Last Failure         if ($LogEntryObj.Component -eq "UpdateOrchestrator" -and $LogEntryObj.Action -eq "Content Install" -and $LogEntryObj.ActionResult -eq "Failure") {             $Obj.UpdateOrchestrator_LastFailure = $LogEntryObj.Date             $Obj.UpdateOrchestrator_LastFailureText = $LogEntryObj.ActionResultText         }         # Add the Log Entry Object to the list         $Obj.LogEntry.Add($LogEntryObj)     } } # Return the Object $Obj

​​​​​​​

Here is an example of what the object looks like:

Code:

UpdateOrchestrator_LastSync        : 12/2/2019 11:28:05 AM UpdateOrchestrator_LastSyncText    : Windows Update Client successfully detected 1 updates. UpdateOrchestrator_LastInstall     : 12/2/2019 11:28:18 AM UpdateOrchestrator_LastInstallText : Installation Successful: Windows successfully installed the following update: Security Intelligence Update for Windows Defender Antivirus - KB2267602 (Version 1.305.3192.0)

Feedback is welcomed and follow Dustin Higgins on Twitter

DHB

Edited by user Tuesday, December 03, 2019 3:33:02 AM(UTC)  | Reason: Not specified

Sponsor
Ad Space here
Rss Feed  Atom Feed
Users browsing this topic
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.