Coloring WindowsUpdate.log

The other day I’ve seen the post about WinDump Color Highlighting PowerShell Script from Jason Fossen and thought that it could be very useful if the WindowsUpdate.log could be colored.

On February, there has been a problem with the Silverlight update that seemed to fail with error 80070643 but it was actually correctly installed.
Doug Neal from Microsoft Update explained on the patchmanagement.org distribution list that it was due to a detection logic error.

Here’s an extract how the error about Silverlight (MS12-016) is displayed using the colored extract of the WindowsUpdate.log
WU log extract

Later on, I’ve also found some explanations about How to read the Windowsupdate.log file.

I did not focus too much on performance (I’ve added a progress bar to see what’s going on) and I’ve added the ability to search either by a date or a string. Enjoy 🙂

#Requires -Version 2.0            
            
            
            
param(            
   [Parameter(ParameterSetName='Date', Mandatory=$true, Position=0)]            
    [System.DateTime]${Date},            
            
    [Parameter(ParameterSetName='DateString', Mandatory=$true, Position=0)]            
    [system.string]${DateString},            
            
    [Parameter(ParameterSetName='SearchString', Mandatory=$true, Position=0)]            
    [system.string]${SearchString}            
)            
            
            
if (Test-Path $env:systemroot\WindowsUpdate.log)            
{            
    $allcontent = Get-Content -Path $env:systemroot\WindowsUpdate.log            
} else {            
    Write-Host -ForegroundColor Red -Object ("Cannot find $env:systemroot\WindowsUpdate.log")            
    exit            
}            
            
switch ($PsCmdlet.ParameterSetName)            
{            
    Date {            
        $formatteddate = "{0:yyyy}-{1:MM}-{2:dd}" -f $Date,$Date,$Date            
    }            
    DateString {            
        if (($DateString -match "^\d{4}\-\d{2}\-\d{2}$") -or ($DateString -match "^\d{4}$") -or ($DateString -match "^\d{4}\-\d{2}"))            
        {            
            $formatteddate = $DateString            
        } else {            
            Write-Host -ForegroundColor Red -Object "The expected DateString format is yyyy-MM-dd"            
            exit            
        }            
    }            
}            
            
$parsedcontent = @()            
$count = 0            
foreach ($line in $allcontent)            
{            
    $count++            
    Write-Progress -activity "Parsing WindowsUpdate.log" -status "Percent added: " -PercentComplete (($count/$allcontent.Count)*100)            
            
    if ($formatteddate -ne $null)            
    {            
        if ($line.startswith($formatteddate))            
        {            
            # Add each line to our array            
            $parsedcontent += $line            
        }            
    }            
    if ($SearchString -ne $null)            
    {            
        if ($line -match [regex]::escape($SearchString))            
        {            
            # Add each line to our array            
            $parsedcontent += $line            
        }            
    }            
}            
            
$count = 0            
foreach ($line in $parsedcontent)            
{            
    $count++            
    Write-Progress -activity "Displaying colored WindowsUpdate.log" -status "Percent added: " -PercentComplete (($count/$parsedcontent.Count)*100)            
    # First split the line by Tabs            
    $arString = @($line -split ([char]9))            
    # Date and time            
    Write-Host -ForegroundColor Cyan -NoNewline -Object ($arString[0] + " " + $arString[1] +  " ")            
    # PID and TID            
    Write-Host -ForegroundColor Gray -NoNewline -Object ($arString[2] + " " + $arString[3] +  " ")            
    # Component            
    Write-Host -ForegroundColor Blue -NoNewline -Object ($arString[4] + " ")            
    # Text: get it as a single line            
    $restofline = -join ($arString[5..($arString.Count-1)])            
    switch ($restofline)            
    {            
        # Lines that match only a reptition of ":","*","-","+" or "#" that acts as line separators            
        {$_ -match [regex]'^[\:|\*|\-|\+|\#]+$'}        {Write-Host -ForegroundColor DarkGray -Object $_ -NoNewline}            
        # Only lines that begin by either ":","*","-","+","=" or "#"            
        {$_ -match [regex]'^[\:|\*|\-|\+|\=|\#]+\s{1}'} {Write-Host -ForegroundColor Cyan -Object $_ -NoNewline}            
        # Lines that begin by ">>-- "              
        {$_ -match [regex]'^>>\-\-\s{1}'}               {Write-Host -ForegroundColor Gray -Object $_ -NoNewline}            
        # Lines that begin by "  + "            
        {$_ -match [regex]'^\s{2,3}\+\s{1}.'}           {Write-Host -ForegroundColor DarkGray -Object $_ -NoNewline}            
        # Lines that begin by "  *       {"            
        {$_ -match [regex]'^\s{2,3}\*\s{7}\{.'}         {Write-Host -ForegroundColor DarkGray -Object $_ -NoNewline}            
        # Lines that begin by "  *   Title = "            
        {$_ -match [regex]'^\s{2,3}\*\s{3}Title\s=\s'}  {Write-Host -ForegroundColor White -Object $_ -NoNewline}            
        # Lines that begin by "  * Added update {"            
        {$_ -match [regex]'^\s{2,3}\*\s{1}Added\s{1}update\s{1}\{'} {Write-Host -ForegroundColor DarkGray -Object $_ -NoNewline}            
        default            
        {            
            # Now we split other lines and the remaining text by spaces            
            $arrestofline = @($restofline.split(([char]32)))            
            foreach ($t in $arrestofline)            
            {            
                switch($t)            
                {            
                    # Case sensitive match            
                    {$_ -cmatch "WARNING:"} {Write-Host -ForegroundColor Yellow   -Object $_ -NoNewline}            
                    {$_ -cmatch "FATAL:"}   {Write-Host -ForegroundColor Red      -Object $_ -NoNewline}            
                    # Any hexadecimal notation except 0x00000000 that may be followed by "." or ",".            
                    {$_.StartsWith("0x") -and ($_ -notmatch '^0x00000000([\.|\,]??)')}   {Write-Host -ForegroundColor Red -Object $_ -NoNewline}            
                    { ($_ -match '^0x00000000([\.|\,]??)')} {Write-Host -ForegroundColor Green    -Object $_ -NoNewline}            
                    # Match an hexadecimal number followed by "." or not.            
                    {$_ -match "^([0-9a-f]{8})((\.)??)$"}   {Write-Host -ForegroundColor Red      -Object $_ -NoNewline}            
                    # Match a number but a hexadecimal            
                    {$_ -match "^\d{1,7}(([,|\)])??)$"}     {Write-Host -ForegroundColor Magenta  -Object $_ -NoNewline}            
                    {$_ -match "^\d{9,20}(([,|\)])??)$"}    {Write-Host -ForegroundColor Magenta  -Object $_ -NoNewline}            
                    # Match a Date Time yyyy-MM-dd HH:mm:ss            
                    {$_ -match "^\d{4}\-\d{2}\-\d{2}$"}     {Write-Host -ForegroundColor White -Object $_ -NoNewline}            
                    {$_ -match "^\d{2}\:\d{2}\:\d{2}$"}     {Write-Host -ForegroundColor White -Object $_ -NoNewline}            
                    # Exact matches            
                    {$_ -eq 'state:0'} {Write-Host -ForegroundColor Green    -Object $_ -NoNewline}            
                    {$_ -eq 'hr=0x0'}  {Write-Host -ForegroundColor Green    -Object $_ -NoNewline}            
                    {$_ -eq 'True'}    {Write-Host -ForegroundColor Magenta  -Object $_ -NoNewline}            
                    {$_ -eq 'False'}   {Write-Host -ForegroundColor Magenta  -Object $_ -NoNewline}            
                    # Begins by 'Yes and might be followd by ",",";" or nothing            
                    {$_ -match '^Yes(([,|;])??)$'} {Write-Host -ForegroundColor Magenta -Object $_ -NoNewline}            
                    {$_ -match '^No(([,|;])??)$'}  {Write-Host -ForegroundColor Magenta -Object $_ -NoNewline}            
                    # Anything that matches a URL            
                    {$_.StartsWith("http://")}     {Write-Host -ForegroundColor Green   -Object $_ -NoNewline}            
                    {$_.StartsWith("https://")}    {Write-Host -ForegroundColor Green   -Object $_ -NoNewline}            
                    {$_ -eq '(00000000)'}          {Write-Host -ForegroundColor Green   -Object $_ -NoNewline}            
                    {$_ -match 'successfully'}     {Write-Host -ForegroundColor Green   -Object $_ -NoNewline}            
                    # Anything that matches the 'Succeeded' word followed by ",","]","." or nothing            
                    {$_ -match 'Succeeded(([,|\]\.])??)$'} {Write-Host -ForegroundColor Green -Object $_ -NoNewline}            
                    {$_ -match '^Failed(([,|\]\.])??)$'}   {Write-Host -ForegroundColor Red   -Object $_ -NoNewline}            
                    # A keyword that may begin by "(" or not and followed by 'hr=' and a repetition of numbers            
                    {$_ -match "^((\()??)hr=[0-9][0-9]+"}  {Write-Host -ForegroundColor Red   -Object $_ -NoNewline}            
                    # A path that contains the '\SoftwareDistribution\' keyword            
                    {$_ -match [regex]'\\SoftwareDistribution\\'} {Write-Host -ForegroundColor White -Object $_ -NoNewline}            
                    default {Write-Host -ForegroundColor DarkGray -Object $_ -NoNewline}            
                } # end if switch            
                Write-Host -ForegroundColor Yellow -Object " " -NoNewline            
            } # end of foreach            
        } # end of default            
    } # end of switch            
    # Now insert a 'new line'            
    Write-Host -Object ([char]10)            
}            
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s