i am completely new to Powershell and I am trying to create a script to extract the timestamp for the string found in a log file. There are log files everyday and it should select the latest file. It then looks for a string in that file. Now, where it finds the string it should also return a timestamp where the string is located. I am only able to complete the first part and struggling with the 2nd bit. My script is in no way optimal but it is a start. Any help is appreciated.
Set-Location -Path "O:\xyz\0502251\logs"
$latest = (Get-ChildItem -Path $dir -Filter 'async_SPARKLE_ONITE_*.log' | Sort-Object CreationDate -Descending | Select-Object -last 1).fullname
$pattern = "Successfulyl finished running psp_dba_maint_4"
$search = (Get-Content $latest | Select-String -Pattern "psp_dba_maint_4" | Select-Object -last 1)
if($search)
{
"The overnight completed at:"
}
else
{
"Do something"
}
This looks for the latest file and extracts the string. Now Just want to know at what time this log was generated.

The log is:
Connection 1
Server message: 2022-10-15 23:56:07:020
Message number: 0, Severity 10, State 1, Line 126
Procedure 'psp_dba_locklogin'
Message String: -----> login SPRK_SVC_IRISS logged in at 23:55:45 running SRI.exe:AWAITING COMMAND on rptSPARKLE from host da-pvrep02 is still active
Connection 1
Server message: 2022-10-15 23:56:07:020
Message number: 0, Severity 10, State 1, Line 126
Procedure 'psp_dba_locklogin'
Message String: -----> login SPRK_SVC_IRISS logged in at 23:55:45 running SRI.exe:AWAITING COMMAND on rptSPARKLE from host da-pvrep05 is still active
Connection 1
Server message: 2022-10-15 23:56:07:020
Message number: 0, Severity 10, State 1, Line 126
Procedure 'psp_dba_locklogin'
Message String: -----> login SPRK_SVC_IRISS logged in at 23:55:39 running SRI.exe:SELECT on rptSPARKLE from host da-pvrep02 is still active
Connection 1
Server message: 2022-10-15 23:56:07:020
Message number: 0, Severity 10, State 1, Line 126
Procedure 'psp_dba_locklogin'
Message String: -----> login SPARKLE_CAI logged in at 23:55:37 running SPARKLE ESB (pooled):AWAITING COMMAND on A_uatSPK from host DA-UVESB01 is still active
Connection 1
Server message: 2022-10-15 23:56:07:020
Message number: 0, Severity 10, State 1, Line 355
Procedure 'psp_dba_dbrefresh'
Message String: Setting PrivShield on SPRKSZCBS OUT OF maintenance mode
Connection 1
Server message: 2022-10-15 23:56:07:022
Message number: 0, Severity 10, State 1, Line 362
Procedure 'psp_dba_dbrefresh'
Message String:
Connection 1
Server message: 2022-10-15 23:56:07:022
Message number: 0, Severity 10, State 1, Line 364
Procedure 'psp_dba_dbrefresh'
Message String: - Refresh 2 complete
Connection 1
Server message: 2022-10-15 23:56:07:028
Message number: 0, Severity 10, State 1, Line 42
Procedure 'psp_dba_maint_4'
Message String: Successfulyl finished running psp_dba_maint_4
This has different values in files generated everyday. So it should look for the latest file and return the result as The overnight completed at: 23:56.
Here is a variant using the switch statement to efficiently process the file line-by-line and test each line to match given RegEx patterns:
$found = switch -File $latest -RegEx {
'\d\d:\d\d' { $timestamp = $matches[0] }
'Successfulyl finished running psp_dba_maint_4' { $true; break }
}
if( $found ) {
"The overnight completed at: $timestamp"
}
else {
"Not found"
}
$found = switch ... assigns the output of the switch statement to the variable. The output will be $true if the pattern has been found.\d\d:\d\d searches for the time (first occurence of a pair of two digits separated by :) within the current line. The automatic variable $matches[0] then gives the matched value, similar to the RegEx -match operator. For a detailed explanation of the RegEx pattern and the ability to experiment with it, see this Regex101.com page.$false output of the switch statement, an empty output evaluates to $false in a boolean context (in this case the if statement), so if the pattern isn't found, the else branch will be entered.Successfulyl which I just copied from your example ;)To complement zett42's helpful switch-based answer:
A Select-String solution, as you attempted, is possible, via the -Context parameter, which allows you to capture the lines surrounding a matching line as well:
$time =
Select-String -LiteralPath $latest -Pattern 'psp_dba_maint_4' -Context 3 |
Select-Object -Last 1 |
ForEach-Object {
# Extract and output the 'HH:mm' part of the timestamp from
# the 3rd line above the match (the first element in the pre-context array)
$_.Context.PreContext[0] -replace '^.+ (..:..).+$', '$1'
}
if ($time) {
"The overnight completed at: $time"
} else {
'Do something'
}
Note:
It is much more efficient to pass the file path of the target file to Select-String, via -LiteralPath, than it is to pass the file's content, line by line, via Get-Content.
System.IO.FileInfo), as emitted by Get-ChildItem, to $latest, you could alternatively have provided it via the pipeline: $latest | Select-String ...The type of the match-information objects that Select-String emits is Microsoft.PowerShell.Commands.MatchInfo.
The regex-based -replace operator is used to extract (part of) the time-of-day string from the context line.
$1 refers to the first and only capture group, (...)), see this regex101.com page.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With