locked
How do you PowerShell to automate Event-Log delivery by email? RRS feed

  • Question

  • I want to automate my daily server checks. Rather than having to manually check event logs I would like instead for the event log information to be emailed to me daily.

    My goal is as follows:

    For each server (we have two), generate a daily report of any Errors, Warnings or Crucial messages in the Application of System logs that have occurred in the last 24 hours. I'm also planning to develop it further for AD logs, DNS logs etc.

    Is this possible with PowerShell? 

    A nicely formatted email attachment would be preferred - perhaps in HTML format but ok in text/xls as long as columns are properly formatted etc and easy to view.  The idea being all I have to do is check my emails first thing and view the logs.

    I'm about to research ways of doing this but if anyone can offer any examples this would be much appreciated.

     

    Monday, July 25, 2011 2:42 PM

Answers

  • I am already doing this.  Here is my script for the System log of Server2 for the last 24 hours (errors and warnings):

     

    Get-Eventlog -log system -after ((get-date).addDays(-1)) -EntryType Error, Warning | export-csv "C:\scripts\sysevents.csv"
    Send-MailMessage -To admin@somedomain.com -From "SysEvents@server2.local" -Subject "System Events" -Attachments "c:\scripts\sysevents.csv" -SmtpServer server1
    

     I have included this in a batch file, which I run as a Scheduled Task every 24 hours.  It sends me a csv file, which I can open in Excel.


    If you found this post helpful, please give it a "Helpful" vote. If it answered your question, remember to mark it as an "Answer".

    Monday, July 25, 2011 3:21 PM
  • I've done this. Not too hard to get something basic working. Three things I learnt:

    1. Get-WinEvent is much more efficient at reading event log content.

    2. I needed filtering. There are lots of benign errors and warnings, without filtering the counts of warnings and errors would so high that I would never really be able to see things that need action.

    The filters are an array of hashes which contain a name, a filter function (which takes the event log entry object)... if any of the filters match the log entry is not put in the email (but a count of how many times that filter matched is).

    3. Out-String is very helpful: feed Format-* cmdlets into Out-String with its width parameter to better control the formatting and allow the email body to be built up.

     


    Richard J Cox
    Tuesday, July 26, 2011 9:19 AM

All replies

  • I won't provide you full working example but simple building blocks, example sending emails with errors in global array

    Function Send-Report
    {
      if ($global:MyErrors.Length -gt 0)
      {
        $subject = "Server Problem on " + $env:ComputerName
        $smtpServer = "myemailserver";
        
        $to = "youremail";
        $from = "donotreply@domain.com";
        
        $message = ''
        foreach ($line in $global:MyErrors)
        {
          $message += $line + '<br />'
        }
        
        $msg = new-object System.Net.Mail.MailMessage $from, $to, $subject, $message
        $msg.IsBodyHtml = $true
        $client = new-object System.Net.Mail.SmtpClient $smtpServer
        $client.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
        $client.Send($msg)
        
      }
    }#end Send-Report
    

    Getting EventLogs entries from Last 24 hours with defined type (Infromation, Critical etc.). Just change EntryType and LogName

    Get-EventLog -LogName System -After (Get-Date).AddHours(-24) -EntryType Error
    


    With kind regards
    Krystian Zieja
    http://www.projectenvision.com
    Follow me on twitter
    My Blog
    Need help with your systems?
    Monday, July 25, 2011 2:54 PM
  • So this will obtain the event log information and attach it to an email completely automatically?

    Monday, July 25, 2011 3:00 PM
  • No I just gave you the examples, that will help you develop your own script, at least I hope that they will help you, using above code and a little bit of work you should be able to create your own powershell script that will do what your want. Than you have to save your script and schedule it to run once per day. If you will have problems with your own script just post questions on the forum and someone will help you
    With kind regards
    Krystian Zieja
    http://www.projectenvision.com
    Follow me on twitter
    My Blog
    Need help with your systems?
    Monday, July 25, 2011 3:07 PM
  • I am already doing this.  Here is my script for the System log of Server2 for the last 24 hours (errors and warnings):

     

    Get-Eventlog -log system -after ((get-date).addDays(-1)) -EntryType Error, Warning | export-csv "C:\scripts\sysevents.csv"
    Send-MailMessage -To admin@somedomain.com -From "SysEvents@server2.local" -Subject "System Events" -Attachments "c:\scripts\sysevents.csv" -SmtpServer server1
    

     I have included this in a batch file, which I run as a Scheduled Task every 24 hours.  It sends me a csv file, which I can open in Excel.


    If you found this post helpful, please give it a "Helpful" vote. If it answered your question, remember to mark it as an "Answer".

    Monday, July 25, 2011 3:21 PM
  • Cheers.

    Any way to make the column widths auto fit?

    Monday, July 25, 2011 3:22 PM
  • The following macro takes that dirty csv file, and deletes unwanted columns, and autosizes the remaining columns:

     

    Sub CleanUp()
    
    Rows("1:1").Select
     Selection.Delete Shift:=xlUp
     Columns("C:C").Select
     Selection.Delete Shift:=xlToLeft
     Selection.Delete Shift:=xlToLeft
     Selection.Delete Shift:=xlToLeft
     Selection.Delete Shift:=xlToLeft
     Columns("F:F").Select
     Selection.Delete Shift:=xlToLeft
     Selection.Delete Shift:=xlToLeft
     Columns("G:G").Select
     Selection.Delete Shift:=xlToLeft
     Selection.Delete Shift:=xlToLeft
     Selection.Delete Shift:=xlToLeft
     Selection.Delete Shift:=xlToLeft
     Columns("A:F").Select
     Columns("A:F").EntireColumn.AutoFit
     
    End Sub
    
    

    In fact, I also wrote a really cool Excel macro to colourize the rows according to the event source. This makes it easy to read and analyse.  Let me know if your've interested, and I'll post it.

     

    • Proposed as answer by Bigteddy Monday, July 25, 2011 7:25 PM
    • Unproposed as answer by Bigteddy Tuesday, July 26, 2011 9:28 AM
    Monday, July 25, 2011 3:39 PM
  • deffinitely interested in the Excel macro
    Tuesday, July 26, 2011 7:26 AM
  • I've done this. Not too hard to get something basic working. Three things I learnt:

    1. Get-WinEvent is much more efficient at reading event log content.

    2. I needed filtering. There are lots of benign errors and warnings, without filtering the counts of warnings and errors would so high that I would never really be able to see things that need action.

    The filters are an array of hashes which contain a name, a filter function (which takes the event log entry object)... if any of the filters match the log entry is not put in the email (but a count of how many times that filter matched is).

    3. Out-String is very helpful: feed Format-* cmdlets into Out-String with its width parameter to better control the formatting and allow the email body to be built up.

     


    Richard J Cox
    Tuesday, July 26, 2011 9:19 AM
  • 'This macro, "Colourize", will colour your spreadsheet according to values in a certain column.
    'You can choose the column from which to get the values to colourize, and choose the start row.
    
    'For example, you have a sheet with addresses on it. One of the columns is the city. Now there could
    'be many different cities, and many repeated ones. So, if you want all the lines with "London" colored red,
    'and all the lines with "New York" coloured blue, etc, this program will do that.
    
    'Thanks to Mogulman52 for his input!
    
    Dim colColumn As Integer
    Dim colRow As Integer
    
    Private Sub GetInput()
    
    colColumn = Int(InputBox("Which column number do you want to colourize by?"))
    colRow = Int(InputBox("Which row do you want to start at?"))
    Cells(colRow, colColumn).Select
    Range(Selection, Selection.End(xlDown)).Select
    
    End Sub
    Private Sub ColumnToColours()
    
    Dim hshErrors As New Scripting.Dictionary
    
    Dim colours(0 To 4) As String
     colours(0) = vbYellow
     colours(1) = vbWhite
     colours(2) = vbCyan
     colours(3) = vbMagenta
     colours(4) = vbGreen
     
    Call GetInput ' Creates a selection based on your input
    k = 0 'Colour counter variable
    
    For Each obj In Selection 'For each cell in the column
    
    If k = 5 Then k = 0 'Reset colours counter if necessary
    If (obj.value = 0) Then GoTo EndOfReportReached
    If Not hshErrors.Exists(obj.value) Then
     hshErrors.Add obj.value, colours(k) 'Add the value of the cell as a key value if not already present, and a colour
     k = k + 1 'next colour
    End If
    
    Next obj
     
    EndOfReportReached:
    
    For Each obj In Selection
     If (obj.value = 0) Then Exit Sub 'End of report reached and we don't care anymore
     obj.Interior.Color = hshErrors.item(obj.value) 'Set the background colour according to the value in the cell
    Next obj
    
    Set hshErrors = Nothing
    End Sub
    
    Private Sub ColourRows()
    
    Rows(colRow).Select
    Range(Selection, Selection.End(xlDown)).Select
    intRowCount = Selection.Rows.Count
    
    For j = 0 To intRowCount
     Rows(j + colRow).Select
     Selection.Interior.Color = Selection(colColumn).Interior.Color 'For every row, copy the background colour
     'of the cell to the whole row
    Next j
    
    End Sub
    
    Public Sub Colourize()
    
    Application.ScreenUpdating = False
    Call ColumnToColours
    Call ColourRows
    Application.ScreenUpdating = True
    
    End Sub
    
    
    
    
    Note:  You can add many more colors if you want.  I've just included the VB constant colors to make the example shorter.

    If you found this post helpful, please give it a "Helpful" vote. If it answered your question, remember to mark it as an "Answer".



    Tuesday, July 26, 2011 9:30 AM
  • I wrote a CodePlex project to deliver snazzy color formatted PivotTables each morning based on the last 24 hours eventlog.   Helps me keep a "pulse" on the server farm and notice any strange issues.   Even has "maintenance hours" to exclude "normal" errors from a given daily time window (1AM-4AM).

    Check it out at https://comb.codeplex.com/


    @SPJeff | www.spjeff.com


    • Edited by SPJeff Wednesday, March 26, 2014 12:08 AM link
    Tuesday, March 25, 2014 11:51 PM