In the last part of this article series on sending email using PowerShell I demonstrated how to create HTML emails from PowerShell scripts.
- 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
One of the downsides to creating HTML output from PowerShell scripts is that the formatting is not very nice. The default formatting results in messages that look something like this.
The HTML for that email message was created by piping the output from one command into the ConvertTo-HTML cmdlet. Fortunately ConvertTo-HTML has the -Head parameter that can be used to add style information to the HTML that it generates.
For example, by adding this line to the script used in the last article we can change the font to something a little nicer to look at.
$style = "<style>BODY{font:arial 10pt;}</style>"
Then modify the ConvertTo-HTML cmdlet to add the -Head parameter.
$message.Body = Get-ExchangeServer | Select-Object Name,ServerRole | ConvertTo-Html -Head $style
This time when the script is run the email looks like this instead.
That is a little better, but we can do a lot more. How about we add some more styles to the table and really make it look nice.
$style = "<style>BODY{font-family: Arial; font-size: 10pt;}" $style = $style + "TABLE{border: 1px solid black; border-collapse: collapse;}" $style = $style + "TH{border: 1px solid black; background: #dddddd; padding: 5px; }" $style = $style + "TD{border: 1px solid black; padding: 5px; }" $style = $style + "</style>"
Now the script produces an email that looks like this.
Although this requires you to know a little bit about how HTML styles work, it is a pretty easy topic to learn and once you get a few working styles in your scripting tool kit you can just use them over and over again.
Pingback: Localnet Email - Login Information -Official Site
Well that was a head scratcher. I’m guessing the comment section is stripping HTML tags. So things like this line are blank:
$style = $style + “”
The end style tag should be in the quotes. This is why people are complaining about their “style” being in text at the top of their email.
How to conditionally change table row color in html table by power shell command
The CSS is something like this for Odd/Even rows:
tr:nth-child(even) { background-color: #eee; } tr:nth-child(odd) { background-color: #fff; }
Brilliant. Thanks for posting.
Hi , Can u please help me to get table in HTML format in powershell.
Thursday, March 01, 2018 6:53:02 AM
Queue status Count
BadQueue 0
HoldingQueue 0
InboundQueue 0
LanQueue 0
LocalQueue 0
RemoteQueue 0
RetryQueue 76
Diskspace Used Free
E:Drive space 1357.241749 318.1576614
for some reason, when I do my script, the style tag comes out above the table. and the table is formatted plain. this is my script, i am really stuck on this and have tried various ways to get this to work, i am using gmail.
# make the “creds” file first and drop it into a directory.
Write-Host “`n Starting script, connecting to server” -ForegroundColor Green
$creds = Get-VICredentialStoreItem -file “D:…”
connect-viserver -server $creds.Host -User $creds.User -Password $creds.Password
Start-Sleep -s 30
Write-Host “`n Connection to server complete” -ForegroundColor Green
Write-Host “`n Pulling data from Win03vc02” -ForegroundColor Green
$date = Get-Date
$dateforname = Get-Date -UFormat ‘%m-%d-%Y-%H%M%S’
$filename = “VMsnapshots_” + $dateforname + “.html”
$tablestyle = “BODY{font:calibri 14pt;}”
$Report += Get-VM | Get-Snapshot | Select-Object VM,VMId,Description,PowerState,SizeGB | Sort-Object SizeGB | ConvertTo-Html -Head $tablestyle | Out-String
Write-Host “`n Data pulled, sending mail in 60 seconds…” -ForegroundColor green
Start-Sleep -s 60
$from = “a”
$to = “a”
$subject = “VMWare snapshots report for week of $date”
$smtp = “a”
Send-MailMessage -from $from -to $to -subject $subject -BodyAsHtml -Body $Report -smtpServer $smtp
Write-Host “`n e-mail will arrive shortly, process complete!”
I had the same problem.
This style works for me:
$style = “”
$style = $style + “BODY{font-family: Arial; font-size: 10pt;}”
$style = $style + “TABLE{border: 1px solid black; border-collapse: collapse;}”
$style = $style + “TH{border: 1px solid black; background: #dddddd; padding: 5px; }”
$style = $style + “TD{border: 1px solid black; padding: 5px; }”
$style = $style + “”
Pingback: Reparatii Calculatoare
How to add two tables in one e-mail body
Hi All,
I need a pwershell script to get the email alert when site went to disable state in IIS 7.0
can some one help on this, Thanks
Hi Paul,
I am new to Powershell and I am trying to make use of your code above. Basically I want to change font size half way through an email but so far I have failed. The email is set as HTML, and I can get the text to change to italic, but I am stumped on the font size change.
Where the font changes to italic below, I want that font to change to Arial, font size 8. – Many Thanks – Larry
#Message Body
$msg.IsBodyHTML = $True
$msg.Body = ”Please See Attached Files
Many Thanks,
Larry (Test) xxxx“
Sorry Paul, it did not accept the breaks or italic commands in the $msg.body above
Where the “(Test) xxxx” is shown above, this is the text that I want changed
Cheers
Larry
The Real Person!
The Real Person!
Italics in HTML tags is “em” (in pointy brackets) I think.
Ah right I see, thanks Paul.
I’ve amended the script, which now works perfectly.
Thanks again.
Matt
$smtpsettings = @{
To = “me@domain.com”,”me1@domain.com”
From = “ExchangeReports@domain.com”
Subject = “MailBox Report for $((Get-Date).ToShortDateString())”
SmtpServer = “mail.domain.localnet”
}
$style = “BODY{font-family: Arial; font-size: 10pt;}”
$style = $style + “TABLE{border: 1px solid black; border-collapse: collapse;}”
$style = $style + “TH{border: 1px solid black; background: #7FFF00; padding: 5px;}”
$style = $style + “TD{border: 1px solid black; padding: 5px;}”
$style = $style + “”
$MailBoxReport = Get-MailboxDatabase `
| Get-MailboxStatistics | ?{$_.IsArchiveMailbox -eq $false} `
| Sort-Object TotalItemSize -Desc `
| Select-Object DisplayName, Database, TotalItemSize, LastLogonTime, LastLoggedOnUserAccount -First 20 `
| ConvertTo-Html -Head $style
Send-MailMessage @smtpsettings -Body $MailBoxReport -BodyAsHTML
Hey, Matt.
I’ve tried to add this line “Send-MailMessage @smtpsettings -Body $MailBoxReport -BodyAsHTML” into sharepoint powershell function, but it returns an error. LOL
what can i do?
The Real Person!
The Real Person!
Maybe sharing the error message would be helpful.
Hey thanks for this. If you wanted to add more than one table in the body of an email, how would you do so using this script?
Thanks
Hello Paul,
Great script, it works very well.
Just one question though – how do you specify multiple email recipients?
Thanks
The Real Person!
The Real Person!
As a comma-separated list.
Eg, “address1@domain.com”,”address2@domain.com”
Thanks for the reply Paul.
I tried a comma separated list before posting the comment – the error returned is below:
New-Object : Exception calling “.ctor” with “2” argument(s): “The specified string is not in the form required for an e-mail address.”
The script runs but the only the first email address in the list receives the email.
Script is below:
$smtpServer = “mail.domain.localnet”
$smtpFrom = “ExchangeReports@domain.com”
$smtpTo = “me@domain.com”,”me1@domain.com”
$messageSubject = “MailBox Report for $((Get-Date).ToShortDateString())”
$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true
$style = “BODY{font-family: Arial; font-size: 10pt;}”
$style = $style + “TABLE{border: 1px solid black; border-collapse: collapse;}”
$style = $style + “TH{border: 1px solid black; background: #7FFF00; padding: 5px;}”
$style = $style + “TD{border: 1px solid black; padding: 5px;}”
$style = $style + “”
$message.Body = Get-MailboxDatabase `
| Get-MailboxStatistics | ?{$_.IsArchiveMailbox -eq $false} `
| Sort-Object TotalItemSize -Desc `
| Select-Object DisplayName, Database, TotalItemSize, LastLogonTime, LastLoggedOnUserAccount -First 20 `
| ConvertTo-Html -Head $style
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($message)
The Real Person!
The Real Person!
Ah, I really should update this article series to get rid of the PowerShell 1.0 references.
So if you look back at this part you’ll see the PowerShell 2.0 method for sending email, which uses a proper cmdlet Send-MailMessage.
https://www.practical365.com/powershell-how-to-send-email/
An example:
==================================
$smtpsettings = @{
To = “administrator@exchangeserverpro.net”
From = “exchangeserver@exchangeserverpro.net”
Subject = “Exchange CAS Health Report – $now”
SmtpServer = “smtp.exchangeserverpro.net”
}
Send-MailMessage @smtpsettings -Body $whatever
==================================
So in this case that To should accept multiple comma-separated addresses.
If you’re looking for some more comprehensive examples most if not all of the scripts available in http://inside.exchangeserverpro.com have code for sending email.
Hi Logan
Did Paul ever reply to you? I have a scenario where I have two tables in my message body, but the second one doesn’t seem to adhere to the formatting. Yet if I output the entire message body to and HTML file and open in a browser, it looks right. Seems like Outlook or the send-mailmessage cmdlet is doing something with the formatting.
Oops, sorry – my copy/paste didn’t work so well there. The ‘$style’ code should be:
$style = “BODY{font-family: Arial; font-size: 10pt;}”
$style = $style + “TABLE{border: 1px solid black; border-collapse: collapse;}”
$style = $style + “TH{border: 1px solid black; background: #dddddd; padding: 5px; }”
$style = $style + “TD{border: 1px solid black; padding: 5px; }”
$style = $style + “”
Hi Paul, great write up.
I have followed all 4 parts of your series and have had good success. The only thing I can’t get working is the table formatting from this latest part. The tags don’t seem to be getting processed, the HTML code is simply printed at the top of email body verbatim (before the cmdlet’s output).
Here’s my script:
$smtpServer = “localhost”
$smtpFrom = “name1@test.com”
$smtpTo = “name2@test.com”
$messageSubject = “Test”
$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true
$style = “BODY{font-family: Arial; font-size: 10pt;}”
$style = $style + “TABLE{border: 1px solid black; border-collapse: collapse;}”
$style = $style + “TH{border: 1px solid black; background: #dddddd; padding: 5px; }”
$style = $style + “TD{border: 1px solid black; padding: 5px; }”
$style = $style + “”
$message.Body = Get-MailboxExportRequest | Get-MailboxExportRequestStatistics | Select-Object SourceAlias,Status | ConvertTo-Html -Head $style
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$credentials=new-object system.net.networkcredential(”user”,”password”)
$smtp.credentials=$credentials.getcredential($smtpServer,25,”basic”)
$smtp.Send($message)
Thanks!
Hey Paul,
This guide is awesome and I’ll definitely be using it to create some custom alerts for my servers.
There is one thing that I wanted to nitpick though.
Where you assigned values to the style sheet variable, there is a short way to do it:
$style = “BODY{font-family: Arial; font-size: 10pt;}
TABLE{border: 1px solid black; border-collapse: collapse;}
TH{border: 1px solid black; background: #dddddd; padding: 5px; }
TD{border: 1px solid black; padding: 5px; }
”
Unless there is a reason why you did it your way?… I am still new to PS.
Pingback: How to Automate Exchange 2010 Database Backup Alert Emails
Very useful tip!
Thanks a lot.
Pingback: PowerShell: How to Add a HTML Message Body to Emails Sent from Scripts