Add the output of an SQL query to an HTML table using Powershell

I have multiple databases from various SQL Servers.

I am attempting to output SQL data to an HTML table using Powershell from these different databases/SQL Servers, and then send it via email. Although my current script is functioning, it generates multiple tables for each result in the html report. What I need is to concatenate the data into a single table (with all the data combined). I'm having some difficulty figuring out how to merge the information into just one table.



#Set flag to 0 for email notification (if any)
$alert = 0

$List = Get-Content -Path "C:\Users\testadmin\Documents\Log\serverlist.txt";

Foreach ($Server in $ServerList){

    $SQL = ($Server -split '=')[0];
    $DB = ($Server -split '=')[1];

    $Query = "select host, Service, Status from Table with(nolock)";

    $Value = Invoke-Sqlcmd -ServerInstance $SQL -Database $DB -Query $Query;

    foreach ($mylocal in $Value) {

        $hostname = $mylocal.host;
        $Service = $mylocal.Service;
        $Status = $mylocal.Status; 

         if ($Status -ne 'Running') {
         
             $alert = 1;

             $Body += "<head> 
                       <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>

                      <style>
                        TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
                        TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED;}
                        TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}

                          table.center {
                            margin-left: auto; 
                            margin-right: auto;
                          }
                      </style>

                      <title>Warning</title>
                      </head> 
                    <body> 

                      <h3>Apps are Stopped!</h3>

                      <h4>Timestamp: $(Get-Date)</h4>

                    <table>

                      <tr>
                        <th>SQL</th>
                        <th>DB</th>
                        <th>Service Status</th>
                      </tr>

                      <tr>
                        <td>$SQL</td>
                        <td>$DB</td>
                        <td>$Status</td>
                      </tr>

                     </table>
                   </body>";
            } else {
                Write-Host ("no alert");
            }
      }  
}

if ($alert -eq '1'){

    $Mail = @{
        From = '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="572332242336333a3e39173b3834363b7934383a">[email protected]</a>'; 
        To = '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="701c1f13111c11141d191e301c1f13111c5e131f1d">[email protected]</a>';
        Subject = 'Warning!!';
        smtpserver = 'myrelay.test.com';
        Body = $Body;
        BodyAsHtml = $true;
    };

    Send-MailMessage @Mail;
} 

Answer №1

To effectively create your HTML structure, it is important to separate the base html (which includes head, body, table title, and table headers) from the loop where you generate only the table cells.

The next step involves assembling all the pieces to form a complete HTML document.

Here's an example:


# Sample data with calculated fields
$Value = Get-Service | Select @{ 'Name' = 'host'; 'Expression' = { "localhost" } },
@{ 'Name' = 'Service'; 'Expression' = { $_.ServiceName } }, Status

$HtmlTemplate = @{
    Base_Date_TableLoop          = @'
  <!-- Base Date Table Loop -->
'@
    TableLoop_SQL_DB_Status = @'
        <tr>
            <td>{0}</td>
            <td>{1}</td>
            <td>{2}</td>
        </tr>
'@
}

$Date = Get-Date
$Table = [System.Text.StringBuilder]::new()

foreach ($mylocal in $Value ) {
    $hostname = $mylocal.host
    $Service = $mylocal.Service
    $Status = $mylocal.Status

    $Table.AppendLine(($HtmlTemplate.TableLoop_SQL_DB_Status -f $hostname,$Service,$Status)) | Out-Null
}

$HtmlBody = $HtmlTemplate.Base_Date_TableLoop.Replace('{0:Date}',$Date).Replace('{0:TableLoop}',$Table.ToString())

$HtmlBody | Out-File 'SomeReport.html' 

Considerations:

I prefer storing all elements of the HTML in a single variable like `HtmlTemplate`. Each piece serves as a building block for the final HTML. I use naming conventions like `Base_Date_TableLoop` to allow for easy replacements later without confusion.

Addtional Information:

In this script, I've used a combination of placeholders and `-f` operator for the loop part and `.replace` method for the base html section. This approach helps avoid altering the original HTML unnecessarily. For replacing specific parts, I chose `.replace` over `-Replace` to prevent regex operations.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I noticed an excess of white space on the right side of my Angular website

Check out my website here. Everything seems to be functioning correctly, however, there is an issue with scrolling on mobile. It should only scroll up and down, not left and right! I have noticed a strange white space on the right side of my site when view ...

Is there a method in AngularJS to submit form data when the input fields are pre-populated using a GET request?

How do I submit form data in AngularJS? I have a div that populates the input field from a GET request. Now, I want to send this data using a POST method. How can I achieve this? Below is the form div: <div class="row" ng-app="myApp" ng-controller="myC ...

Developing interactive filter buttons with unique identifiers to sort and display elements that share the same identifier

My website has filtering buttons labeled "UI, DEVELOPMENT, DATABASE, etc." <ul class="tags_list"> <li><a href="#" id="tag_ui">Ui</a></li> <li><a href="#" id="tag_database">Database</a></li> ...

Issue with Favicon display in all versions of Internet Explorer

Visit my website. I have attempted multiple solutions found on Stack Overflow and different forums, yet I am unable to make it work. The code runs perfectly in all browsers except for Internet Explorer (regardless of the version) :( Can anyone provide ass ...

Leverage AJAX variables directly within the HTML page

In my application, I have incorporated an Input type="date" field to capture date values from users. However, I need to send the value of the date as "sdate" in the URL used in the action method, as illustrated below. My goal is to post the value of the In ...

What causes the html5 <audio> tag to appear differently on Chrome versus IE browsers?

When viewed in Chrome, the design appears clean and compact, but when seen in Internet Explorer, it looks large and overwhelming. Check out the screenshots below.. Do you have any suggestions to fix this issue? Know of any mp3 hosting platforms with an emb ...

Tips for including HTML tags in strings without causing issues with nested tags

I am struggling with a string that contains both text and HTML tags, specifically <a href=""></a> tags. My goal is to apply the "i" tag around the text outside of the "a" tags without creating nested tags like: <i><a href=""></a ...

Initiate an animation upon reaching a designated element using Jquery scroll event

Hey there! I've been trying to create an animation without using any plugins, but unfortunately, I haven't had much luck so far. Here's the code I've been working on. If anyone can help me figure this out, I'd really appreciate it ...

Despite utilizing the .img-fluid class, the image remains incompatible with the parent div and does not fit properly

So, I'm currently working on a test code where my aim is to fit an image into the parent div using Bootstrap 5. However, I'm facing a challenge where the image leaves a noticeable gap width-wise, despite using the .img-fluid class. You can see th ...

What is the best way to incorporate a dropdown menu into existing code without causing any disruption?

I've come across this question multiple times before, but I still haven't found a suitable answer or solution that matches my specific situation. (If you know of one, please share the link with me!) My goal is to create a basic dropdown menu wit ...

Concealing divisions on a website with CSS styling

In my div, I have some text that I want to hide. <div style='visibility:hidden;' id='emailid'>$email</div> Although the visibility attribute successfully hides the text, it leaves behind empty space on the webpage where th ...

Transferring data from JavaScript to PHP for geolocation feature

Hello everyone, I'm looking to extract the longitude and latitude values from my JavaScript code and assign them to PHP variables $lat and $lng. This way, I can retrieve the city name and use it in my SQL query (query not provided). Below is the scrip ...

Allow the content to be scrolled

When it comes to my CSS script, I encounter no issues on larger computer screens. However, users with smaller resolutions like 1024 x 768 are experiencing problems viewing the entire HTML page. Only half of the page is displayed, making it impossible for t ...

Circular gradient backdrop

Looking to create a sleek and professional body background for my website that is as attractive as Twitter's. Can you help me achieve the same blue shaded background effect? I'm new to web development and would appreciate any guidance on how to m ...

Error in line 36: firebase.auth function is undefined

Snippet of index.html code <html> <head> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" ...

Having trouble implementing table row selection with semantic-ui table

I am currently in the process of adopting Semantic-UI, but I am encountering some issues. Specifically, I am struggling to make row selection work in a table. Below is the sample HTML I am using from Semantic-UI: <table class="ui selectable celled tab ...

Disable browser suggestions in Material UI's Autocomplete component

Encountering an issue with Material-ui Autocomplete: import Autocomplete from "@material-ui/lab/Autocomplete"; Currently using it in: <Autocomplete id="checkboxes-tags-demo" autoComplete={false} options={sta ...

Guide to verifying a value within a JSON object in Ionic 2

Is there a way to check the value of "no_cover" in thumbnail[0] and replace it with asset/sss.jpg in order to display on the listpage? I have attempted to include <img src="{{item.LINKS.thumbnail[0]}}"> in Listpage.html, but it only shows the thumbna ...

Change the position of a Div by clicking on a different Div using JQuery for custom movements

I have successfully managed to slide the div left/right based on the answers below, but I am encountering some issues with the top div. Here are the specific changes I am looking to make: 1. Make both brown lines thinner without affecting the animations. ...

Zurb Foundation gem causing navigation errors

Typically, I rely on the Twitter Bootstrap Rails gem for my projects, but this time I decided to try out the Zurb Foundation gem. Following the installation instructions meticulously, I added the navigation code: <div class="row"> <div class="th ...