I am trying to use PowerShell's type -wait
command to monitor a log file in real time on Windows in the same way that I would use tail -f
on Linux, and I want to pipe the file to another command - select-string
, like grep
- that will trigger an action based on a condition. On Linux, I would use watch
to accomplish what I'm trying to do.
In the following example, I am trying to print the phrase "You caught a critter!"
whenever a new line, which contains the string "status=Caught"
, is written to the log file.
while (1) {if (type -wait "$env:USERPROFILE\AppData\Roaming\CritterCatcherApp\Logs\CritterBag-170118.log" | select-string -quiet "state=Caught") {write-host "You caught a critter!"} else {continue}}
Please note that the -quiet
argument for the select-string
command returns True
. Actually, in this example, it only returns True
one time, when I first run the command, as the log file has existing lines that contain the string "status=Caught"
.
I do need to somehow overlook the existing strings (or, e.g., rotate the log files), but right now, the issue is that I need the PowerShell script to not only continue to tail the file, but I also need it to continue to evaluate whether each new line that is written to the file contains the given string. Then, if the string is present, I need to execute an arbitrary action, like print a line; else, continue listening for the string.
The following post indicates that the -wait
argument is an option for the Get-Content
cmdlet: How to monitor a windows log file in real time? . I am not sure if I should expect -wait
to work with a foreach
loop, as described in this post: In Powershell can i use the select-string -quiet switch within a foreach statement .
How can I modify the above PowerShell script to tail a log file and execute an action for each new line with a given string, and continue to tail the file and evaluate new lines as they are written?
You can do it on the pipeline with Where-Object (?)
and ForEach-Object (%)
:
Get-Content file -wait | ? { $_ -match "status=Caught" } | % { Write-Host "You caught a critter!" }
Each time status=Caught
is detected in the file, the Write-Host
in the ForEach-Object
will execute