How to Send Alerts to Your Mailbox using .NET

By Jesse Hamrick • August 14th, 2008

Sending Email.I received a request from a colleague asking if I had a script that would poll a file and send him an email if a file's size became larger than 2k. Apparently they are using an application that was written by a friend-of-a-friend who is no longer in the Software Business so there is no support for the product. How does this kind of stuff happen???

My reaction was wow! What happens when the file grows larger than 2k(yes you are reading this correctly, 2k)? My colleague replied, "The app slows down, sometimes locks up, and users start to complain. Our course of action is to delete the file, the application regenerates it and we start all over again. Attempting to be pro-active, we periodically check the file size by manually browsing the file properties. Most of the time we are able to catch and fix the problem before the users are affected. It's just the times we miss all hell breaks loose." I said, "I can help you with that issue…"

Let's create an early warning system so that we are compliant with the famous buzz word "Pro-Active!"

First, the email template:

#* =========================
#* SMTP Mail Alert
#* =========================

#* Create new .NET object and assign to variable
$mail = New-Object System.Net.Mail.MailMessage

#* Sender Address
$mail.From = New-Object System.Net.MailAddress("user@domain.com");

#* Recipient Address
$mail.To.Add("user@domain.com");

#* Message Subject
$mail.Subject = "Place Subject of email here";

#* Message Body
$mail.Body = "Place body content here";

#* Connect to your mail server
$smtp = New-Object System.Net.Mail.SmtpClient("yourdomain.com");

#* Uncomment line below if authentication is required
#* $smtp.Credentials = New-Object System.Net.NetworkCredential("username", "passwd");

#* Send Email
$smtp.Send($mail);

Now that we have our template, let me explain how I provided a solution. Basically I created a script (shown below) that uses the email template as a function. When the script runs it enumerates the file size and based on the condition it either calls the mail function to send a warning or it does nothing. I set up a Windows task schedule to run the script every 15 minutes, times may vary depending on the situation.

AlertMe.ps1

#* ======================
#* Alert Me Script
#* ======================
#* Create Email Function
#* ======================
function sendEmail {

#* Create new .NET object and assign to variable
$mail = New-Object System.Net.Mail.MailMessage

#* Sender Address
$mail.From = New-Object System.Net.MailAddress("user@domain.com");

#* Recipient Address
$mail.To.Add("user@domain.com");

#* Message Subject
$mail.Subject = "Place Subject of email here";

#* Message Body
$mail.Body = "Place body content here";

#* Connect to your mail server
$smtp = New-Object System.Net.Mail.SmtpClient("yourdomain.com");

#* Uncomment line below if authentication is required
#* $smtp.Credentials = New-Object System.Net.NetworkCredential("username", "passwd");

#* Send Email
$smtp.Send($mail);

}

#* =====================
#* Script Body
#* =====================

#* Connect to file. You can connect to a local file or a remote file via UNC.
#* In this example I connect to a remote share
$File = Get-ChildItem "\\ServerName\ShareName\Path\File.txt"

#* Check File size and take action based on condition.
if ($File.Length -gt 2000)
#* If condition is TRUE call sendEmail function
{sendEmail}

#* If condition is FALSE script does nothing

The template can also be used to send warnings for:

  • Disk Space Issues
  • CPU usage
  • Memory consumption
  • Runaway processes
  • Event Log monitoring

Just to name a few, the possibilities are limitless…

Email This Post To A Friend Email This Post To A Friend 

Comments

How did you get AlertMe.ps1 to be scheduled and still run with noone logged onto the system? Would that work with all ps1 scripts?

By Jesse Hamrick on August 15th, 2008 at 2:36 pm

Since I’m connecting to a share, I set up the task scheduler to run under an account that has access to the local system and the file on the file server. The script runs when no one is logged on the system. Yes, It should work with all ps1 scripts.
To set up a ps1 file to run in a scheduled task:
Path in Run box: C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -command “& C:\Path\scriptName.ps1″
This consists of the location of PowerShell.exe (above is the default location) and the script you wish to run.
If there a spaces in the path name it should look like this “& ‘C:\Program Files\Scripts\ScriptName.ps1′”

AWESOME! Thank you!

Hi, I’m having issues running your script I get

“New-Object : Cannot find type [System.Net.MailAddress]: make sure the assembly containing this type is loaded” as an error.

I am running powershell 1.0

I modified your script though so that instead of

$mail.From = New-Object System.Net.MailAddress(“user@domain.com”);

it becomes

$mail.From = user@domain.com“;

and it seems to work now. I’m just posting to let you know.

instead: “$smtp.Credentials = New-Object System.Net.NetworkCredential(“username”, “passwd”);”
you can use: $smtp.UseDefaultCredentials = $true

I’m having difficulty getting an array of values that I’m trying send as the $mail.body – despite every formatting trick I’ve tried, they continuously come across all strung together. The best I’ve been able to do is send in non-HTML format to Outlook and the message “Extra line breaks in this message were removed.” appears above the To: line. I can click that and then the message appears as I would like, but that’s a hassle given the nature of how my alerts work.

Here’s the code that almost works:

… $result is loaded as an array from a SQL query …

$result = $DataSet.Tables[0] | foreach-object { $mail.Body += $_.msg+”`n” }

if ($mail.Body -ne $null) {
$smtp = new-object System.Net.Mail.SmtpClient(”my.mail.server”)
$smtp.Send($mail) }

I have the template set up in powershell and was wondering how to test it to see if it works?

By Kevin Marquette on July 9th, 2010 at 1:49 pm

This is a great example of how to send emails from Powershell.

You should offer your colleague version 2 of the script where you just delete the file for him.

Hello! I used the same fix as Deon and it worked; otherwise, it gave up an error: “New-Object : Cannot find type [System.Net.MailAddress]: make sure the assembly containing this type is loaded.”

What a neat thing! Thank you!

By Jimesh Makawana on September 14th, 2012 at 5:15 am

Hi
I got below error when run this script

—————————————Sending Email
Property ‘Credentials’ cannot be found on this object; make sure it exists and is settable.
At line:7 char:12
+ $smtp. <<<< Credentials = New-Object System.Net.NetworkCredential("jimesh", "JimeSh@70");
+ CategoryInfo : InvalidOperation: (Credentials:String) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound

Exception calling "Send" with "1" argument(s): "The SMTP server requires a secure connection or the client was not authenticated. The server response was: Authentication required"
At line:23 char:16
+ $smtp.Send <<<< ($msg)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

 

Leave a Comment

« | Home | »