0

How can I read only the last two rows of a .log file? The following script reads the full .log file which returns an incorrect status. For my particular case the string returning the correct status per .log file is written in the last two rows.

function Get-Status($file) {
    if (Select-String -Quiet 'Finished with errors' $_.FullName) {
        return "ERROR"
    } elseif (Select-String -Quiet 'Finished with warnings' $_.FullName) {
        return "WARNING"
    } elseif (Select-String -Quiet 'Finished.' $_.FullName) {
        return "SUCCESS"
    } else {
       return "FAILED"
    }
}

Get-ChildItem C:\logfolder\*.log | % {
    [PSCustomObject] @{
        Name = $_.Name;
        Date = $_.LastWriteTime;
        Status = Get-Status($_.FullName)]
    }
}
dmartins
  • 45
  • 8

4 Answers4

2

you can read the files content using Get-Content and the select only the last two lines like:

$fileContent = Get-Content -Path $file -Tail 2

so adding this to your Get-Status function should return the correct state:

function Get-Status($file) {
    $fileContent = Get-Content -Path $file -Tail 2
    if (Select-String -Quiet -Pattern 'Finished with errors' -InputObject $fileContent) {
        return "ERROR"
    } elseif (Select-String -Quiet -Pattern 'Finished with warnings' -InputObject $fileContent) {
        return "WARNING"
    } elseif (Select-String -Quiet -Pattern 'Finished.' -InputObject $fileContent) {
        return "SUCCESS"
    } else {
       return "FAILED"
    }
}
Guenther Schmitz
  • 1,955
  • 1
  • 9
  • 23
0

In recent versions of PowerShell Get-Content supports -Tail parameter, so you can pipe Get-Content into select string, e.g. for first if statement:

Get-Content -Tail 2  $_.FullName | Select-String -Quiet 'Finished.'
andr3yk
  • 176
  • 6
0

Another variation is to use a switch in the Get-Status function:

function Get-Status([string]$file) {
    # get the last two lines of the log and recombine them with a newline
    switch -Regex ((Get-Content -Path $file -Tail 2) -join "`r`n") {
        '(?m)^Finished with error'   { 'ERROR'   ; break}
        '(?m)^Finished with warning' { 'WARNING' ; break}
        '(?m)^Finished'              { 'SUCCESS' ; break}
        default                      { 'FAILED'}
    }
}

Get-ChildItem -Path 'C:\logfolder' -Filter '*.log' -File | ForEach-Object {
    [PSCustomObject] @{
        Name = $_.Name
        Date = $_.LastWriteTime
        Status = Get-Status $_.FullName
    }
}

Please notice that with PowerShell you should use a space character betweet the function name and the parameter, not put this parameter inside brackets.

Theo
  • 57,719
  • 8
  • 24
  • 41
0

Unix tail equivalent command in Windows Powershell

At the stop of your Get-Status() function, include this:

$lines = Get-Content $file | Select-Object -Last 2

The do your search against $lines instead.

Emanuel V
  • 143
  • 8