48

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 'myself@gmail.com' `
    -to 'myself@gmail.com' -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 'myself@gmail.com' -to 'myself@gmail.com' -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.

SteveC
  • 15,808
  • 23
  • 102
  • 173
slayedbylucifer
  • 22,878
  • 16
  • 94
  • 123

7 Answers7

51

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 = "myself@gmail.com"
$EmailFrom = "me@mydomain.com"
$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="myself@gmail.com",  #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 "Myself@gmail.com" -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.

Zak
  • 6,976
  • 2
  • 26
  • 48
Nick
  • 4,302
  • 2
  • 24
  • 38
  • 2
    Thanks for the solution and your time. I was able to make it work with this command: `PS > Send-MailMessage -smtpServer smtp.gmail.com -Credential $credential -Usessl true -from 'myself@gmail.com' -to 'myself@gmail.com' -subject 'Testing' -attachment C:\CDF.pdf`. THe only thing is, you have store the credentials in a variable (`$credential` in above command) using `Get-Credential` prior to running this command. and yes, this works only on Powershell Ver 2. Also please find my answer regarding ssl usage. – slayedbylucifer Sep 17 '12 at 16:14
  • Please do post if you come up with a way to put encrypted password. That would really helpful. Thanks. – slayedbylucifer Sep 17 '12 at 16:19
  • Yes, with your command you would need the `get-credential` command. This is looking for a plain-text password, so `get-credential` wouldn't work, since it stores it as a secure string. I'll play with it some more at lunch when I have some free time and see if I can figure out a way to get the password secured until it is called. – Nick Sep 17 '12 at 16:31
  • 1
    I cheated on the encrypting password bit. Since it's a script, I don't think you can make it impervious to prying eyes. My hack of a solution was to simply Base64 encode my password and use it along with a `Base64-Decode` function. That way it's not obvious what the password is. Works like a champ. – Chase Florell Mar 13 '13 at 22:53
  • 1
    @Nick you first code don't have the declaration of `$EmailFrom` variable – JuanPablo Oct 08 '13 at 13:43
  • @JuanPablo Thank you for pointing that out. I have modified the answer. – Nick Oct 08 '13 at 21:07
33

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 'sender@gmail.com' -To 'recipient@gmail.com' -Subject 'TEST'
Angel Yordanov
  • 3,112
  • 1
  • 22
  • 19
18

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 = "usernameForEmailPassword@gmail.com"
$File = "C:\EmailPassword.txt"
$cred=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, (Get-Content $File | ConvertTo-SecureString)
$EmailTo = "emailTo@yahoo.com"
$EmailFrom = "emailFrom@gmail.com"
$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.

Dima
  • 655
  • 2
  • 8
  • 20
  • I've found you can create a `NetworkCredential` directly, without having to go through an intermediate `PSCredential` object. – mwfearnley Jan 25 '18 at 09:00
9

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.

Tim Dunn
  • 91
  • 1
  • 2
  • This should be the accepted answer, as it is exactly what was asked at first (not recode a whole email sending function, but just 'how to use '-credential' option) – Worst Dec 07 '21 at 15:56
7

So..it was SSL problem. Whatever I was doing was absolutely correct. Only that I was not using the ssl option. So I added "-Usessl true" to my original command and it worked.

slayedbylucifer
  • 22,878
  • 16
  • 94
  • 123
  • Same here. Looked and acted like an authentication issue, but simply turning on SSL fixed it. What's really strange in my case is that it suddenly quit working on its own after working fine for weeks. Wonder if an update was pushed that change the behavior/requirements of the server? I know I didn't change any of our connector settings! – Brian Knoblauch Mar 26 '19 at 18:53
5

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 'yyy@gmail.com' -To 'xxx@email.com' -Subject 'TEST'
ArtOfWarfare
  • 20,617
  • 19
  • 137
  • 193
JohnMiguel
  • 155
  • 3
  • 10
2

Along with the other answers i would like to point out that if you have two factor authentication, you will need to create an application password on your google account.

For the detailed explanations : https://support.google.com/accounts/answer/185833

Laurent B
  • 2,200
  • 19
  • 29
  • Warning to others, if you don't have 2-Step enabled, SMTP will be blocked with the same generic unauthenticated message unless you turn on "Allow less secure apps" in Gmail's security settings or enable 2-Step. – WhoIsRich May 30 '22 at 00:12