[security] Send mail via Gmail with PowerShell V2's Send-MailMessage

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 "[email protected]", $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.

This question is related to security powershell gmail

The answer is


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!!


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

Tested and working solution:

$EmailFrom = "[email protected]"
$EmailTo = "[email protected]"
$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...


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.


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  = '[email protected]'
    From = '[email protected]'
    To = '[email protected]'
    Subject = 'Sending emails through Gmail with Send-MailMessage'
    Body = "Check out the PowerShellMagazine.com website!"
    Attachments = 'D:\articles.csv'
}

Send-MailMessage @param

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!


Send email with attachment using PowerShell -

      $EmailTo = "[email protected]"  // [email protected]
      $EmailFrom = "[email protected]"  // [email protected]
      $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("[email protected]", "xxxxxxxx"); // xxxxxx-password
      $SMTPClient.Send($SMTPMessage)

This should fix your problem:

$credentials = New-Object Management.Automation.PSCredential “[email protected]”, (“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


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

$EmFrom = "[email protected]"
$username = "[email protected]"
$pwd = "YOURPASSWORD"
$EmTo = "[email protected]"
$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

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 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 = “[email protected]”
$msg.To.Add(”[email protected]”)
$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.


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('[email protected]', '[email protected]', 'test subject', 'test message')

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("[email protected]", "[email protected]", "Test Message", "Message via local SMTP")

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 - [email protected]
## 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 [email protected]
    [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.


Examples related to security

Monitoring the Full Disclosure mailinglist Two Page Login with Spring Security 3.2.x How to prevent a browser from storing passwords JWT authentication for ASP.NET Web API How to use a client certificate to authenticate and authorize in a Web API Disable-web-security in Chrome 48+ When you use 'badidea' or 'thisisunsafe' to bypass a Chrome certificate/HSTS error, does it only apply for the current site? How does Content Security Policy (CSP) work? How to prevent Screen Capture in Android Default SecurityProtocol in .NET 4.5

Examples related to powershell

Why powershell does not run Angular commands? How do I install the Nuget provider for PowerShell on a unconnected machine so I can install a nuget package from the PS command line? How to print environment variables to the console in PowerShell? Check if a string is not NULL or EMPTY The term 'ng' is not recognized as the name of a cmdlet VSCode Change Default Terminal 'Connect-MsolService' is not recognized as the name of a cmdlet Powershell Invoke-WebRequest Fails with SSL/TLS Secure Channel Install-Module : The term 'Install-Module' is not recognized as the name of a cmdlet Change directory in PowerShell

Examples related to gmail

Expected response code 250 but got code "535", with message "535-5.7.8 Username and Password not accepted How to to send mail using gmail in Laravel? HTML image not showing in Gmail Gmail Error :The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required Send email from localhost running XAMMP in PHP using GMAIL mail server The server response was: 5.7.0 Must issue a STARTTLS command first. i16sm1806350pag.18 - gsmtp Gmail: 530 5.5.1 Authentication Required. Learn more at Sending mail attachment using Java Javamail Could not convert socket to TLS GMail Unable to send email using Gmail SMTP server through PHPMailer, getting error: SMTP AUTH is required for message submission on port 587. How to fix?