1

I am not good at html I am trying to create a table in outlook email like below (without colors)

enter image description here

I tried below code but not able to get this format

$HtmlTable = "<table border='1' align='Left' cellpadding='2' cellspacing='0' style='color:black;font-family:arial,helvetica,sans-serif;text-align:left;'>
<tr style ='font-size:12px;font-weight: normal;background: #FFFFFF'>
<th align=left><b>Customer Name*</b></th>
<th align=left><b>SERVER NAME</b></th>
<th align=left><b>IP Address</b></th>
<th align=left><b>Hostname without FQDN</b></th>
<th align=left><b>Server OS flavour (Drop Down)</b></th>
<th align=left><b>Datacenter</b></th>


</tr>"

    $HtmlTable += "<tr style='font-size:12px;background-color:#FFFFFF'>
    <td>" + "MYCOMPANY" + "</td>
    <td>" + "TESTSERVER" + "</td>
    <td>" + "10.10.10.10" + "</td>
    <td>" + "test" + "</td>
    <td>" + "test1" + "</td>
    <td>" + "test2" + "</td>
    </tr>"


$HtmlTable += "</table>"

Send-MailMessage -from $fromEmail -to $toEmail -Cc $toCCmail1 -SmtpServer $smtpServer -Body $HtmlTable  -Subject "  Report" -BodyAsHtml

Output in email

enter image description here

the data I have like below

$VM = get-vm | where {($_.Name -match $hostname)} | SELECT -Unique
$Summary = $VM | select  @{N="DNSName";E={$_.ExtensionData.Guest.Hostname}}, @{N="IPAddress";E={$_.Guest.IPAddress[0]}}, @{N=”Datacenter”;E={Get-Datacenter -VM $_}}
$DNS = $Summary.DNSName
$pos = $DNS.IndexOf(".")
$DNSName = $DNS.Substring(0, $pos)
$GuestOS = $VM.Guest.OSFullName
$IPAddress = $Summary.IPAddress
$dc = $Summary.Datacenter

Please need your help to get this html format

With respect to the solution provided by @Theo

enter image description here

email body

$body = @"

<html>

Hi Team, <br /><br />

Please raise a ticket CPU & memory situation from below servers. <br /><br />

<b>Unmapp (Remove) below Situations -</b><br />

MEMORY_USED_WARN<br />
MEMORY_USED_CRIT<br />
CPU_Warning<br />
    

<br /><br />

$htmlTemplate -replace '@@TABLES@@', ($tables -join '<br />')


Thank you <br /><br />

***This is an auto-generated email. Please do not respond***

</html>

"@
1
  • Without an example representation of how the PowerShell objects you want to export to HTML look like is hard to help as we would be guessing for a proper answer Commented Jan 19, 2022 at 18:36

2 Answers 2

1

As this question is all about HTML styling, I would use Here-String templates with placeholder strings to build the body:

# the first one is the template for the completed body:
$htmlTemplate = @"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
    <style>
        body {font-family: Calibri, Tahoma, Helvetica, sans-serif; color: black;}
        table {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;width: 100%;}
        td {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
    </style>
 </head>
 <body>
@@TABLES@@
 </body>
</html>
"@

# the second one is for each table you want to put in
$tableTemplate = @"
  <table>
  <tr>
    <td>Customer Name</td>
    <td colspan="2" style="text-align:center">@@CUSTOMER@@</td>
  </tr>
  <tr>
    <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
  </tr>
  <tr>
    <td rowspan="4" style="text-align:center">@@SERVER@@</td>
    <td>IP Address</td></td>
    <td style="text-align:center">@@IP@@</td>
  </tr>
  <tr>
    <td>Hostname without FQDN</td>
    <td style="text-align:center">@@HOSTNAME@@</td>
  </tr>
  <tr>
    <td>Server OS flavour (Drop Down)</td>
    <td style="text-align:center">@@OS@@</td>
  </tr>
  <tr>
    <td>Datacenter</td>
    <td style="text-align:center">@@DATACENTER@@</td>
  </tr>
  </table>
"@

Now you use your code to get the info for each VM and loop over that data.
For each of the VM's, you create a table using the $tableTemplate:

$tables = foreach ($machine in $VMs) {
    # here your code to gather the data

    # now replace the placeholders in the template with real data and output
    # a completed html table. These will be collected in variable $tables
    $tableTemplate -replace '@@CUSTOMER@@', "YourCustomerName" -replace
                            '@@SERVER@@', "YourServerName" -replace
                            '@@IP@@', $IPAddress -replace
                            '@@HOSTNAME@@', $DNSName -replace
                            '@@OS@@', $GuestOS -replace
                            '@@DATACENTER@@', $dc
}

After that, combine this into the completed body:

$body = $htmlTemplate -replace '@@TABLES@@', ($tables -join '<br />')

and use for the -Body parameter in the Send-MailMessage call

You should now have html looking like this:

enter image description here

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for this. it's great. Just one thing. when I am getting the output in email, above and below the table I am getting some texts. I have added the screenshot. can you please check.
@EmptyCoder You did put the line $body = $htmlTemplate -replace '@@TABLES@@', ,.. below the loop and just before the Send-MailMessage did you?
@EmptyCoder ..and the line $body = $htmlTemplate -replace ... is one line. It looks like you added a newline before -replace ??
I have other contents in email body. so I have placed the line inside the body. added the email body for your reference. and It will be for individual VM. so removed the loop also.
I just kept $htmlTemplate $tables in place of $htmlTemplate -replace '@@TABLES@@', ($tables -join '<br />') and it worked fine. thanks a ton.
|
0

There was the same question asked before, but I won't ask to archive it, 'cause your context of the text is different, so here we are.

I cannot help you right now, but I'll give you enough useful links you can use.

Here:

If that doesn't work, then try this: (NOTE: I USED THE SAME QUESTIONS' ANSWER AS REFERENCE)

FOR ONE TABLE

Get-Content "C:\Dv\Server_List.txt" -ErrorAction SilentlyContinue | ForEach-Object {
    Write-Host "Automatic Services Stopped :" $_ 
    Get-WmiObject Win32_Service -ComputerName $_ -Filter  "startmode = 'auto' AND state != 'running'"
} |
    Select-Object DisplayName, Name, State, StartMode |
    ConvertTo-Html |
    Out-File C:\Dv\Report.html

FOR MULTIPLE TABLES

# Generate the content which should be inserted as a set of HTML tables
$preContent = Get-Content "C:\Dv\Server_List.txt" -ErrorAction SilentlyContinue | ForEach-Object {
    $ComputerName = $_

    Write-Host "Automatic Services Stopped :" $ComputerName 

    # A table (and heading) will only be generated for $ComputerName if there are services matching the filter. 
    Get-WmiObject Win32_Service -ComputerName $ComputerName -Filter  "startmode = 'auto' AND state != 'running'" |
        Select-Object DisplayName, Name, State, StartMode |
        ConvertTo-Html -PreContent "<h2>$ComputerName</h2>" -Fragment
}

# Generate the document which holds all of the individual tables.
$htmlDocument = ConvertTo-Html -Head $htmlHead -PreContent $preContent | Out-String
# Because the document has no input object it will have an empty table (<table></table>), this should be removed.
$htmlDocument -replace '<table>\r?\n</table>' | Out-File C:\Dv\Report.html

Even the STYLING

$HtmlHead = '<style>
    body {
        background-color: white;
        font-family:      "Calibri";
    }

    table {
        border-width:     1px;
        border-style:     solid;
        border-color:     black;
        border-collapse:  collapse;
        width:            100%;
    }

    th {
        border-width:     1px;
        padding:          5px;
        border-style:     solid;
        border-color:     black;
        background-color: #98C6F3;
    }

    td {
        border-width:     1px;
        padding:          5px;
        border-style:     solid;
        border-color:     black;
        background-color: White;
    }

    tr {
        text-align:       left;
    }
</style>

# Use the Head parameter when calling ConvertTo-Html
| ConvertTo-Html -Head $HtmlHead |

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.