htmlsqlpowershellviewhtml-email

Removing unwanted "system or script generated" Columns from Email Body


I've written a powershell code to generate a table in the body of an email for select users. The result of the execution for some reason includes "RowError", "RowState", "Table", "ItemArray", and "HasErrors" columns. I do not know if these are hidden columns coming from a SQL view that my code is reading or my own code generating them with each line it processes. I have tried to have PowerShell simply ignore the columns in the body of the HTML but am not seeing any change with each test email sent.

The Code

# Database connection parameters
$server = 'BIG-YELLOWSERVER'
$database = 'THECookies'

# SQL query
$query = "SELECT * FROM dbo.[All_My_Cookies] ORDER BY Chips, 'Dough'"

# Create a new SQL connection object using Windows Authentication
$connectionString = "Server=$server;Database=$database;Integrated Security=True;"
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection $connectionString

# Open SQL connection
$sqlConnection.Open()

# Execute the query and retrieve the data
$command = $sqlConnection.CreateCommand()
$command.CommandText = $query
$result = $command.ExecuteReader()

# Load data into a DataTable
$table = New-Object System.Data.DataTable
$table.Load($result)

# Remove unwanted columns
$columnsToRemove = @("RowError", "RowState", "Table", "ItemArray", "HasError")
foreach ($column in $columnsToRemove) {
    if ($table.Columns[$column]) {
        $table.Columns.Remove($column) | Out-Null
    }
}

# Close the SQL connection
$sqlConnection.Close()

# Lets attach the report for good measure
$csvFileName = "4KV Grid CVO Summary $(Get-Date -Format 'yyyy-MM-dd').csv"
$table | Export-Csv -Path $csvFileName -NoTypeInformation

# Define the CSS styles for the HTML tables
$style = @"
<style>
th {
    background-color: #b0c4de;
    color: black; 
    font-family: Arial, sans-serif; 
    font-size: 8pt;
}
td, th {
    border: 1px solid #ddd;
    padding: 1px;
    color: black; 
    font-family: Arial, sans-serif; 
    font-size: 8pt;
}
tr:nth-child(even) {
    background-color: #ffffff;
    color: black; 
    font-family: Arial, sans-serif; 
    font-size: 8pt; 
}
tr:nth-child(odd) {
    background-color: #e6e6e6;
    color: black; 
    font-family: Arial, sans-serif; 
    font-size: 8pt; 
}
tr:hover {
    background-color: #ddd;
}
</style>
"@

# Group the data by 'Region' and create HTML tables
$groupedTables = $table | Group-Object -Property Region | ForEach-Object {
    $region = $_.Name
    $regionHeader = "<h2>$region Region</h2>"
    $regionTable = $_.Group | ConvertTo-Html -Fragment
    $regionHeader + $regionTable
}

# Join all HTML strings into one and include the CSS styles
$htmlContent = $style + ($groupedTables -join "`n")

# Convert the data to HTML format and store in a variable
$htmlTable = $htmlContent

$emailBody = $introMessage + "The Ultimate Cookie report.`nPlease confirm receipt of this report. Thanks`n`n" + $htmlTable

# Email parameters
$smtpServer = "exchsmtp.cookiemonster.net"
$from = "luisohara@cookiemonster.com"

# Official Recipients

# $to = @("thecookiefiend@cookiemonster.com")
$subject = "The Ultimate Cookie Report"

# Send the email
Send-MailMessage -From $from -To $to -Subject $subject -Body $emailBody -BodyAsHtml -SmtpServer $smtpServer -Attachments $csvFileName

The Database View

SELECT TOP (1000) [Cookies]
      ,[Bigbird TVE]
      ,[Smurfberries in Effect]
      ,[White Chocolates]
      ,[VR1]
      ,[VR1%]
      ,[VR2]
      ,[VR2%]
      ,[VR3]
      ,[VR3%]
      ,[Previous Day Change]
      ,[Physical Pies]
      ,[TimeStamp]
      ,[reportDate]
  FROM [CookieReport].[dbo].[I_Like_Cookies]

Desired Results

enter image description here


Solution

  • Trying to remove RowError etc., from $table.Columns won't do you any good, because they aren't column values - they're properties attached to each instance of DataRow contained in the table.

    ConvertTo-Html doesn't know the difference between properties from the table and properties from row metadata, so we need to explicitly pass the column names to its -Property parameter - and those we can grab from $table.Columns:

    $columnNames = $table.Columns |ForEach-Object ColumnName
    
    # Group the data by 'Region' and create HTML tables
    $groupedTables = $table | Group-Object -Property Region | ForEach-Object {
        $region = $_.Name
        $regionHeader = "<h2>$region Region</h2>"
        $regionTable = $_.Group | ConvertTo-Html -Fragment -Property $columnNames
        $regionHeader + $regionTable
    }
    

    In case you need to pipe data rows to a command that doesn't allow you to pass property names via -Property, use Select-Object in between:

    $_.Group |Select-Object -Property $columnNames |ConvertTo-Html -Fragment