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
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