David Megnin
asked on
Simple example of sending SQL query result as HTML formatted table in an email using Powershell
I tried piecing together a couple scripts, one that send a single value to an email address and another that writes a query result to a text file, but I don't know Powershell well enough to get it to work.
I want to send the result of an SQL query of just a few columns as an HTML formatted table in an email message using Send-MailMessage.
Here is what I've got. It prints the table to the console and the output file, but the email fails with an error.
If there's a cleaner or better with to do this, I'd like to learn it. Thank you!
I want to send the result of an SQL query of just a few columns as an HTML formatted table in an email message using Send-MailMessage.
Here is what I've got. It prints the table to the console and the output file, but the email fails with an error.
<# connection string and SQL command to execute #>
[String] $now = Get-Date
[String] $to = 'dmegnin@careersourcebroward.com'
[String] $connectionString = 'Server=MSQLServ; Database=ITASync; Integrated Security=SSPI;'
[String] $query = @'
SELECT Provider, LoginDate, DATEDIFF(day, LoginDate, GetDate()) as Diff
FROM Logins
WHERE DATEDIFF(day,LoginDate, GetDate()) IN (37)
'@
$connection = New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = $connectionString
$connection.Open()
$command = $connection.CreateCommand()
$command.CommandText = $query
$result = $command.ExecuteReader()
$table = new-object “System.Data.DataTable”
$table.Load($result)
$format = @{Expression={$_.Provider};Label="Provider Name";width=30},@{Expression={$_.LoginDate};Label="Login Date"; width=25},@{Expression={$_.Diff};Label="Days"; width=8}
$table | Where-Object {$_.Provider -like "*PROFESSOR" -and $_.Diff -lt 100} | format-table $format
$table | Where-Object {$_.Provider -like "*PROFESSOR" -and $_.Diff -lt 100} | format-table $format | Out-File C:\Temp\ee\Providers.txt
Send-MailMessage -BodyAsHtml -Body "$table | Where-Object {$_.Provider -like "*PROFESSOR" -and $_.Diff -lt 100} | format-table $format" -SmtpServer mail.careersourcebroward.com -From "Contract Expiration Database <csbd@careersourcebroward.com>" -To $to -Subject "Provider: $($_.Provider) logged in $($_.Diff) days ago."
$connection.Close()
If there's a cleaner or better with to do this, I'd like to learn it. Thank you!
SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
ASKER
Hi footech,
Unfortunately, I'm not on my way to working anything out. ;-) I found both of those examples and they just look like they are either close to what I'm looking for or at least contain part of what I need. I only started trying to learn Powershell last week when I was asked to find a way to send email alerts when our companies contracts were nearing their expiration dates.
Anyway, I didn't know a "-Fragment" parameter existed. It makes sense to me though.
David, I don't understand your sentence fragment "two entirely different questions." I'm asking for a simple example of a Powershell script to send the result of a query in an email and I provide what I have so far but that doesn't work.
Then I provide an example that I found, while googling around, that looks like it contains mostly what I want, but also has a bunch of stuff that I don't need, but don't know Powershell well enough (at all, really) to remove what doesn't fit with with I need. Thanks for understanding.
Unfortunately, I'm not on my way to working anything out. ;-) I found both of those examples and they just look like they are either close to what I'm looking for or at least contain part of what I need. I only started trying to learn Powershell last week when I was asked to find a way to send email alerts when our companies contracts were nearing their expiration dates.
Anyway, I didn't know a "-Fragment" parameter existed. It makes sense to me though.
David, I don't understand your sentence fragment "two entirely different questions." I'm asking for a simple example of a Powershell script to send the result of a query in an email and I provide what I have so far but that doesn't work.
Then I provide an example that I found, while googling around, that looks like it contains mostly what I want, but also has a bunch of stuff that I don't need, but don't know Powershell well enough (at all, really) to remove what doesn't fit with with I need. Thanks for understanding.
If your first does everything you want and you're just concerned about the error you get when you try to send an email, then you should post the error. But just looking at it I would say the below would work. And if so, then other changes as shown previously are just formatting choices.
Send-MailMessage -BodyAsHtml -Body ($table | Where-Object {$_.Provider -like "*PROFESSOR" -and $_.Diff -lt 100} | ConvertTo-HTML | Out-String) -SmtpServer mail.careersourcebroward.com -From "Contract Expiration Database <csbd@careersourcebroward.com>" -To $to -Subject "Provider: $($_.Provider) logged in $($_.Diff) days ago."
ASKER
footech, that worked. It displays the three column table in the console window and also sends me an email with a similar table, with the correct three columns... plus columns for; "RowError", "RowState", "Table", "ItemArray", and "HasErrors."
I don't really need those extra columns, and I don't know how to suppress them.
It's not a huge thing if the extra columns can't be suppressed, but it would be nice if the email was formatted just like the console output.
Thanks.
I don't really need those extra columns, and I don't know how to suppress them.
It's not a huge thing if the extra columns can't be suppressed, but it would be nice if the email was formatted just like the console output.
Thanks.
ASKER
David, thank you for taking the time to strip out the unnecessary bits from that example. I think I like the way the HTML seems to be formatted in that example so I'll have to add in the information for my database, etc. to see what it actually looks like. That was an unedited example I found in another forum, so it's not in a "testable" state, yet.
ASKER
footech, I found this while Googling for how to suppress those extra columns:
But, I'm not using that particular method of creating the table, so I'm not sure how to incorporate that into the script you are helping me with. The table you created looks beautiful. I just would like to exclude those exact columns shown in the example above. Thanks again.
You should be able to simply select the data from your table that you do want when defining $body.
$body = $DataSet.Tables[0] | Select bug_id,Status,Resolution,Summary,Dea dline | convertto-html | out-string
Or, you can select everything, and then specify what you want to exclude:
$body = $DataSet.Tables[0] | Select * -ExcludeProperty RowError, RowState, Table, ItemArray, HasErrors | convertto-html | out-string
But, I'm not using that particular method of creating the table, so I'm not sure how to incorporate that into the script you are helping me with. The table you created looks beautiful. I just would like to exclude those exact columns shown in the example above. Thanks again.
ASKER
Got it! I added "| Select -property" and the column names I want to keep into the <body> and it's perfect.
Here is the whole working script. Thank you so much for your help. David, thanks for your input as well!
Here is the whole working script. Thank you so much for your help. David, thanks for your input as well!
<# connection string and SQL command to execute #>
[String] $now = Get-Date
[String] $to = 'david@domain.com'
[String] $connectionString = 'Server=SQLServer; Database=OurDatabase; Integrated Security=SSPI;'
[String] $query = @'
SELECT Provider, LoginDate, DATEDIFF(day, LoginDate, GetDate()) as Diff
FROM Logins
WHERE DATEDIFF(day,LoginDate, GetDate()) < (37)
'@
$connection = New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = $connectionString
$connection.Open()
$command = $connection.CreateCommand()
$command.CommandText = $query
$result = $command.ExecuteReader()
$table = new-object “System.Data.DataTable”
$table.Load($result)
$head = @"
<style>
TABLE{border-width: 2px;border-style: solid;border-color: black;border-collapse: collapse;}
TH{border-width: 2px;padding: 4px;border-style: solid;border-color: black;background-color:lightblue;text-align:left;font-size:14px}
TD{border-width: 1px;padding: 4px;border-style: solid;border-color: black;font-size:12px}
</style>
"@
$prebody = @"
<H4>SQL query results</H4>
"@
$message = @"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
$head
</head>
<body>
$($table | Select -property Provider, LoginDate, Diff | Where-Object {$_.Provider -like "*PROFESSOR" -and $_.Diff -lt 100} | ConvertTo-Html -Fragment -PreContent $prebody -PostContent "<p>footer</p>" | Out-String)
<hr>
<p></p>
<p>Thank You,</p>
<p>Signature Block</p>
</body>
</html>
"@
Send-MailMessage -BodyAsHtml -Body $message -SmtpServer mail.domain.com -From "Contract Expiration Database <csbd@domain.com>" -To "david@domain.com" -Subject "neat stuff"
$connection.Close()
ASKER
Thank you, both, for your help!
ASKER
Open in new window