2

We would like to tail several log files "live" in powershell for particular string. We have tried to use "get-content" command but without luck because everytime as a result we received only results from one file. I assume that it was caused by "-wait" parameter. If there is any other way to tail multiple files ? I heard about runspaces but still I don't know how to implement it.

Our sample script below

dir d:\test\*.txt -include *.txt | `
Get-Content -Wait | `
select-string "windows" | `
ForEach-Object {Write-EventLog -LogName Application -Source "Application error" -EntryType information -EventId 999 -Message $_}

Any help will be appreciated.

2
  • Use get-childitem instead of dir and remove the -wait switch, see if that works Commented Oct 24, 2014 at 9:54
  • Thank for quick response but that is not what I needed. I need to track several txt files in specific directory "live" and that's why i used "-wait" option. Commented Oct 24, 2014 at 9:59

2 Answers 2

2

Might be slightly late to the party...

As per here, we can use the following in a .ps1 file;

$ProgressPreference='SilentlyContinue'
Workflow My-Tail
{
    Param([string[]] $Path)

    foreach -parallel ($file in $path)
    {
        Get-Content -Path $file -Tail 1 -Wait
    }
}

This lets us tail multiple files, invoking in powershell like;

My-Tail (dir C:\Users\User\Documents\*.log)

All that's left then is to filter by the required string;

My-Tail (dir C:\Users\User\Documents\*.log) | Select-String -Pattern ".*ERROR.*"

This will tail all files ending in .log in Documents, outputting lines that contain the text 'ERROR'

Sign up to request clarification or add additional context in comments.

1 Comment

This works perfectly for what I need except I can't tell which file is which when they're all being read at the same time. Is there a way to open each 'get-content' in its own window/instance?
0

The only way I can think to do this is to create a bunch of jobs that run the command on each file. You can then receive the job output in a loop and changes in any of the files will be written to the screen:

gci d:\test\*.txt | % { $sb = [scriptblock]::create("get-content -wait $_") ; start-job -ScriptBlock $sb }
while(1) { 
  $m = $(get-job | receive-job | select-string "searchstring") 
  if($m -ne $null) { 
     Write-EventLog -LogName Application -Source "Application error" -EntryType information -EventId 999 -Message $m
  }
  sleep 1 
}

10 Comments

Ok, but if there is a way to find specific word and generate an event in windows log ? I've asked about it because we wanted to monitor specific application for errors and write an event to logs, then our Nagios system will raise alarm.
Thank you but script returned an error Write-EventLog : Cannot validate argument on parameter 'Message'. The argument is null, empty, or an element of the arg ument collection contains a null value. Supply a collection that does not contain any null values and then try the comm and again. At D:\FIX.ps1:4 char:112 + ... d 999 -Message $m + ~~ + CategoryInfo : InvalidData: (:) [Write-EventLog], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.
Have you run it without the Write-EventLog line to make sure the message is populated properly first?
No I've just run it almost exactly as you provided, I've only changed "searchstring" attribute and saved code as ps1. So what exactly should I do ?
Made another edit, actually need to check $m is not empty before attempting to write the event log. You may want to replace the Write-EventLog ... with Write-Host $m while you're testing. That will write the results to the screen.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.