The following script can be used to send an email message using SMTP. This method is slightly different to my previous post about sending email messages in Powershell as this method uses the smtpClient method rather than mailmessage in order to allow for authentication to occur.
$From = "fromaddress@domain.com"
$To = "toaddress@domain.com"
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
$Username = "username@gmail.com"
$Password = "gmailpassword"
$subject = "Email Subject"
$body = "Insert body text here"
$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
$smtp.EnableSSL = $true
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
$smtp.Send($From, $To, $subject, $body);
You will need to update the values of the first 8 variables to match what is required for the email account/domain you are sending from.
The SMTP Server and Port number will vary for different email providers - I can confirm the server and port specified above for Gmail are correct though.
UPDATE - 29/11/13
You can also use the System.Net.Mail.MailMessage class to give you the additional option to add CC, BCC, attachments etc, as per the below script. Simply update the first 9 variables below to configure your email message.
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
$Username = "username@gmail.com"
$Password = ""
$to = "user1@domain.com"
$cc = "user2@domain.com"
$subject = "Email Subject"
$body = "Insert body text here"
$attachment = "C:\test.txt"
$message = New-Object System.Net.Mail.MailMessage
$message.subject = $subject
$message.body = $body
$message.to.add($to)
$message.cc.add($cc)
$message.from = $username
$message.attachments.add($attachment)
$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"
Perfect! This is just what I needed. thanks!
ReplyDeleteIt helped me, thanks much!
ReplyDeletePlease help me to advise how to add cc and attachment in this scripts, Thanks
ReplyDeleteHi Baktash - thanks for your comment. I have updated the original post to give you details on how to do this (add CC and attachment).
DeleteGreat tutorial. Do you have any idea how the message body can have newlines? My body gets concatenated in a single line...
ReplyDeleteTo start a new line use `r`n
Deleteeg. $body = "line 1 text `r`n line 2 text `r`n line 3 text
The inverted single quote (next to the "1" key) is an escape character, used to format text. Hope this helps :-)
Perfect! Exactly what I'm looking for! Great job! Thanks.
ReplyDeleteGood Job..Much Appreciated
ReplyDeleteThis post has everything I needed to set up my email script. Thanks so much!!!!!!
ReplyDeleteGood Job.. But How To Add Many attachments?
ReplyDeleteHi friend, I followed your script but the error message appears:
ReplyDelete-------------------------------------------------------------------------------------
Exception calling "Send" with "1" argument(s): "Failure sending mail."
At C:\Users\Rodrigo\Desktop\MonitorPS\SendMail.ps1:148 char:5
+ $smtp.Send($msg)
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SmtpException
--------------------------------------------------------------------------------------
Please, do you have any idea?
Thanks,
Rodrigo
Hi Peter
ReplyDeleteGreat post, may thnx. I'm getting the same error as Rodrigo. Somehow it seems as though the credentials do not get applied correctly in PS4. Any tips on that? (Applying creds in PS4)
Many thanks again
Willem
Rodrigo/Willem - I just tested this myself using Powershell 4.0, copy and pasted both of my examples above and it worked fine. What email domain are you sending from? eg. Gmail, Yahoo, Hotmail?
DeleteThis comment has been removed by the author.
ReplyDeleteHello Peter, this command works perfectly when using standard Gmail authentication method, but do you know if there is a way to send 2-step verification codes?
ReplyDelete# Google provides the ability to create "App passwords" that allows you to configure a 16 character application specific password.
Delete# Login to your google account, then go to https://myaccount.google.com/security
# scroll down page and select "App passwords"
# then select "Mail" or "Other" and specify a device name (for your own information), then Generate
# the 16 char password becomes a direct login password to your gmail account that you can use with your normal login user id in powershell. I have used this technique successfully with powershell from Windows 10 and windows 8.1
# when you decide you no longer need that app password, you can always revoke it using the same page
This is great.Thanks for sharing.I have enabled two steps verification and was getting authentication failure error.now it got fixed based on the above method
Deletedos not work for me!?
DeleteHi
ReplyDeleteIt mainly works but I cannot work out how to find the correct path for the attachemnet/
Hi Peter,
ReplyDeleteI am trying to use the powershell script to send mails but I am facing a problem with the University gmail setup. When we login into mail.google.com we use the external account and we are redirect into the internal shibboleth authentication.
So I am trying to figure out how to solve this problem inside the script without success.
Have you any idea how to do that?
Thanks for your help
Mirco
Thanks this really work
ReplyDeleteReally worked!!!! thanks peter....
ReplyDeleteIt works fine across google Accounts but a delay seen when sending from a gmail account to other server accounts.
how can I add multiple recipients?
ReplyDeleteI need to send an email on specific event ID in event viewer. Can you please guide what I need to add to above script?
ReplyDeleteHere's a powershell script to pull the specified events from the event log, you can redirect this to a text file. My example is looking for 3 different events, all related to restarts, but can be ANY event id you want to capture. This is run from the local machine but you can code it to pull from remote machines
Delete===============codestart===============
Get-EventLog System | Where-Object {$_.EventID -eq "1074" -or $_.EventID -eq "6008" -or $_.EventID -eq "1076"} | ft Machinename, TimeWritten, UserName, EventID, Message -AutoSize -Wrap
===============code end-===============
Here's a powershell script to pull the specified events from the event log, you can redirect this to a text file. My example is looking for 3 different events, all related to restarts, but can be ANY event id you want to capture. This is run from the local machine but you can code it to pull from remote machines
Delete===============codestart===============
Get-EventLog System | Where-Object {$_.EventID -eq "1074" -or $_.EventID -eq "6008" -or $_.EventID -eq "1076"} | ft Machinename, TimeWritten, UserName, EventID, Message -AutoSize -Wrap
===============code end-===============
Hi Peter, if I'm piping a command to the $body, can I still format the objects to display on different lines? Tried using carriage returns in the form of Get-Content C:\input.txt | ForEach-Object {$_.Line + "`r`n"} but doesn't seem to be working.
ReplyDeletefor me it work with this script , I run it from the local host of exchange
ReplyDelete$SMTPServer = "2k8x64Ex2k10.EXCHDOM.COM"
#$SMTPPort = "587"
$SMTPPort = "25"
#Username = "2k8x64Ex2k10@EXCHDOM.COM"
#$Username = "Administrator@EXCHDOM.COM"
$Username = "test@EXCHDOM.COM"
$Password = "rrrrrrrrr"
$to = "test@EXCHDOM.COM"
$cc = "test@EXCHDOM.COM"
$subject = "Email Subject"
$body = "Insert body text here"
#$attachment = "C:\test.txt"
#$message = New-Object [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { return $true }
$message = New-Object System.Net.Mail.MailMessage
$message.subject = $subject
$message.body = $body
$message.to.add($to)
$message.cc.add($cc)
$message.from = $username
#$message.attachments.add($attachment)
$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
$smtp.EnableSSL = $true
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { return $true }
#$smtp.UseDefaultCredentials=$true
$smtp.send($message)
write-host "Mail Sent"
Tried using this script with both gmail accounts and other email accounts, using the correct info etc. but always fails with a timeout and never actually sends the email, any ideas?
ReplyDeletelog into your gmail, you should see an "unauthorized" login attempt, this script, like all the others, is missing a critical piece to force it to basic authentication. this script will work on an exchange server, but as written here, will not authenticate to gmail.
DeleteThis script, like all the others has been tested and works with my gmail account and has done so since the article was first published
DeleteHave you got any local firewall/antivirus software that may be blocking the connection?
For this to work, you have to turn on the option to allow access to less secure apps in your Google account security settings.
DeleteHi Peter,
ReplyDeleteI am using Powershell 3.0 ISE and have tried running the code you provided to send a basic e-mail to and from my personal g-mail account.
I keep getting the following error message:
Exception calling "Send" with "4" arguments: "The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.0 Must issue a STARTTLS command first. p39sm5629990qkp.47 - gsmtp"
Any thoughts?
I am getting a similar message
DeleteException calling "Send" with "1" argument(s): "The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1
Authentication Required. Learn more at"
At line:21 char:1
+ $smtp.send($message)
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : SmtpException
Thank you for the information, I think this article is very useful for all who read it.
ReplyDelete.
Thanks so very much for this. Been trying to send mail to a restricted DL using send-mailmessage and simply cannot get it to accept the credentials I feed it. The method detailed here works like a charm, though!
ReplyDeleteHi Peter,
ReplyDeleteuseful post mate, now become my collection of powershell script. Recently I use powershell to let me know about free disk space condition on the server, I post it here http://yunarwinardi.com/free-disk-space-alerts-to-your-email-easy-steps/
Thanks
Nice post. It worked good. Thanks
ReplyDeleteI am using SendGrid SMTP (smtp.sendgrid.net) for sending email, but getting the error
ReplyDeleteSend-MailMessage : Unable to read data from the transport connection: net_io_connectionclosed.
At line:36 char:5
+ Send-MailMessage -smtpServer $SMTPServer -Credential $SGCredentia ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.Mail.SmtpClient:SmtpClient) [Send-MailMessage],
SmtpException
+ FullyQualifiedErrorId : SmtpException,Microsoft.PowerShell.Commands.SendMailMessage
Great tutorial. Do you have any idea how the message body can have newlines? My body gets concatenated in a single line...
ReplyDeleteOxford Security
I love this great article
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDeleteI love this article
ReplyDeleteDo you have any idea how the message body can have newlines?
ReplyDeleteAs the body is html code, use < br > for a new line, or < p > for a new paragrah (remove the spaces between the brackets and characters - needs to be formatted like this in order for it to post)
DeleteNice post. It worked good. Thanks
ReplyDeletethis script will work on an exchange server, but as written here, will not authenticate to gmail.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteGreat article, Thanks for sharing
ReplyDeleteNow i can send an email message using SMTP. Thanks for sharing such awesome information.
ReplyDeleteException calling "Send" with "1" argument(s): "The SMTP server requires a secure connection or the client was not
ReplyDeleteauthenticated. The server response was: 5.5.1 Authentication Required
sounds like you aren't configured to send using SSL - make sure the $smtp.EnableSSL = $true is present
DeleteThanks for sharing such awesome information.
ReplyDeletenice update
ReplyDeletewhat is username and password in this script? Is it system username and password..?
ReplyDeleteYou need to use the username and password for the email account you are sending from
DeleteThe username would typically be the email address
Peter, I stumbled upon your "Sending SMTP Emails with Powershell using Authentication" last night after having tried so many others - exactly what I needed , well almost! I'd really like only to send, say, the last dozen lines of a log file which has the pertinent information? Many thanks for your efforts and all respondents! Michael
ReplyDeleteHi Michael - you can use the following to include text (the last 12 lines) from a log file in the body of the email
ReplyDelete$body = get-content "C:\blah\logfile.log"
$body = $body[-12..-1]
-12 represents the 12th last line of the file, -1 represents the last line of the file. You just need to change the path above to match where your log file is located
The $body variable is already used in my original example above for the body text of the email ($message.body = $body)
Hope this helps!
Hi Peter,
ReplyDeleteThanks for sharing, however I'm getting the error that was raised by some ppl on earlier comments. Please see below:
"Send" with "1" argument(s): "The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required.
I just changed the values with my creds but still getting the error. I'm using a gmail account.
TIA
Regards,
Chii
You may have to allow access to "less secure apps" in your google account settings
DeleteGo to https://myaccount.google.com/lesssecureapps and set it to "On" and try again
You may have to allow access to "less secure apps" in your google account settings
ReplyDeleteGo to https://myaccount.google.com/lesssecureapps and set it to "On" and try again
Thanks it worked for me
DeleteThis comment has been removed by a blog administrator.
ReplyDeleteHey men, i have a problem with the premission for the System.Net.Mail.Attachment and the last line get another error: Exception calling "Send" with "1" argument(s): "Faild to send the mail."
ReplyDeleteAt line:23 char:1
+ $smtp.send($message)
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SmtpException
Found this and used it on my Windows 2012 PS script
ReplyDeleteIt worked exactly as described when I needed my PS script to bounce SMTP mail through the Earthlink (smtpauth.earthlink.net 587) using my Earthlink account to authenticate.
Copied and pasted, changed the needed details for my account and it worked.
There was one confusing error message from the SMTP server when I 1st tried it due to a typo in the password. It complained it could not deliver the email to all recipients.