In the last part of this series we looked at simple techniques for sending email from PowerShell.
- Part 1 – How to Send SMTP Email Using PowerShell
- Part 2 – How to Add a Message Body to Emails Sent from Scripts
- Part 3 – How to Add a HTML Message Body to Emails Sent from Scripts
- Part 4 – How to Create Formatted HTML Output from Scripts
In this article we’ll take a closer look at how you can create the email message body for emails that you are sending via PowerShell.
In the last article I demonstrated a simple PowerShell script for sending emails that contained the following code, using the SmtpClient .NET object .
# #.SYNOPSIS #Sends SMTP email via the Hub Transport server # #.EXAMPLE #.Send-Email.ps1 -To "administrator@exchangeserverpro.net" -Subject "Test email" -Body "This is a test" # param( [string]$to, [string]$subject, [string]$body ) $smtpServer = "ho-ex2010-caht1.exchangeserverpro.net" $smtpFrom = "reports@exchangeserverpro.net" $smtpTo = $to $messageSubject = $subject $messageBody = $body $smtp = New-Object Net.Mail.SmtpClient($smtpServer) $smtp.Send($smtpFrom,$smtpTo,$messagesubject,$messagebody)
Now let’s build on that example by adding more content to the message body of the emails.
Using Command Output as Email Message Content with PowerShell
When running this script anything that we specify with the -Body parameter will be the message body of the email. It could be a text string, or it could even be the output from another PowerShell command. For example:
[PS] C:Scripts>.Send-Email.ps1 -To "administrator@exchangeserverpro.net" -Subject "List of Exchange Servers" -Body (Get-ExchangeServer)
The command above would produce an email that looks like this:
Neat trick, but notice how the list of Exchange servers appears as all one string that wraps over two lines? Wouldn’t it be nicer to see the server names displayed in an easier to read list format? Let’s take a look at how you can achieve that.
[PS] C:Scripts>[string]$emailbody = "" [PS] C:Scripts>$servers = Get-ExchangeServer [PS] C:Scripts>foreach ($server in $servers) {$emailbody = $emailbody + $server.name + "`r`n"} [PS] C:Scripts>.Send-Email.ps1 -To "administrator@exchangeserverpro.net" -Subject "List of Exchange Servers" -Body $emailbody
So what did I do there? Here are the steps I just followed:
- Declare a variable $emailbody as type string. This will be the variable that is passed to the script to be the message body of the email that gets sent.
- Used the Get-ExchangeServer cmdlet to retrieve a list of the Exchange servers in the organization into an array of $servers.
- Looped through the array using the ForEach-Object (abbreviated to “foreach”) cmdlet and appended each server name to the $emailbody string, including (and this is the important part) a carriage return after each server name.
- Ran the script using the $emailbody variable for the -Body script parameter.
The result is an email that looks like this; much better don’t you agree?
Now this is only a demonstration. In reality you probably aren’t going to want to send yourself an email with a list of your Exchange servers, at least not very often.
However you can use the same techniques I’ve just demonstrated to build scripts that email you any command or script output, such as a list of mailboxes with no storage quotas that you have emailed to yourself automatically each month.
Using File Contents as Email Message Content with PowerShell
Another technique for getting content for the message body of an email sent via PowerShell is to use the contents of a file.
For example, I run continuous pings between certain servers to detect any network interruptions that may be occurring. An entry is written to a log file any time a ping times out. Every day I want to receive an email with the results of the previous day’s ping monitoring, so I can do that using a script like this.
# #.SYNOPSIS #Sends daily dropped ping report # #.EXAMPLE #.Send-DroppedPingReport.ps1 # $smtpServer = "ho-ex2010-caht1.exchangeserverpro.net" $smtpFrom = "reports@exchangeserverpro.net" $smtpTo = "administrator@exchangeserverpro.net" $messageSubject = "Dropped ping report" [string]$messagebody = "" $logs = Get-Content C:Logsdroppedpings.log foreach ($log in $logs ) { $messagebody = $messagebody + $log + "`r`n" } $smtp = New-Object Net.Mail.SmtpClient($smtpServer) $smtp.Send($smtpFrom,$smtpTo,$messagesubject,$messagebody)
This is the same technique that was used earlier to create an array and loop through it to add the carriage returns so that the email is formatted nicely. The main difference is the use of Get-Content instead of Get-ExchangeServer.
As you can see it is very simple to create useful, informative emails that are sent by your PowerShell scripts.
Thanks! Very helpful for creating useful e-mail messages.
Hi, How can i add content in the email body(not in email subject), help me with the script part and write it for me
Hi Paul ,
i need your help please. our SCOM server is down actually and i need to monitor our replication on Hyperv via powershell command. i found this command :
Get-VMReplication -ComputerName Hyperv1-HQ.domain .com
i need the output of this poweshell to be send to me and other colleague via email on a daily basis twice per day, what is the way to do it?
also can i get the output via email for multiple command for example :
Get-VMReplication -ComputerName Hyperv1-HQ.domain.com
Get-VMReplication -ComputerName Hyperv2-HQ.domain.com
etc…
thanks a lot.
Tony.
Hi Paul,
This is very useful article. Thanks for sharing your knowledge. I’m new to powershell scripting and these articles are crystal clear and very useful.
I wrote a script for my purpose where it has to trigger an email based on the windows event viewer log. The syntax seems to be correct however I’m getting below error. By any chance do you know what is the issue?
Error message:
send-mailMessage : Mailbox unavailable. The server response was: 5.7.60 SMTP; Client does not have permissions to send
as this sender
At D:\Powershell Scripts\EventLogNotification.ps1:15 char:2
+ send-mailMessage -From $emailfrom -To $emailto -Subject $emailsubject -Body $em …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.Mail.SmtpClient:SmtpClient) [Send-MailMessage], SmtpExcept
ion
+ FullyQualifiedErrorId : SmtpException,Microsoft.PowerShell.Commands.SendMailMessage
Hi,
While sending email through power shell i’m getting display name as email address.
Is there parameter to set a Display Name for Email to receive instead of email address
That helped me. Thank you!
God bless
Hello,I check your blog named “PowerShell: How to Add a Message Body to Emails Sent from Scripts” daily.Your story-telling style is awesome, keep doing what you’re doing! And you can look our website about free ip proxy https://proxylistdaily4you.blogspot.com/.
@Ricky Valencia
If you find a solution to put file.txt content in the message body of the email, it would be nice if you share that knowledge here too!
I and others have the same question.
The Real Person!
The Real Person!
Ingest the file contents to a variable using Get-Content, then use that variable as the message body.
Eg..
$filecontent = Get-Content .File.txt
Then in the Send-MailMessage command use the -Body parameter, e.g.
-Body $filecontent
Hi Eddie,
You can create a distribution group and send to that address or create a variable and separate the recipients with ,
example:
$recipients = “Boss “, “employee1 ”
Send-MailMessage -To $recipients -Subject ‘New Mail’ -Body $messagebody -SmtpServer $smatpserver -From ‘alerts@domain.com’
I prefer distribution group as it is easier to manage without editing the script every time
Best,
Sean Noy
how do i send to multiple recipients?
Good Article Paul.. Thank you for sharing..
Hi Paul,
Kindly ignore my previous question. I was able to find the solution. I have a second question though, how do i send to multiple recipients?
HI Paul,
Great article. I have a question. I have 2 files (txt files) and the contents of those file I want to make it as email message content and send to my email. How can I do that? THank you.
Hi Ricky,
I have the same problem, I have power shell script for sending backup log file (.txt)in email attachment from task scheduler & its working fine . now I want to send .txt file contents in email body , can you please share the script of this.
How to add an attachment. I am using Windows 2012 R2 Server.
The Real Person!
The Real Person!
If you use the Send-MailMessage cmdlet to send emails from PowerShell it has an -Attachments parameter.
https://technet.microsoft.com/en-us/library/hh849925.aspx
Very nice (was on the verge of saying elegant). Too bad Send-MailMessage doesn’t do this automatically for txt files (ie treat it as/is).
Very nice Blog. Thanks much.
Paul,
Here’s a bit of another challenge. In Exchange, you can create a foreign connector with an address space with a transport rule for routing. An example would be with RightFax.
new-foreignconnector -name “RightFaxConnector” -addressspaces (“RFAX:*;1″,”FAX:*;1”)
So, in the example of RightFax, you address for sending would be FAX:Name@1112223333
To send from an email client, you would simply include brackets: [FAX:Name@1112223333]
However, with Powershell, the send-mailmessage expects a static format of recipient@domain.com
However, if you try to use send-mailmessage, the cmdlet won’t recognize the address space and the recipient is invalid.
Neither the Powershell 1.0 nor the Powershell 2.0 methods work.
Is it possible to send an email using a different address space with Powershell?
Pingback: private investigator badges and id's
Pingback: How to Automate Exchange 2010 Database Backup Alert Emails
Pingback: PowerShell: How to Add a HTML Message Body to Emails Sent from Scripts