[powershell] How to pass credentials to the Send-MailMessage command for sending emails

I'm having difficulty passing my credentials to the Send-MailMessage command

This is what I am running:

Send-MailMessage -smtpServer smtp.gmail.com -from '[email protected]' `
    -to '[email protected]' -subject 'Test' -attachment C:\CDF.pdf

it errors with below the message which is obviously because I have not passed my gmail credentials

Send-MailMessage : 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.

I googled a bit and also went through the man page of Send-MailMessage and found that the "-credential" parameter needs to be passed.

My issue is: HOW ?

I tried with Get-Credentials as below:

$mycredentials = Get-Credential

Then entered my usrname and password for gmail in the box that pops up.

then I run below command:

Send-MailMessage -smtpServer smtp.gmail.com -credentail $mycredentials `
  -from '[email protected]' -to '[email protected]' -subject 'Test' -attachment C:\CDF.pdf

and still it fails with the exact same error.

So I need help from you guys on how do I pass my Credentials to the Send-MailMessage command. I learned about PScredentials but not exactly sure what it is and how to use it in this context.

This question is related to powershell

The answer is


I found this blog site: Adam Kahtava
I also found this question: send-mail-via-gmail-with-powershell-v2s-send-mailmessage
The problem is, neither of them addressed both your needs (Attachment with a password), so I did some combination of the two and came up with this:

$EmailTo = "[email protected]"
$EmailFrom = "[email protected]"
$Subject = "Test" 
$Body = "Test Body" 
$SMTPServer = "smtp.gmail.com" 
$filenameAndPath = "C:\CDF.pdf"
$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("username", "password"); 
$SMTPClient.Send($SMTPMessage)

Since I love to make functions for things, and I need all the practice I can get, I went ahead and wrote this:

Function Send-EMail {
    Param (
        [Parameter(`
            Mandatory=$true)]
        [String]$EmailTo,
        [Parameter(`
            Mandatory=$true)]
        [String]$Subject,
        [Parameter(`
            Mandatory=$true)]
        [String]$Body,
        [Parameter(`
            Mandatory=$true)]
        [String]$EmailFrom="[email protected]",  #This gives a default value to the $EmailFrom command
        [Parameter(`
            mandatory=$false)]
        [String]$attachment,
        [Parameter(`
            mandatory=$true)]
        [String]$Password
    )

        $SMTPServer = "smtp.gmail.com" 
        $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body)
        if ($attachment -ne $null) {
            $SMTPattachment = New-Object System.Net.Mail.Attachment($attachment)
            $SMTPMessage.Attachments.Add($SMTPattachment)
        }
        $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
        $SMTPClient.EnableSsl = $true 
        $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($EmailFrom.Split("@")[0], $Password); 
        $SMTPClient.Send($SMTPMessage)
        Remove-Variable -Name SMTPClient
        Remove-Variable -Name Password

} #End Function Send-EMail

To call it, just use this command:

Send-EMail -EmailTo "[email protected]" -Body "Test Body" -Subject "Test Subject" -attachment "C:\cdf.pdf" -password "Passowrd"

I know it's not secure putting the password in plainly like that. I'll see if I can come up with something more secure and update later, but at least this should get you what you need to get started. Have a great week!

Edit: Added $EmailFrom based on JuanPablo's comment

Edit: SMTP was spelled STMP in the attachments.


in addition to UseSsl, you have to include smtp port 587 to make it work.

Send-MailMessage -SmtpServer smtp.gmail.com -Port 587 -Credential $credential -UseSsl -From '[email protected]' -To '[email protected]' -Subject 'TEST'

It took me a while to combine everything, make it a bit secure, and have it work with Gmail. I hope this answer saves someone some time.

Create a file with the encrypted server password:

In Powershell, enter the following command (replace myPassword with your actual password):

"myPassword" | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-File "C:\EmailPassword.txt"

Create a powershell script (Ex. sendEmail.ps1):

$User = "[email protected]"
$File = "C:\EmailPassword.txt"
$cred=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, (Get-Content $File | ConvertTo-SecureString)
$EmailTo = "[email protected]"
$EmailFrom = "[email protected]"
$Subject = "Email Subject" 
$Body = "Email body text" 
$SMTPServer = "smtp.gmail.com" 
$filenameAndPath = "C:\fileIwantToSend.csv"
$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($cred.UserName, $cred.Password); 
$SMTPClient.Send($SMTPMessage)

Automate with Task Scheduler:

Create a batch file (Ex. emailFile.bat) with the following:

powershell -ExecutionPolicy ByPass -File C:\sendEmail.ps1

Create a task to run the batch file. Note: you must have the task run with the same user account that you used to encrypted the password! (Aka, probably the logged in user)

That's all; you now have a way to automate and schedule sending an email and an attachment with Windows Task Scheduler and Powershell. No 3rd party software and the password is not stored as plain text (though granted, not terribly secure either).

You can also read this article on the level of security this provides for your email password.


PSH> $cred = Get-Credential

PSH> $cred | Export-CliXml c:\temp\cred.clixml

PSH> $cred2 = Import-CliXml c:\temp\cred.clixml

That hashes it against your SID and the machine's SID, so the file is useless on any other machine, or in anyone else's hands.


And here is a simple Send-MailMessage example with username/password for anyone looking for just that

$secpasswd = ConvertTo-SecureString "PlainTextPassword" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("username", $secpasswd)
Send-MailMessage -SmtpServer mysmptp -Credential $cred -UseSsl -From '[email protected]' -To '[email protected]' -Subject 'TEST'