Sending Formatted HTML email

Sunny picture Sunny · Oct 29, 2013 · Viewed 32.3k times · Source

I have a text file output.txt which has following content:

OPERATINGSYSTEM     PROJECTSERVER1   PROJECTSERVER2
Windows                       1.36             4.42
Linux12                       2.78             5.76
MacOS                         3.45             6.39
Ubuntu                        4.12             0.00
Android                       0.00             3.46
FreePhysicalMemory           30.12            31.65
TotalVisibleMemorySize       48.00            48.00
CPULoadPercentage                2                4

I want to send content of output.txt in a email as a body in Formatted HTML table look in Windows server 2008 R2. I am trying with below code, but its not working for me..where am I mistaking below ?

$smtpServer = "[email protected]"
$smtpFrom = "[email protected]"
$smtpTo = "[email protected]"
$messageSubject = "Servers Memory"

$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true

$message.Body = Get-Content C:\Logs\output.txt
$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>"

$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($message)

EDIT1

When i modified my code as below:

$smtpServer = "[email protected]"
$smtpFrom = "[email protected]"
$smtpTo = "[email protected]"
$messageSubject = "Servers Memory"

$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true

$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>"
$message.Body = "<head><pre>$style</pre></head>"
$message.Body += Get-Content C:\Logs\output.txt

$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($message)

I am getting mail like this:

OPERATING SYSTEM SERVER1 SERVER2 Windows 1.36 4.42 Linux 2.78 5.76 MacOS 3.45 6.39 Android 0.00 3.46 Ubuntu 4.12 0.00 FreePhysicalMemory 30.12 31.65 TotalVisibleMemorySize 48.00 48.00 

Note: I am using Powershell v1.0

Answer

Adi Inbar picture Adi Inbar · Oct 29, 2013

Okay, the question is a little unclear, but I'll take a stab at it based on what I infer is "not working for you". I'm guessing that your script is successfully sending the message, and what's not working is that the formatting of the message is all wrong, for two reasons:

  1. output.txt is in plain text, not HTML. When rendered in HTML, the whitespace won't be preserved and there won't be any line breaks. If the whitespace consists of spaces, the consecutive spaces will be reduced to single spaces, and if it's tabs, I believe the text will all run together with no whitespace at all. I take it you were expecting $message.IsBodyHTML = $true to convert your plain text input to HTML, but that's not what it does. It just sets a property of the message that instructs mail clients to interpret the body as HTML (specifically, it sets the Content-Type header to "text/html"), but you have to actually supply it HTML code.
  2. You're setting the $style variable to a bunch of CSS code, but then you don't do anything with it. I presume you intended to add it to $message.Body. The problem with that is that you can't reliably put a style sheet in an email message; most clients will ignore it. The styles have to be inline.

output.txt should look like this:

<body style="font-family: Arial; font-size: 10pt;">
  <table style = "border: 1px solid black; border-collapse: collapse;">
    <tr>
      <th style = "border: 1px solid black; background: #dddddd; padding: 5px;">OPERATINGSYSTEM</th>
      <th style = "border: 1px solid black; background: #dddddd; padding: 5px;">PROJECTSERVER1</th>
      <th style = "border: 1px solid black; background: #dddddd; padding: 5px;">PROJECTSERVER2</th>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">Windows</td>
      <td style = "border: 1px solid black; padding: 5px;">1.36</td>
      <td style = "border: 1px solid black; padding: 5px;">4.42</td>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">Linux12</td>
      <td style = "border: 1px solid black; padding: 5px;">2.78</td>
      <td style = "border: 1px solid black; padding: 5px;">5.76</td>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">MacOS</td>
      <td style = "border: 1px solid black; padding: 5px;">3.45</td>
      <td style = "border: 1px solid black; padding: 5px;">6.39</td>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">Ubuntu</td>
      <td style = "border: 1px solid black; padding: 5px;">4.12</td>
      <td style = "border: 1px solid black; padding: 5px;">0.00</td>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">Android</td>
      <td style = "border: 1px solid black; padding: 5px;">0.00</td>
      <td style = "border: 1px solid black; padding: 5px;">3.46</td>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">FreePhysicalMemory</td>
      <td style = "border: 1px solid black; padding: 5px;">30.12</td>
      <td style = "border: 1px solid black; padding: 5px;">31.65</td>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">TotalVisibleMemorySize</td>
      <td style = "border: 1px solid black; padding: 5px;">48.00</td>
      <td style = "border: 1px solid black; padding: 5px;">48.00</td>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">CPULoadPercentage</td>
      <td style = "border: 1px solid black; padding: 5px;">2</td>
      <td style = "border: 1px solid black; padding: 5px;">4</td>
    </tr>
  </table>
</body>

The PowerShell script should look like this:

$smtpServer = "[email protected]"
$smtpFrom = "[email protected]"
$smtpTo = "[email protected]"
$messageSubject = "Servers Memory"

$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true
$message.Body = Get-Content C:\Logs\output.txt

$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($message)

If you can't provide output.txt in HTML because it's generated automatically in plain text, then your script will need to convert it. If the format is consistently as shown in your example, that's not too complicated. Replace the $message.Body = line with this:

$body = Get-Content C:\Logs\output.txt | Out-String
$body = $body -replace '^(\S+)\s+(\S+)\s+(\S+)', '<tr><th style = "border: 1px solid black; background: #dddddd; padding: 5px;">$1</th><th style = "border: 1px solid black; background: #dddddd; padding: 5px;">$2</th><th style = "border: 1px solid black; background: #dddddd; padding: 5px;">$3</th></tr>'
$body = $body -replace '\n(\S+)\s+(\S+)\s+(\S+)', '<tr><td style = "border: 1px solid black; padding: 5px;">$1</td><td style = "border: 1px solid black; padding: 5px;">$2</td><td style = "border: 1px solid black; padding: 5px;">$3</td></tr>'
$body = '<body><table style = "border: 1px solid black; border-collapse: collapse;">' + $body + '</table></body>'
$message.Body = $body