Saving Event Logs Using PoSH – My First Ever Script!

Finally after months and months of thinking about it,  I have finally been able to play with Powershell and make it do something useful.

My task was to save the Event Logs Errors off of all of our production servers on a daily basis. I was handed a piece of paper with a list of servers and told to get on with it. I could have easily done it manually, but I would have had to have changed my job title to “Event Log Saver Guy” as that would be all I would have time to do.

So Powershell it was, and what a steep learning curve it turned out to be.

So to start with I had to find a good Powershell Script Editor to help make my life that little bit easier. PowerGUI Script Editior came highly recommended.

Once i had the tools i was now ready to get to work… but where do I start? My first step was to try and get my local PC event logs using the command

Get-eventlog

Simple, this is goning to be straight forward i thought…No quite so fast.

Get-EventLog as it turns out can only be used for the Local host and not remote servers which is what I needed.  After hours of trying to connect to my colleagues Logs, I decided to consult The Oracle.. AKA Alan Renouf and he pointed me to this;

get-wmiobject win32_ntlogevent -filter "type='error'" -computer TEST1

This line of code would return all of the errors on the event logs of the remote computer named TEST1. Great!

Now to perform this command on a list of servers and export the results to a .csv file. I have to confess that I didnt do this alone, I had some great attempts but needed Alan for a bit of guidance here and there. After speaking to Alan he came up with this “One-Liner”

Get-content c:\servers1.txt | foreach { get-wmiobject win32_ntlogevent -filter 
"type='error'" -computer $_ | Select ComputerName, EventCode, Logfile, Message, 
RecordNumber, SourceName, @{N="TimeWritten";E={$_.ConvertToDateTime($_.TimeWritten)}}, 
Type, User | export-csv-force -NoTypeInformation "c:\$_.csv"}

That’s one loooong line…but granted, its all on one line.

This line basicly, gets the list of servers from the file c:\servers.txt and for each server, collects all of the errors found in the event logs and saves them to a .csv which will dynamicly be called <servername>.csv. It’s pretty simple when you break it down, it’s just knowning what commands are available to use.

That was it, that was all I need to complete my task.  That was too easy…so I decided to add a few extra features;

Each week we clear out the event logs so I wanted to create a directory using the week number and i also added the week number to the .csv file name e.g. <servername>-Week23.csv just so they were easier to sort out.

I used the

Get-Date -UFormat %V

command to bring back the week number, but because the first day of the year was on a wednesday the week number changes half way through the week which is not ideal. So with a little help i now use this command to get the week number which starts on monday;

$week = [INT]((((get-date).dayofyear)+2)/7)

So to create a new directory each week I used this simple if statement;

if (!(Test-Path -path C:\Week$week\))
{
New-Item C:\Week$week\ -type directory
}

And to finish with I decided I would like to be Emailed once the script has been succefully run;

$emailFrom = "email1@email.com"
$emailTo = "email2@email.com"
$subject = "Event Logs Retrieved"
$body = "The Event Logs for the following Servers have been Saved, Please check \\<unc 
path>\Week$week\ to make sure they have all be saved ok.

$serverlist"
$smtpServer = "mail.email.com"
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($emailFrom,$emailTo,$subject,$body)

by adding this line to my script;

$serverlist = get-content c:\servers1.txt 

I was able to add the list of servers to my confirmation email.

So my final script looks like this;

$serverlist = get-content c:\servers1.txt
$week = [INT]((((get-date).dayofyear)+2)/7)
if (!(Test-Path -path C:\Week$week\))
{
New-Item C:\Week$week\ -type directory
}
Get-content c:\servers1.txt | foreach { get-wmiobject win32_ntlogevent -filter 
"type='error'" -computer $_ | Select ComputerName, EventCode, Logfile, Message, 
RecordNumber, SourceName, @{N="TimeWritten";E={$_.ConvertToDateTime($_.TimeWritten)}}, 
Type, User | export-csv -force -NoTypeInformation "c:\Week$week\$_-$week.csv"}
$emailFrom = "email1@email.com"
$emailTo = "email2@email.com"
$subject = "Event Logs Retrieved"
$body = "The Event Logs for the following Servers have been Saved, Please check \\<unc 
path>\Week$week\ to make sure they have all be saved ok.

$serverlist"
$smtpServer = "mail.email.com"
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($emailFrom,$emailTo,$subject,$body)

I’m pretty sure the formatting is all wrong and there are easier ways to achieve the functions that i require, but I guess thats all part of the learning.