none
How to write script errors into a custom event log ...

    Question

  • So I've run the following code on one of my servers to create a custom event log and source:

    New-EventLog -LogName psLogs -source scripts
    Limit-EventLog -overflowaction overwriteasneeded -maximumsize 1MB -logname psLogs
    Write-EventLog -LogName psLogs -Source scripts -Message "PsLogs Event Log Setup Complete!" -EventId 0 -EntryType information
    Write-Host "PsLogs Event Log Setup Complete!"

    This works fine since I ran it as "Administrator"

    Next question is how do I incorporate this Event Log into a script that I am running via task scheduler so that if the scheduled script errors it will output the errors to this log?  I would also like to know how to write the Information and Warning types too.

    In other words if I run a script that automatically installs printers via a CSV and the thing errors out for any reason I want an entry in my Custom Event Log to appear.



    • Edited by Wasisname Wednesday, August 07, 2013 6:51 PM Clarification for future readers
    Thursday, July 04, 2013 8:54 PM

Answers

  • You could do something along those lines, yes.  I would personally prefer to trap the errors close to where they occur, but it is technically possible to do this at the end of the script, as you suggest.  For that approach, I would recommend calling $error.Clear() at the beginning of the script (to make sure you're not writing errors that happened to exist earlier in the same PowerShell session).

    I would recommend creating a separate event for each error that occurs, rather than trying to generate one entry in the event log that contains all of the errors in the entire script.  Otherwise, there's a chance you may reach the maximum event message size (32768 characters, if I remember correctly).  Something like this:

    $error.Clear()
    
    # ... script does work
    
    foreach ($errorRecord in $error) {
        Write-EventLog -LogName psLogs -Source scripts -Message "$($errorRecord | Out-String)" -EventId 0 -EntryType Error
    }


    Also, keep in mind that by default, only 256 errors are stored in the $error variable before it starts to overwrite the oldest entries.  One would hope that your script doesn't generate 256+ errors, but if you're operating on very large numbers of objects, it's possible.  You can update the $MaximumErrorCount variable to change this default value, if you like.
    Tuesday, July 09, 2013 5:57 PM
  • You can also use try and catch

    Try { SomeFunction }
    Catch {Write-eventlog -message $_.Exception.message}

    That'll put the specific errors as individual entries in your log.  After that you can get more specific with your errors using if statements to filter as needed.


    Hope that helps! Jason

    Wednesday, July 10, 2013 2:55 PM

All replies

  • You'd just need to incorporate more Write-EventLog commands into your other script, similar to the one you already posted. The -EntryType parameter controls what type of event you're writing; valid values are Error, Warning, Information, SuccessAudit and FailureAudit.

    Write-EventLog -LogName psLogs -Source scripts -Message "This is a test Information message." -EventId 1 -EntryType information
    
    Write-EventLog -LogName psLogs -Source scripts -Message "This is a test Warning message." -EventId 2 -EntryType Warning
    
    

    Friday, July 05, 2013 12:49 AM
  • I guess I don't understand because it looks like that code would write to the eventlog no matter what and that what will be written is what is between the quotes? 

    I want the errors to be written as they occur and those errors may vary depending on the script's error if there is one or more.

    Friday, July 05, 2013 1:38 PM
  • Ah.  As far as I know, there is currently no way to just automatically redirect all errors generated by a PowerShell script to an event log.  You still need to have your script perform error checking, and call Write-EventLog as needed.

    We're currently discussions some options for automatic redirection of PowerShell output to other targets (be it a log file, event log, whatever) in this thread:  http://social.technet.microsoft.com/Forums/scriptcenter/en-US/dd865899-26f2-42f6-a403-04528fa48541/scripting-logging-in-powershell-discussion .  It's still in an early design phase, but eventually you might be able to use this new module to achieve what you're looking for.

    Friday, July 05, 2013 1:44 PM
  • *ACK*

    That's a bummer.  I don't have a development background, so much of what I'm reading on your linked thread is over my head.  A lot of things like this seem as if it should be a straight forward process or built into some type of CMDlet/string of CMDlets and, disappointingly, it ends up being very complicated, at least from my perspective.

    Thanks for the information.

    Friday, July 05, 2013 3:22 PM
  • Hi,

    I agree with David, Write-EventLog cmdlet could be used to create custom event log, please also refer to the below article:

    http://www.petri.co.il/use-powershell-to-create-custom-log-events.htm

    Regards,

    Yan Li

    If you have any feedback on our support, please click here .


    Cataleya Li
    TechNet Community Support

    Tuesday, July 09, 2013 6:34 AM
    Moderator
  • Yan LI

    I have gotten as far as creating a custom event log and a source.  I know that I can write to the event log using this source.  But the real difficulty for me lays in the fact that there isn't a way, as of yet, to redirect errors generated by my script to this eventlog.  I could write a verbatim statement to it, but what I want is variable, not predefined, because that doesn't help me find the problem. 

         The error could be "Access Denied" or something like "Object cannot be null".  Whatever the error generated by a failure in the script's attempt to run is - (and not pre-defined by myself) - is what I want sent to the event logs.  For example if I run an automated script via task scheduler, such as making changes to printers, and it fails for any reason I'd like to be able to check the event log for the errors.  Simply getting the generic "An error occured." isn't helpful.

    But as David stated thus far there isn't a way to do this.


    • Edited by Wasisname Tuesday, July 09, 2013 1:33 PM redundancy
    Tuesday, July 09, 2013 1:31 PM
  • Could you perhaps add the following line of code to the end a script to accomplish what I'm after?

    Write-EventLog -LogName psLogs -Source scripts -Message "$error" -EventId 0 -EntryType Error
    Perhaps with an if,else statement that checks whether $error -NE "null" then do the Write-Eventlog CMDlet?


    • Edited by Wasisname Tuesday, July 09, 2013 3:04 PM code correction
    Tuesday, July 09, 2013 3:01 PM
  • You could do something along those lines, yes.  I would personally prefer to trap the errors close to where they occur, but it is technically possible to do this at the end of the script, as you suggest.  For that approach, I would recommend calling $error.Clear() at the beginning of the script (to make sure you're not writing errors that happened to exist earlier in the same PowerShell session).

    I would recommend creating a separate event for each error that occurs, rather than trying to generate one entry in the event log that contains all of the errors in the entire script.  Otherwise, there's a chance you may reach the maximum event message size (32768 characters, if I remember correctly).  Something like this:

    $error.Clear()
    
    # ... script does work
    
    foreach ($errorRecord in $error) {
        Write-EventLog -LogName psLogs -Source scripts -Message "$($errorRecord | Out-String)" -EventId 0 -EntryType Error
    }


    Also, keep in mind that by default, only 256 errors are stored in the $error variable before it starts to overwrite the oldest entries.  One would hope that your script doesn't generate 256+ errors, but if you're operating on very large numbers of objects, it's possible.  You can update the $MaximumErrorCount variable to change this default value, if you like.
    Tuesday, July 09, 2013 5:57 PM
  • This is awesome!  At least it appears so preliminarily.  I haven't, as of yet, come across an instance of an automated script in my environment that would need to handle the 256 errors.  As it stands any time I've dealt with a number of objects that approaches having the possibility of generating that many, I run it manually and can see that it's generating errors.

    Just for informational purposes, is updating the $MaximumErrorCount a permanant change or only for that session; would I need to include that change in each script?

    • Edited by Wasisname Wednesday, July 10, 2013 2:25 PM clarification
    Wednesday, July 10, 2013 2:24 PM
  • You'd need to set it in each script (or in a profile);  it returns to the default setting for new sessions.

    Wednesday, July 10, 2013 2:31 PM
  • TYVM! :)

    I will likely mark your previous comment as the answer, but not for a day or so in case I come into a problem or have further related question(s).

    The scheduled task scripts don't often run into errors so I won't wait for that to occur.


    • Edited by Wasisname Wednesday, July 10, 2013 2:43 PM clarification
    Wednesday, July 10, 2013 2:42 PM
  • You can also use try and catch

    Try { SomeFunction }
    Catch {Write-eventlog -message $_.Exception.message}

    That'll put the specific errors as individual entries in your log.  After that you can get more specific with your errors using if statements to filter as needed.


    Hope that helps! Jason

    Wednesday, July 10, 2013 2:55 PM
  • It will also allow you to monitor the event log as the script runs as the errors will be logged as they occur

    Hope that helps! Jason

    Wednesday, July 10, 2013 2:56 PM