How to attach excel files in an email using powershell - powershell

I have the following select statement that extract data from a SQL Server database table:
$QUERY = "SELECT * FROM Table1"
$DataVariable = Invoke-Sqlcmd -ServerInstance "MyInstance" -Database "MyDB" -Query $QUERY
How can I attach the $DataVariable as an excel file in my email?
I am working on the code below:
$Date = get-date -format "dd-MMM-yyyy"
$Day = $Date.DayOfWeek
$DateTested = $Date
$filename = "MYReport_$(get-date -f yyyy-MM-dd).XLS"
$OutputFile = "\\server\c$\Output\$filename"
I don't seem to go anywhere with this. Can anyone assist please?
Thanks

Your code snippets don't seem to be related to one another
there is no attempt to mail anything
I suggest to save $Datavarable to csv (xlsx is also possible)
this raw example script uses gmail and splatting to fill the parameters
$QUERY = "SELECT * FROM Table1"
$DataVariable = Invoke-Sqlcmd -ServerInstance "MyInstance" -Database "MyDB" -Query $QUERY
$filename = "MYReport_$(get-date -f yyyy-MM-dd).csv"
$OutputFile = "\\server\c$\Output\$filename"
$DataVariable | Export-Csv $OutPutFile -NoTypeInformation
$emailAcc = "youraccount#gmail.com"
$Cred = Get-Credential -UserName $emailAcc -Message "Enter gmail password for $emailAcc"
$MsgParam = #{
From = $emailAcc
To = "recipient#domain.com"
Subject = $filename
Body = 'blah blah sending $filename'
Attachments = $OutPutFile
SmtpServer = "smtp.gmail.com"
}
Send-MailMessage #MsgParam -UseSSL -cred $Cred

I have managed to build the code below and it worked for me !!!!!!!!!!!!!!:
$DataVariable = Invoke-Sqlcmd -ServerInstance $ResultsInstance -Database $ResultsDatabase -Query $SQL
$Date = get-date -format "dd-MMM-yyyy"
$Day = $Date.DayOfWeek
$DateTested = $Date
$filename = "MyReport_$(get-date -f yyyy-MM-dd).csv"
$OutputFile = "\\serverName\c$\Output\$filename"
$DataVariable | Export-csv $OutPutFile -NoTypeInformation
$to = "Support"
$body = "Dear <b><font color=black>$to</b></font> <br>"
$body += "<p>Please find attached report.</p> <br>"
$body += "Kind Regards<br>"
$body += "Dev Team <br>"
$fromaddress = "xyz#xyz.com"
#$toaddress = "x#ytm.com"
$toaddress = "x#ytm.com"
$bccaddress = "x#ytm.com"
$CCaddress = "x#ytm.com"
$Subject = "My weekly report"
$attachment = $OutputFile
$smtpserver = "xyzmail"
####################################
$message = new-object System.Net.Mail.MailMessage
$message.From = $fromaddress
$message.To.Add($toaddress)
$message.CC.Add($CCaddress)
$message.Bcc.Add($bccaddress)
$message.IsBodyHtml = $True
$message.Subject = $Subject
$attach = new-object Net.Mail.Attachment($attachment)
$message.Attachments.Add($attach)
$message.body = $body
$message.Priority = [System.Net.Mail.MailPriority]::High
$smtp = new-object Net.Mail.SmtpClient($smtpserver)
if ($DataVariable) {
$smtp.Send($message)
Write-Host "The variable is not null" }

Related

Powershell to monitor a folder and send email when there are new files

I need some assistance on how to create a powershell to monitor a folder and subfolders and send an email every 15 minutes for example, with a list of files that added to this folder
I will set up a schedule task to run every 15 minutes
Email output will be something like:
File Name, Path
TEST.TXT uploaded to C:\ROOT\BUSINESS
test2.txt uploaded to C:\ROOT\BUSINESS\May2021
Here is what I have so far. Any help is appreciated.
SMTPServer = "EMAIL SERVER (ip)"
$SMTPPort = "111"
$Username = "SENDER#EMAIL.COM"
$path="C:\ROOT\BUSINESS\"
$to = "test1#gmail.com"
$cc = "test2#gmail.com"
$subject = " New File available "
$message = New-Object System.Net.Mail.MailMessage
$message.subject = $subject
$message.to.add($to)
$message.cc.add($cc)
$message.from = $username
$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
$smtp.EnableSSL = $true
#$smtp.Credentials = New-Object System.Net.NetworkCredential $Username;
If ($File = Get-ChildItem $Path | Where { $_.LastWriteTime -ge [datetime]::Now.AddMinutes(-15) }){
$smtp.send($message)}
write-host "Mail Sent"
Thanks
Try this condition:
if ((Get-ChildItem $Path | Where { $_.LastWriteTime -ge [datetime]::Now.AddMinutes(-15) }).Count -ge 1){ <# do something #> }

How can I embed HTML File in email body

How can I use powershell to embed an HTML file in email body? This is what I have so far:
##Connect to the data source using the connection details and T-SQL command we provided above, and open the connection
$connection = New-Object System.Data.OleDb.OleDbConnection $connectionDetails
$command = New-Object System.Data.OleDb.OleDbCommand $sqlCommand,$connection
$connection.Open()
##Get the results of our command into a DataSet object, and close the connection
$dataAdapter = New-Object System.Data.OleDb.OleDbDataAdapter $command
$dataSet = New-Object System.Data.DataSet
$dataAdapter.Fill($dataSet)
$connection.Close()
$body = $TableHeader
$dataSet.Tables | Select-Object -Expand Rows |
Select-Object * -ExcludeProperty Comment, RowError, RowState, Table, ItemArray, HasErrors |
ConvertTo-HTML -head $a –body $body |
Out-File $OutputFile
$ReportLink = "file://serverr/c$/Output/Report.Html"
Write-Output " Reporting"
$MailUsername = "you"
$MailPassword = "your pasword"
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList #($MailUsername,(ConvertTo-SecureString -String $MailPassword -AsPlainText -Force))
Send-MailMessage -To "abc#ymail.com" -From "xyz#ymail.com" -SmtpServer Ymail -Credential $cred -Subject " Report:" -Body $ReportLink -BodyAsHtml
I am still new to powershell. Thank you in advance
Assuming the data whichever you want to change to HTML format is in $Result Array
$EmailFrom = ""
$EmailTo = ""
$SMTPServer = ""
$EmailSubject =""
$Report = "<HTML><TITLE>Title</TITLE><BODY background-color:peachpuff><font color =""#99000"" face=""Microsoft Tai le""><H2> Heading </H2></font><Table border=1 cellpadding=0 cellspacing=0><TR bgcolor=gray align=center><TD><B>Row1</B></TD><TD><B>Row2</B></TD><TD><B>Row3</B></TD><TD><B>Row4</B></TD></TR>"
Foreach($Entry in $Result)
{
$Report += "<TR>"
$Report += "<TD>$($Entry.Value1)</TD><TD>$($Entry.Value2)</TD><TD>$($Entry.Value3)</TD><TD align=center>$($Entry.Value4)</TD></TR>"
}
$Report += "</Table></BODY></HTML>"
$mailmessage = New-Object system.net.mail.mailmessage
$mailmessage.from = ($EmailFrom)
$mailmessage.To.add($EmailTo)
$mailmessage.Subject = $EmailSubject
$mailmessage.Body = $Report
$mailmessage.IsBodyHTML = $true
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer)
$SMTPClient.Send($mailmessage)
I needed to add this script, it works like magic
$message = new-object System.Net.Mail.MailMessage
$message.From = $from
$message.To.Add($to)
$message.CC.Add($CC)
$Subject = " put subject here"
$message.IsBodyHtml = $True
$message.Subject = $Subject
$attach = new-object Net.Mail.Attachment($attachment)
$message.Attachments.Add($attach)
$message.body = $body
$smtp = new-object Net.Mail.SmtpClient($smtpserver)
$smtp.Send($message)

Search for a file that matches a keyword, then attach it to an email

I've written a PowerShell script that searches a folder for a file that matches a keyword eg Japan and then adds the file as an attachment to an email.
The email sends correctly, however the file isn't attached.
Add-PSSnapin Microsoft.Exchange.Management.Powershell.Admin -ErrorAction
SilentlyContinue
$dir = "C:\Users\user\Desktop"
$file = Get-ChildItem -Path $dir | -Filter "$keyword" -Recurse | Select-Object
$keyword = "Japan"
$mailboxdata = (Get-MailboxStatistics | select DisplayName,TotalItemSize,TotalDeletedItemSize, ItemCount, LastLoggedOnUserAccount, LastLogonTime)
$mailboxdata | Export-Csv "$file"
$smtpServer = "192.168.1.100"
$att = New-Object Net.Mail.Attachment($file)
$msg = New-Object Net.Mail.MailMessage
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$msg.From = "email#mail.com"
$msg.To.Add("email#othermail.com")
$msg.Subject = "Notification from email server"
$msg.Body = "Attached is the email server mailbox report for Japan"
$msg.Attachments.Add($att)
$smtp.Send($msg)
$att.Dispose()
You've modified a script from another source (that sends Mailbox Statistics from Microsoft Exchange) and you've left in parts of it that you do not need.
$dir = "C:\Users\user\Desktop"
$keyword = "Japan"
$smtpServer = "192.168.1.100"
$file = Get-ChildItem -Path $dir -Filter "*$keyword*" -Recurse
$att = New-Object Net.Mail.Attachment($file)
$msg = New-Object Net.Mail.MailMessage
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$msg.From = "email#mail.com"
$msg.To.Add("email#othermail.com")
$msg.Subject = "Notification from email server"
$msg.Body = "Attached is the email server mailbox report for Japan"
$msg.Attachments.Add($att)
$smtp.Send($msg)
$att.Dispose()
I would use Send-MailMessage instead as it's syntax is much easier to use:
$dir = "C:\Users\user\Desktop"
$keyword = "Japan"
$Attachment = Get-ChildItem -Path $dir -Filter "*$keyword*" -Recurse
$From = "email#mail.com"
$To = "email#othermail.com"
$Subject = "Files matching: $keyword"
$Body = "Attached is the file for: $keyword"
$SMTPServer = "192.168.1.100"
Send-MailMessage -From $From -To $To -Subject $Subject -Body $Body -SmtpServer $SMTPServer -Attachments $Attachment.FullName

PowerShell multiple email recipients (attachment) from csv / empty cell issue

I recently started to work on PS script for email automation.
Manage to put something together where I have CSV file from where PowerShell is extracting data (multiple recipients, attachment, etc).
The problem is, when some of the cells are empty, script won`t work.
There is one similar question, but I am just not sure how to implement solution on my case:
$importFile = "Users.csv"
$users = import-csv $importFile | select *
foreach($user in $users)
{
$Name = $user.'Name'
$to = $user.'To'
$to2 = $user.'To2'
$Attachment = $user.'Attachment'
$Attachment2 = $user.'Attachment2'
$write = "Emailing account " + $to + " ..."
Write-Host $write
$body = [string]::join([environment]::newline, (Get-Content -path $emailFile))
$body = $body.Replace('[Name]', $Name)
$mail = New-Object System.Net.Mail.MailMessage
$mail.From = $emailFrom
$mail.To.Add($to)
$mail.To.Add($to2)
$mail.Subject = $emailSubject
$mail.IsBodyHtml = $true
$mail.Body = $body
$mail.Attachments.Add($Attachment)
$mail.Attachments.Add($Attachment2)
$smtp = New-Object System.Net.Mail.SmtpClient
$smtp.Host = $smtpServerHost
$smtp.Port = $smtpServerPort
$smtp.EnableSsl = $smtpServerSsl
$smtp.UseDefaultCredentials = $false
$smtp.Credentials = $credentials
$smtp.Send($mail)
This is how looks CSV file
Any suggestion is more than welcome :)
Try Where-Object to filter out rows.
$users = Import-Csv $importFile |
Where-Object {$_.Name -ne ""} |
Select-Object *
For what it is worth: if the whole "row" is blank you can shortcut this to simply be
...
Where-Object {$_} |
...
Implementing IF function resolved the case. For example if ($to2 -ne '') is checking if $to2 cell is empty. If no, then $mail.To.Add($to2). The same situation for $Attachment. Here is the code:
$mail = New-Object System.Net.Mail.MailMessage
$mail.From = $emailFrom
$mail.To.Add($to)
if ($to2 -ne '') {
$mail.To.Add($to2)
}
$mail.Subject = $emailSubject
$mail.IsBodyHtml = $true
$mail.Body = $body
$mail.Attachments.Add($Attachment)
if ($Attachment2 -ne '') {
$mail.Attachments.Add($Attachment2)
}

Powershell HTML email formatting

The below script puts database backup details into a nicely formatted table with borders and saves as a .htm. It then emails the report, but when the report is emailed the 'table' has no borders and no gap between the 'LastBackupDate' column and the 'LastLogBackupDate' column - it basically looks the same as the results would on the powershell console. Can anyone tell me how to format the email so all the html is used from the file? P.s. I can't use send-mailmessage due to issues with gmail ssl. Thanks.
#HTML
$a = "<style>"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 1px;padding: 10px;border-style: solid;border-color: black;}"
$a = $a + "TD{border-width: 1px;padding: 10px;border-style: solid;border-color: black;}"
$a = $a + "</style>"
#Set Date
$date = ( get-date ).ToString('yyyyMMdd')
#Locate DB
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
$s = New-Object ('Microsoft.SqlServer.Management.Smo.Server') "LOCALHOST\SQLX64"
#Retrieves the last backup dates - for full and log backups
$dbs=$s.Databases
$backups = $dbs | SELECT Name,LastBackupDate, LastLogBackupDate | Sort-Object LastBackupDate | ConvertTo-HTML -head $a -body "<H2>DB01 Database Backup Details $date </H2>" | Out-File $("D:\SQL_Backup_Log_Script\Logs\Backup_Log_Temp.htm")
#Email Report
$EmailFrom = "someone#domain.com"
$emailto = "me#gmail.com"
$Subject = "Database Backup Log $date"
$Body = Get-Content D:\SQL_Backup_Log_Script\Logs\Backup_Log_Temp.htm
$SMTPServer = "smtp.gmail.com"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("someone#domain.com", "password here");
$message = New-Object Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $Body)
$message.IsBodyHtml = $true;
$SMTPClient.Send($message)
#Rename file to include today's date
Rename-Item -path D:\SQL_Backup_Log_Script\Logs\Backup_Log_Temp.htm -newname ($date +"_DB01_Backup_Log.htm")
Try change this line (can't test if is this the problem):
$Body = [System.IO.File]::ReadAllText("D:\SQL_Backup_Log_Script\Logs\Backup_Log_Temp.htm")
the body property in Net.Mail.MailMessage accept [string], get-content return [string[]].