djohnjohn
djohnjohn

Reputation: 65

PowerShell read last two rows of .log file

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)]
    }
}

Upvotes: 1

Views: 1634

Answers (4)

Emanuel V
Emanuel V

Reputation: 153

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.

Upvotes: 1

Theo
Theo

Reputation: 61028

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.

Upvotes: 0

andr3yk
andr3yk

Reputation: 176

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.'

Upvotes: 0

Guenther Schmitz
Guenther Schmitz

Reputation: 1999

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"
    }
}

Upvotes: 2

Related Questions