October 30th, 2009

Sending Automated emails with Send-MailMessage, ConvertTo-HTML, and the PowerShellPack’s TaskScheduler module

PowerShell Team
PowerShell Team

On October 15th I released a large collection of scripts called the PowerShellPack.  The PowerShellPack has tons of PowerShell V2 scripts that can be used to do all sorts of fun and practical things.  Today, we’ll show how to use a module in the PowerShell Pack to schedule sending a daily automated email with information about the installed programs on a given system.

Turning the output of a PowerShell script into an automated email is a snap in PowerShell V2, thanks to a nifty new cmdlet called Send-MailMessage.  Send-MailMessage sends out emails with the credentials of the current user (or an arbitrary user) and an SMTP server.  Send-MailMessage can send HTML emails by using the –BodyAsHtml switch, and ConvertTo-HTML can take the output of a cmdlet and turn it into an HTML chunk.  If the email needs some introduction and a signature, you can always use ConvertTo-HTML’s new –PreContent and –PostContent parameters.

Here’s a quick chunk of script that will send the email message once.  Notice that instead of having a very long line with a lot of parameters, I keep the parameters to Send-MailMessage in a Hashtable and use Splatting to provide them to Send-MailMessage

            $messageParameters = @{
                Subject = "Installed Program report for $env:ComputerName.$env:USERDNSDOMAIN - $((Get-Date).ToShortDateString())"
                Body = Get-WmiObject Win32_Product |
                    Select-Object Name, Version, Vendor |
                    Sort-Object Name |
                    ConvertTo-Html |
                    Out-String
                From = "Me@MyCompany.com"
                To = "Me@MyCompany.com"
                SmtpServer = "SmtpHost"
            }
            Send-MailMessage @messageParameters -BodyAsHtml                        

Now that we’ve got that chunk of code down, let’s go ahead and make sure that any problems we encounter get put into a file somewhere.  I can do this by setting one of PowerShell’s magic variables $ErrorActionPreference = “Stop”, and adding a try/catch around all of my code:

        $ErrorActionPreference = "Stop"
        try {
            $messageParameters = @{
                Subject = "Installed Program report for $env:ComputerName.$env:USERDNSDOMAIN - $((Get-Date).ToShortDateString())"
                Body = Get-WmiObject Win32_Product |
                    Select-Object Name, Version, Vendor |
                    Sort-Object Name |
                    ConvertTo-Html |
                    Out-String
                From = "Me@MyCompany.com"
                To = "Me@MyCompany.com"
                SmtpServer = "SmtpHost"
            }
            Send-MailMessage @messageParameters -BodyAsHtml
        } catch {
            $_ |
                Out-File $env:TEMP\ProblemsSendingHotfixReport.log.txt -Append -Width 1000
        }

Finally, I’ll just go ahead and use the TaskScheduler module from PowerShellPack to make sure the email arrives every day.  To do this, I’ll need to download the PowerShellPack to the machine I’ll be scheduling the task on.   Scheduling a task with the PowerShell Pack involves a short pipeline:  Ours will look something like:

New-Task |
    Add-TaskAction -Script {
        # Our Emailer Here
    } |
    Add-TaskTrigger -Daily -At "9:00 AM" |
    Add-TaskTrigger -OnRegistration |
    Register-ScheduledTask "DailyHotfixReport"                

Piece of cake, right?  In our case, we’re sending an email at 9 AM every day (and when the task is registered) with the output of a simple cmdlet, but I could also use this to run a more complex task, and I can play around with the different trigger types to send the emails whenever I’d like.

Here’s the full script:

 

New-Task |
    Add-TaskAction -Hidden -Script {
        $ErrorActionPreference = "Stop"
        try {
            $messageParameters = @{
                Subject = "Installed Program report for $env:ComputerName.$env:USERDNSDOMAIN - $((Get-Date).ToShortDateString())"
                Body = Get-WmiObject Win32_Product |
                    Select-Object Name, Version, Vendor |
                    Sort-Object Name |
                    ConvertTo-Html |
                    Out-String
                From = "Me@MyCompany.com"
                To = "Me@MyCompany.com"
                SmtpServer = "SmtpHost"
            }
            Send-MailMessage @messageParameters -BodyAsHtml
        } catch {
            $_ |
                Out-File $env:TEMP\ProblemsSendingHotfixReport.log.txt -Append -Width 1000
        }
    } |
    Add-TaskTrigger -Daily -At "9:00 AM" |
    Add-TaskTrigger -OnRegistration |
    Register-ScheduledTask "DailyHotfixReport"

That wasn’t bad, was it?  It took only 24 lines of PowerShell script to create a schedule task that emails me a fairly detailed report of all of the installed programs on the machine. As you can see, PowerShell V2 makes sending automated emails a snap, and the PowerShellPack makes scheduling this or any other script on a regular basis a piece of cake.

Hope this Helps,

James Brundage [MSFT]

Author

PowerShell Team
PowerShell Team

PowerShell is a task-based command-line shell and scripting language built on .NET. PowerShell helps system administrators and power-users rapidly automate tasks that manage operating systems (Linux, macOS, and Windows) and processes.

0 comments

Discussion are closed.