How do I send an email containing a binary file using powershell script? Below is my failing best attempt
$to = 'andy.boo#boo.com'
$subject = 'boo'
$file = 'inf.doc'
$from = $to
$filenameAndPath = (Resolve-Path .\$file).ToString()
[void][Reflection.Assembly]::LoadWithPartialName('System.Net') | out-null
$message = New-Object System.Net.Mail.MailMessage($from, $to, $subject, $subject)
$attachment = New-Object System.Net.Mail.Attachment($filenameAndPath, 'text/plain')
$message.Attachments.Add($attachment)
$smtpClient = New-Object System.Net.Mail.SmtpClient
$smtpClient.host = 'smtp.boo.com'
$smtpClient.Send($message)
Exception calling "Send" with "1" argument(s): "Failure sending mail."
At C:\email.ps1:15 char:17
+ $smtpClient.Send <<<< ($message)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
What version of PowerShell? If you're using version 2.0 save yourself the trouble and just use the Send-MailMessage cmdlet.
If version 1.0:
$msg = new-object system.net.mail.MailMessage
$SMTPClient = new-object system.net.mail.smtpClient
$SMTPClient.host = "smtp server"
$msg.From = "Sender"
$msg.To.Add("Recipient")
$msg.Attachments.Add('<fullPathToFile')
$msg.Subject = "subject"
$msg.Body = "MessageBody"
$SMTPClient.Send($Msg)
Found this.. which is a lot better
Send-MailMessage -smtpServer smtp.doe.com -from 'joe#doe.com' -to 'jane#doe.com' -subject 'Testing' -attachment foo.txt
Related
This PowerShell script runs a SQL query and populates an Excel spreadsheet, then emails that spreadsheet:
$FileName = "C:\Users\user\Documents\Report.xlsx";
$ConnectionString = "OurConnectionString"
$secpasswd = "emailpassword"
$cred = New-Object System.Management.Automation.PSCredential ("emailaddress", $secpasswd)
$SmtpCred = $cred
$ToAddress = 'to#contoso.com'
$FromAddress = 'from#contoso.com'
$SmtpServer = 'smtp.server.com'
$SmtpPort = '587'
$Subject = 'Report'
$Body = "Here is your report"
$SqlQuery = #"
SELECT TOP 10 * FROM dbo.table
"#;
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection;
$SqlConnection.ConnectionString = $ConnectionString;
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand;
$SqlCmd.CommandText = $SqlQuery;
$SqlCmd.Connection = $SqlConnection;
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter;
$SqlAdapter.SelectCommand = $SqlCmd;
$DataSet = New-Object System.Data.DataSet;
$SqlAdapter.Fill($DataSet);
$DataSetTable = $DataSet.Tables["Table"];
$xlsFile = #($DataSetTable | Export-Excel $FileName -AutoSize)
$SqlConnection.Close()
$Attachment = $xlsFile
$mailparam = #{
To = $ToAddress
From = $FromAddress
Subject = $Subject
Body = $Body
Attachments = $Attachment
SmtpServer = $SmtpServer
Port = $SmtpPort
Credential = $SmtpCred
}
Send-MailMessage #mailparam -UseSsl
The error I get when I run this is:
Send-MailMessage : Cannot validate argument on parameter 'Attachments'. The
argument is null, empty, or an element of the argument collection contains a
null value. Supply a collection that does not contain any null values and then
try the command again.
At C:\Users\Desktop\Untitled1.ps1:58 char:18
+ Send-MailMessage #mailparam -UseSsl
+ ~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Send-MailMessage], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage
I can't figure out how $Attachment is ending up as null or empty? I know I've written scripts similar to this in the past and they worked fine. Am I missing something in my script that someone else can see? Further, I don't technically need to save the Excel file to the file system first, I just need to email it as an attachment. So it's ok if the answer eliminates the saving to the file system part, if that's even do-able.
The -Attachments parameter expects a string or list of strings.
see Send-MailMessage
This should be the full path(s) to the file(s) you need to attach, thus requires you to store them first. Generally, if I don't need the files afterwards you can just delete them. Also note that it is required you pass the FullName.
As I cannot see the Output of the Export-Excel function I will assume it returns a File Object then this should work
$mailparam = #{
To = $ToAddress
From = $FromAddress
Subject = $Subject
Body = $Body
Attachments = $xlsFile.FullName
SmtpServer = $SmtpServer
Port = $SmtpPort
Credential = $SmtpCred
}
If you are not returned a File object you will need to get the item first and pass the `FullName'
$MyExcelFile = Get-Item -Path 'C:\MyExcelFile.xlsx'
$mailparam = #{
To = $ToAddress
From = $FromAddress
Subject = $Subject
Body = $Body
Attachments = $MyExcelFile.FullName
SmtpServer = $SmtpServer
Port = $SmtpPort
Credential = $SmtpCred
}
Below is the code snippet used to send mail. which worked until recently and is giving “Failure sending mail." Error. (Version: 5.1.16299.98)
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
$Username = " "
$Password = " "
$to = " "
$cc = " "
$subject = "AUTOMATED "
$message = New-Object System.Net.Mail.MailMessage
$message.Subject = $subject
$message.To.Add($to)
$message.Cc.Add($cc)
$message.From = $username
$message.IsBodyHtml = $true
$message.Body =
$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
$smtp.EnableSSL = $true
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username,$Password);
$smtp.Send($message)
Write-Host "Mail Sent"
The error is:
Exception calling "Send" with "1" argument(s): "Failure sending mail."
At F:\powershell_scripts\xxx.ps1 :88 char:1
+ $smtp.Send($message)
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SmtpException
I can't tell you what the problem is, but I can help you to find out more information about your error!
try {
<your code>
}
catch {
Write-Warning $Error[0].Exception.StackTrace
throw
}
$Error is a special variable in PowerShell that contains a list of the errors that have occurred. Check the documentation for more [/proper] explanation.
$Error[0] is the "most recent" error in the stack.
There are plenty of other properties of the $Error object that you may wish to interrogate for more verbose information... start with
$Error | Get-Member
and go from there.
Hope this helps you get to the bottom of this [and future] issue[s]!
I can create an email and display it with my script, but for some reason it doesn't send and I receive the following error. Am I missing something, maybe there's a permissions issue?
Exception calling "Send" with "0" argument(s): "Operation aborted (Exception from HRESULT: 0x80004004 (E_ABORT))"At C:\TEMP\Scripts\PowerShell\Outlook EMail Creation\TestEMailSend.ps1:27 char:5
+ $mail.Send()
+ ~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
My code:
$global:UserReportsToEmail = "my.email#domain.com"
$ol = New-Object -comObject Outlook.Application
$mail = $ol.CreateItem(0)
$mail.To = "$global:UserReportsToEmail"
$mail.cc = "EMAIL#domain.com"
$mail.Subject = "mySubject"
$mail.HTMLBody =
"<font color ='blue'><b>TESTING STUFFFF!</b></font><br>
Text on a new line $UserID"
$mail.Send()
$inspector = $mail.GetInspector
$inspector.Display()
According to a few of the Microsoft sites (e.g. https://social.msdn.microsoft.com/Forums/en-US/80c66a08-66ee-4ab6-b629-6b1e70143eb0/operation-aborted-exception-from-hresult-0x80004004-eabort-outlook-appointment?forum=outlookdev ) this is due to 'object model guard'. A security feature to prevent automated programs from doing stuff like auto-emailing out viruses and stuff from the background.
You probably already worked this out. Posting this here so that others like myself can more quickly and easily understand why its not working.
you can use the Send-MailMessage CmdLets : https://technet.microsoft.com/en-us/library/hh849925.aspx
then when i need more controls and dispose functionnality i use System.Net.Mail.SmtpClient
try
{
$emailCredentials = Import-Clixml "C:\testMail\credentials.clixml"
$recipients = #("user#mail.com", "user2#mail.com", "user3#mail.com")
$attachments = #("C:\testMail\file.txt", ""C:\testMail\file2.txt", "C:\testMail\file3.txt")
# create mail and server objects
$message = New-Object -TypeName System.Net.Mail.MailMessage
$smtp = New-Object -TypeName System.Net.Mail.SmtpClient($buildInfoData.BuildReports.Mail.Server)
# build message
$recipients | % { $message.To.Add($_) }
$message.Subject = $subject
$message.From = New-Object System.Net.Mail.MailAddress($emailCredentials.UserName)
$message.Body = $mailHtml
$message.IsBodyHtml = $true
$attachments | % { $message.Attachments.Add($(New-Object System.Net.Mail.Attachment $_)) }
# build SMTP server
$smtp = New-Object -TypeName System.Net.Mail.SmtpClient(smtp.googlemail.com)
$smtp.Port = 572
$smtp.Credentials = [System.Net.ICredentialsByHost]$emailCredentials
$smtp.EnableSsl = $true
# send message
$smtp.Send($message)
Write-Host "Email message sent"
}
catch
{
Write-Warning "$($_.Exception | Select Message, Source, ErrorCode, InnerException, StackTrace | Format-List | Out-String)"
}
finally
{
Write-Verbose "Disposing Smtp Object"
$message.Dispose()
$smtp.Dispose()
}
I have the following Powershell script that I would use to send an e-mail:
$smtpServer = "smtp.live.com"
$smtpPort = "465"
$credential = [Net.NetworkCredential](Get-Credential)
$smtpClient = New-Object System.Net.Mail.SmtpClient $smtpServer, $smtpPort
$smtpClient.EnableSsl=$true
$smtpClient.UseDefaultCredentials=$false
$smtpClient.Credentials= $credential
$smtpTo = "existing_email#hotmail.com"
$smtpFrom = "email#hotmail.com"
$messageSubject = "Testing Mail"
$messageBody = "Hi, This is a Test"
$message = New-Object System.Net.Mail.MailMessage $smtpFrom, $smtpTo, $messageSubject, $messageBody
try
{
$smtpClient.Send($message)
Write-Output "Message sent."
}
catch
{
$_.Exception.Message
Write-Output "Message send failed."
}
But I receive this error:
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,mail.ps1
Exception calling "Send with "1" arguments" Failure Sending mail
What is wrong whit this code?
You haven't defined $smtpFrom (address from which the e-mail is sent). Also, just a suggestion, why don't you use Send-MailMessage cmdlet, it's available from PowerShell 2.0
This code works for me without any issues with smtp.live.com and port 587 with SSL
$SmtpServer = 'smtp.live.com'
$SmtpUser = 'your_username#outlook.com'
$smtpPassword = 'your_password'
$MailTo = 'your_to_mail#example.com'
$MailFrom = 'your_username#outlook.com'
$MailSubject = "Test using $SmtpServer"
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SmtpUser, $($smtpPassword | ConvertTo-SecureString -AsPlainText -Force)
Send-MailMessage -To "$MailTo" -from "$MailFrom" -Subject $MailSubject -SmtpServer $SmtpServer -Credential $Credentials -UseSsl -Port 587
I solved changing port to 25. But why I can't use IMAP ?
I have this working on my local machine, but when I try it on another machine, that has the same files in the same place etc, it fails with this error.
function email
{
$emailSmtpServer = "smtp-mail.outlook.com"
$emailSmtpServerPort = "587"
$emailSmtpUser = "USERNAME"
$emailSmtpPass = "PASSWORD"
$attachment = "C:\BackupLog.log"
$emailMessage.Attachments.Add($attachment)
$emailMessage = New-Object System.Net.Mail.MailMessage
$emailMessage.From = "myemail#hotmail.co.uk"
$emailMessage.To.Add( "myemail#civil.lmco.com" )
$emailMessage.Subject = "Database Issues"
$emailMessage.IsBodyHtml = $true
$emailMessage.Body = "Test"
$SMTPClient = New-Object System.Net.Mail.SmtpClient( $emailSmtpServer ,$emailSmtpServerPort )
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential( $emailSmtpUser , $emailSmtpPass );
$SMTPClient.Send( $emailMessage )
}
This is the output
PS C:\Users\XXLOCKRG1> email
You cannot call a method on a null-valued expression
At C:\database_backups\powershell scripts\functions\email.ps1:8 char:34
+ $emailMessage.Attachments.Add <<<< ($attachment)
+ CategoryInfo : InvalidOperation: (Add:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You have two lines of code in the wrong order:
$emailMessage.Attachments.Add($attachment) # $emailMessage isn't instantiated yet
$emailMessage = New-Object System.Net.Mail.MailMessage
Should be:
$emailMessage = New-Object System.Net.Mail.MailMessage
$emailMessage.Attachments.Add($attachment)
You need to instantiate your object before you can reference its members.
You're trying to add an attachment to the $emailMessage object before you actually create it.
$emailMessage.Attachments.Add($attachment) #<---This is causing the error
$emailMessage = New-Object System.Net.Mail.MailMessage
Just rearrange the lines, put the New-Object line before the .Attachments.Add() line.
With that being said, have you tried using the Send-MailMessage cmdlet? It shipped with PowerShell 3.0 and is much, much much easier than using the old SMTP object.