44

I'm trying to figure out how to use PowerShell V2's Send-MailMessage with Gmail.

Here's what I have so far.

$ss = New-Object Security.SecureString
foreach ($ch in "password".ToCharArray())
{
    $ss.AppendChar($ch)
}
$cred = New-Object Management.Automation.PSCredential "uid@example.com", $ss
Send-MailMessage  -SmtpServer smtp.gmail.com -UseSsl -Credential $cred -Body...

I get the following error

Send-MailMessage : 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 foo.ps1:18 char:21
+     Send-MailMessage <<<<      `
    + CategoryInfo          : InvalidOperation: (System.Net.Mail.SmtpClient:SmtpClient) [Send-MailMessage], SmtpException
    + FullyQualifiedErrorId : SmtpException,Microsoft.PowerShell.Commands.SendMailMessage

Am I doing something wrong, or is Send-MailMessage not fully baked yet (I'm on CTP 3)?

Some additional restrictions:

  1. I want this to be non-interactive, so Get-Credential won't work.
  2. The user account isn't on the Gmail domain, but a Google Apps registered domain.
  3. For this question, I'm only interested in the Send-MailMessage cmdlet. Sending mail via the normal .NET API is well understood.
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Scott Weinstein
  • 18,890
  • 14
  • 78
  • 115
  • For what it's worth I get the same error and it looks like everything is ok. I'll play around some more with it. – EBGreen Aug 09 '09 at 23:43
  • Well now you're just being picky. :P – EBGreen Aug 10 '09 at 00:44
  • I think the way you are creating the credential should be ok. I have only authenticated directly to gmail before not through an apps domain, so not sure I'll be much help now. Sorry. – EBGreen Aug 10 '09 at 00:49
  • Curious - uid works, but uid@nongmail.com doesn't – Scott Weinstein Aug 10 '09 at 11:37
  • 4
    I notice this is an old question (2009) and that you updated it years ago (2011), yet there is still no accepted answer. Does that mean you were never able to solve your issue? –  Aug 29 '14 at 14:41
  • [Could anyone answer my question very similar to this?](http://stackoverflow.com/questions/34972917/send-mail-via-gmail-with-powershell-v4) – user3448143 Jan 24 '16 at 12:48
  • 3
    There is some gmail configuration you must perform before you can send emails from powershell. Enable "less secure apps" in the google security control panel. Make sure 2-factor authentication is disabled. Also, make sure the "Captcha" is disabled - this may be necessary if you are running the script on a remote server (not necessary when running on local machine): https://accounts.google.com/DisplayUnlockCaptcha – Jens May 17 '16 at 16:14

13 Answers13

53

Here's my PowerShell Send-MailMessage sample for Gmail...

Tested and working solution:

$EmailFrom = "notifications@somedomain.com"
$EmailTo = "me@earth.com"
$Subject = "Notification from XYZ"
$Body = "this is a notification from XYZ Notifications.."
$SMTPServer = "smtp.gmail.com"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("username", "password");
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)

Just change $EmailTo, and username/password in $SMTPClient.Credentials... Do not include @gmail.com in your username...

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Christian Casutt
  • 2,334
  • 4
  • 29
  • 38
  • thanks I'm a serverfault/superuser member and this helped me make a script to see when my server reboots. – jer.salamon Sep 17 '10 at 23:51
  • 4
    Almost there, however, you may get error message "The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required. " And this is because the default security settings of Gmail block the connection, as suggested by the auto message from Google. So just follow the instructions in the message and enable "Access for less secure apps". At your own risk. :) – ZZZ Jan 20 '15 at 01:17
  • Also, make sure the "Captcha" is disabled - this may be necessary if you are running the script on a remote server (not necessary when running on local machine): https://accounts.google.com/DisplayUnlockCaptcha – Jens May 17 '16 at 16:15
  • 5
    Keep Getting Authentication Failed w/Gmail Account? I had this issue which is what brought me to this post. I thought surely I had something wrong. Turns out, I needed to use an "App Password" instead of my Google Account password (since that is MFA - multi-factor auth). Create App Password: https://www.google.com/settings/security – DoubleJ Feb 17 '20 at 20:28
  • Thank you @DoubleJ, was losing my mind trying to figure out why I wasn't able to authenticate! – Eli Jul 03 '22 at 21:05
15

This should fix your problem:

$credentials = New-Object Management.Automation.PSCredential “mailserver@yourcompany.com”, (“password” | ConvertTo-SecureString -AsPlainText -Force)

Then use the credential in your call to Send-MailMessage -From $From -To $To -Body $Body $Body -SmtpServer {$smtpServer URI} -Credential $credentials -Verbose -UseSsl

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jstar
  • 151
  • 1
  • 2
9

I just had the same problem and ran into this post. It actually helped me to get it running with the native Send-MailMessage command-let and here is my code:

$cred = Get-Credential
Send-MailMessage ....... -SmtpServer "smtp.gmail.com" -UseSsl -Credential $cred -Port 587 

However, in order to have Gmail allowing me to use the SMTP server, I had to log in into my Gmail account and under this link https://www.google.com/settings/security set the "Access for less secure apps" to "Enabled". Then finally it did work!!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
7

I'm not sure you can change port numbers with Send-MailMessage since Gmail works on port 587. Anyway, here's how to send email through Gmail with .NET SmtpClient:

$smtpClient = New-Object system.net.mail.smtpClient
$smtpClient.Host = 'smtp.gmail.com'
$smtpClient.Port = 587
$smtpClient.EnableSsl = $true
$smtpClient.Credentials = [Net.NetworkCredential](Get-Credential GmailUserID)
$smtpClient.Send('GmailUserID@gmail.com', 'yourself@somewhere.com', 'test subject', 'test message')
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shay Levy
  • 121,444
  • 32
  • 184
  • 206
4

I used Christian's Feb 12 solution and I'm also just beginning to learn PowerShell. As far as attachments, I was poking around with Get-Member learning how it works and noticed that Send() has two definitions... the second definition takes a System.Net.Mail.MailMessage object which allows for Attachments and many more powerful and useful features like Cc and Bcc. Here's an example that has attachments (to be mixed with his above example):

# append to Christian's code above --^
$emailMessage = New-Object System.Net.Mail.MailMessage
$emailMessage.From = $EmailFrom
$emailMessage.To.Add($EmailTo)
$emailMessage.Subject = $Subject
$emailMessage.Body = $Body
$emailMessage.Attachments.Add("C:\Test.txt")
$SMTPClient.Send($emailMessage)

Enjoy!

core
  • 41
  • 1
3

After many tests and a long search for solutions, I found a functional and interesting script code at #PSTip Sending emails using your Gmail account:

$param = @{
    SmtpServer = 'smtp.gmail.com'
    Port = 587
    UseSsl = $true
    Credential  = 'you@gmail.com'
    From = 'you@gmail.com'
    To = 'someone@somewhere.com'
    Subject = 'Sending emails through Gmail with Send-MailMessage'
    Body = "Check out the PowerShellMagazine.com website!"
    Attachments = 'D:\articles.csv'
}

Send-MailMessage @param
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
BSF
  • 31
  • 1
3

I am really new to PowerShell, and I was searching about gmailing from PowerShell. I took what you folks did in previous answers, and modified it a bit and have come up with a script which will check for attachments before adding them, and also to take an array of recipients.

## Send-Gmail.ps1 - Send a gmail message
## By Rodney Fisk - xizdaqrian@gmail.com
## 2 / 13 / 2011

# Get command line arguments to fill in the fields
# Must be the first statement in the script
param(
    [Parameter(Mandatory = $true,
               Position = 0,
               ValueFromPipelineByPropertyName = $true)]
    [Alias('From')] # This is the name of the parameter e.g. -From user@mail.com
    [String]$EmailFrom, # This is the value [Don't forget the comma at the end!]

    [Parameter(Mandatory = $true,
               Position = 1,
               ValueFromPipelineByPropertyName = $true)]
    [Alias('To')]
    [String[]]$Arry_EmailTo,

    [Parameter(Mandatory = $true,
               Position = 2,
               ValueFromPipelineByPropertyName = $true)]
    [Alias('Subj')]
    [String]$EmailSubj,

    [Parameter(Mandatory = $true,
               Position = 3,
               ValueFromPipelineByPropertyName = $true)]
    [Alias('Body')]
    [String]$EmailBody,

    [Parameter(Mandatory = $false,
               Position = 4,
               ValueFromPipelineByPropertyName = $true)]
    [Alias('Attachment')]
    [String[]]$Arry_EmailAttachments
)

# From Christian @ stackoverflow.com
$SMTPServer = "smtp.gmail.com"
$SMTPClient = New-Object Net.Mail.SMTPClient($SmtpServer, 587)
$SMTPClient.EnableSSL = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("GMAIL_USERNAME", "GMAIL_PASSWORD");

# From Core @ stackoverflow.com
$emailMessage = New-Object System.Net.Mail.MailMessage
$emailMessage.From = $EmailFrom
foreach ($recipient in $Arry_EmailTo)
{
    $emailMessage.To.Add($recipient)
}
$emailMessage.Subject = $EmailSubj
$emailMessage.Body = $EmailBody
# Do we have any attachments?
# If yes, then add them, if not, do nothing
if ($Arry_EmailAttachments.Count -ne $NULL)
{
    $emailMessage.Attachments.Add()
}
$SMTPClient.Send($emailMessage)

Of course, change the GMAIL_USERNAME and GMAIL_PASSWORD values to your particular user and password.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • take a look at this code for multiple recipients https://stackoverflow.com/questions/10241816/powershell-send-mailmessage-email-to-multiple-recipients/55928717#55928717 – Zunair Aug 03 '21 at 19:54
2

On a Windows 8.1 machine I got Send-MailMessage to send an email with an attachment through Gmail using the following script:

$EmFrom = "user@gmail.com"
$username = "user@gmail.com"
$pwd = "YOURPASSWORD"
$EmTo = "recipient@theiremail.com"
$Server = "smtp.gmail.com"
$port = 587
$Subj = "Test"
$Bod = "Test 123"
$Att = "c:\Filename.FileType"
$securepwd = ConvertTo-SecureString $pwd -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $securepwd
Send-MailMessage -To $EmTo -From $EmFrom -Body $Bod -Subject $Subj -Attachments $Att -SmtpServer $Server -port $port -UseSsl  -Credential $cred
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Andy Urban
  • 21
  • 1
2

Send email with attachment using PowerShell -

      $EmailTo = "udit043.ur@gmail.com"  // abc@domain.com
      $EmailFrom = "udit821@gmail.com"  // xyz@gmail.com
      $Subject = "zx"  //subject
      $Body = "Test Body"  // Body of message
      $SMTPServer = "smtp.gmail.com" 
      $filenameAndPath = "G:\abc.jpg"  // Attachment
      $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $Body)
      $attachment = New-Object System.Net.Mail.Attachment($filenameAndPath)
      $SMTPMessage.Attachments.Add($attachment)
      $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
      $SMTPClient.EnableSsl = $true 
      $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("udit821@gmail.com", "xxxxxxxx"); // xxxxxx-password
      $SMTPClient.Send($SMTPMessage)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
udit043
  • 1,610
  • 3
  • 22
  • 40
2

I had massive problems with getting any of those scripts to work with sending mail in powershell. Turned out you need to create an app-password for your gmail-account to authenticate in the script. Now it works flawlessly!

  • Here is a clean snippet https://stackoverflow.com/questions/10241816/powershell-send-mailmessage-email-to-multiple-recipients/55928717#55928717 – Zunair Aug 03 '21 at 19:55
  • This answer needs to be enriched with the working example and be the accepted answer, since this is currently the only correct solution. All others are outdated. – Bernard Moeskops Mar 18 '22 at 10:22
1

Here it is:

$filename = “c:\scripts_scott\test9999.xls”
$smtpserver = “smtp.gmail.com”
$msg = New-Object Net.Mail.MailMessage
$att = New-Object Net.Mail.Attachment($filename)
$smtp = New-Object Net.Mail.SmtpClient($smtpServer )
$smtp.EnableSsl = $True
$smtp.Credentials = New-Object System.Net.NetworkCredential(“username”, “password_here”); # Put username without the @GMAIL.com or – @gmail.com
$msg.From = “username@gmail.com”
$msg.To.Add(”boss@job.com”)
$msg.Subject = “Monthly Report”
$msg.Body = “Good MorningATTACHED”
$msg.Attachments.Add($att)
$smtp.Send($msg)

Let me know if it helps you San. Also use the send-mailmessage also at Www.techjunkie.tv

For that way also that I think is way better and pure to use.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

I haven't used PowerShell V2's Send-MailMessage, but I have used System.Net.Mail.SMTPClient class in V1 to send messages to a Gmail account for demo purposes. This might be overkill, but I run an SMTP server on my Windows Vista laptop (see this link). If you're in an enterprise you will already have a mail relay server, and this step isn't necessary. Having an SMTP server I'm able to send email to my Gmail account with the following code:

$smtpmail = [System.Net.Mail.SMTPClient]("127.0.0.1")
$smtpmail.Send("myacct@gmail.com", "myacct@gmail.com", "Test Message", "Message via local SMTP")
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chad Miller
  • 40,127
  • 3
  • 30
  • 34
0

I agree with Christian Muggli's solution, although at first I still got the error that Scott Weinstein reported. How you get past that is:

EITHER first login to Gmail from the machine this will run on, using the account specified. (It is not necessary to add any Google sites to the Trusted Sites zone, even if Internet Explorer Enhanced Security Configuration is enabled.)

OR, on your first attempt, you will get the error, and your Gmail account will get a notice about suspicious login, so follow their instructions to allow future logins from the machine this will run on.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tom Keller
  • 11
  • 2