0

I am 100% new at Powershell, I have looked around a bit and not really found a whole lot on this topic, but I apologize if this has been answered elsewhere.

There is a Service that stops functioning every now and then, generally every day around 7am, to 8am, and the only way that I can restore its functionality is to restart the services. Associated with the software.

I am parsing through the event log to find the particular error every 15 minutes.

$lookForError = get-eventlog -before $currentDate -after $pastDate -logname application -source "Windows Backup"


$itCrashed = $FALSE

$lookForError
<#
while($itCrashed = false)
{
    if ($lookForError -eq )

}#>

The general idea here, is to check if the event has occurred, if it has, changed itCrashed to true, exit the loop and initiate the service restart command.

I am not too sure on how I detect the existence of said error using powershell.

Pensai
  • 9
  • 7
  • 1
    Does the service itself stop when this happens? – alroc Jun 09 '14 at 16:56
  • No the service just hangs unfortunately, but it does produce an error in the log, it will produce a "faulting application" error with an access violation error. – Pensai Jun 09 '14 at 16:59
  • What is the error that appears in the event log? Do you have to search the text, or does it throw a specific error#? – TheMadTechnician Jun 09 '14 at 17:03
  • There is some vague data that the error produces such has the EventID(1000), application error being the provider. I had planned to detect the even using the "application error" provider coupled with the event ID. Not sure if this answers your question. – Pensai Jun 09 '14 at 17:06
  • Is there any way I can extract those two things (event id and provider) from the results of the get-eventlog, and use their values in an if statement to see if the error returned is the error I am looking for? – Pensai Jun 09 '14 at 17:08
  • It would probably be easier to just filter the result and then count the number of records returned. Is the Event ID the actual Event ID field or is it inside the event message? Is the provider you mentioned in the message? – Tim Ferrill Jun 09 '14 at 18:25
  • I'm reading this from the raw xml, the eventID is 1000, and the eventRecordID is 174474. The provider is NOT in the message. The way I am constructing this, there will most likely only be 1 returned record. Once the service hangs, it does NOT produce any more records. Furthermore, This ONLY occurs between 7-8:30am. "Faulting application w3wp.exe, version 7.0.6002.18005, time stamp 0x49e03238, faulting module onetutil.dll, version 12.0.6421.1000, time stamp 0x499414d5, exception code 0xc0000005, fault offset 0x00000000000abd8b, process id 0x1c4, application start time 0x01cf764759678ab8." – Pensai Jun 09 '14 at 18:46

2 Answers2

0

Something like this should get you on the right track...

$lookForError = get-eventlog -before $currentDate -after $pastDate -logname application -source "Windows Backup" | Where-Object {$_.EventID -eq 1000}

That will limit the results by the event ID. From there you should be able to assume that a length greater than zero means you should restart the service...

if($lookForError.Length -gt 0) {
    # Restart service
    }

For better performance with large event logs, use this. Thanks @mjolinor!

# First we configure a file to store the last recorded index
$IndexFile = "C:\Users\Public\serviceindex.txt"
if (Test-Path $IndexFile) {
    [Int32]$lastIndex = Get-Content $IndexFile
    } else {
    $lastIndex =0
    }
$eventPadding = 100

# Next we get the newest index and calculate the difference, using this to limit the results
$newest = Get-EventLog -LogName Application -Newest 1
$records = $newest.Index-$lastIndex+$eventPadding
$lookForError = Get-EventLog -LogName Application -source "Windows Backup" -Newest $records | Where-Object {$_.EventID -eq 1000}

# Finally we restart the service if there was an error and update the index file
if($lookForError.Length -gt 0) {
    # Restart service
    $lookForError.Index | Out-File $IndexFile
    }
Tim Ferrill
  • 1,648
  • 1
  • 12
  • 15
  • 1
    Very similar to what I was writing up, but I would do `-after (get-date).addminutes(-15)` and skip the -before, and then I'd call that script every 15 minutes from the task scheduler. Shoot, you could just do (**pseudocode**) `if(get-eventlog -source app -after (get-date)-15 -source "winbackup" | where{$_.eventid -eq 1000}){Restart-Service "WinBackup"}` and make it all one line if you wanted to, and call that line directly from the task scheduler (_powershell -noprofile & {code goes here}_) and skip saving it as a script. – TheMadTechnician Jun 09 '14 at 19:32
  • Get-EventLog -After is horribly slow on large event logs (it starts reading from the beginning of the log). You can speed that up a lot if you get and save the index number from the newest event, and use that as your starting point for the next search. – mjolinor Jun 09 '14 at 19:37
  • @mjolinor -Index takes an Int32. How would you use that as a starting point without having to pipe out the whole result set? – Tim Ferrill Jun 09 '14 at 20:00
  • 1
    The index numbers are sequential. On the next pass, re-read the newest log entry and get the index from that. Subtract the last index number from the newest index, and Get-EventLog -Newest for that many log entries. If you think you might miss entries in the time it takes to do the calculation, you can pad it by a few tens of entries, and then do late filtering on the results by timestamp. – mjolinor Jun 09 '14 at 20:10
  • Nice! I'll see about updating the answer. – Tim Ferrill Jun 09 '14 at 20:12
0
while ( ((Get-Date).Hour -gt 6) -and ((Get-Date).hour -lt 9) ) {

        $lastTested = (get-date).AddMinutes(-15)

        $potentialLogs = Get-EventLog -LogName Application -After $lastTested | where { ( $_.instanceid -eq 1000 ) -and  ($_.source -eq "Application Error")  }

        $potentialLogs | foreach { 

            if( ($_.ReplacementStrings -split '\n') -match 'w3wp.exe' ) {

                restart-service -name ## [insertServiceNameHere]

            }
        }
        Start-Sleep -Seconds 900  ## 15mins
}

According to this answer

An Internet Information Services (IIS) worker process is a windows process (w3wp.exe) which runs Web applications, and is responsible for handling requests sent to a Web Server for a specific application pool.

Also

They only spin up when a request is made. If there are no requests for a long period of time, they will shut down.

I'm going to go out on a limb and guess that your web app doesn't get any requests overnight, shuts down worker processes and when your staff arrive for work in the morning the first person trips of the error you see in the event log?

Maybe would be worth looking at the configuration of the specific app, or running a scheduled task at 5am everyday to restart the service?

Community
  • 1
  • 1
bob
  • 983
  • 11
  • 21