send gmail using powershell [duplicate] - powershell

This question already has answers here:
sending email with gmail using powershell
(3 answers)
Closed 4 years ago.
I'm developing a simply monitoring too for my home and I need it to send me an email. However, no matter what I try, it is not connecting to my gmail account to send the notification - or even a simple test message. I have a script that is working for a utility I wrote for work, but that is using the corporate SMTP relay. I'm not going to mix work and personal resources.
I have spent the past 4-5 weeks digging through this and trying several other development languages. All have come up with similar problems.
I have attempted the following:
Turned on less secure apps
Tried a variety of ports, 25, 465, 587
Turned on and off SSL
Tried various forms of my username (email address)
Turned on 2-factor authentication and created an app password for this utility
Attempted to turn on TLS - as one error indicated I needed a starttls command.
With Powershell, I seem to get two common errors. The first one is dependent on the parameters I'm sending to the Send argument - regardless, it fails.
[Screenshot of error - ][1]
I have been on multiple forums and sites. All of the suggested code appears to be all variants of the same structure, as is the working one for my office - just using our own mail system.

You should be able to use Send-MailMessage for this. Here's an example for sending an email securely using Gmail's SMTP server (including how to securely store your credential for further use later or in automation):
# Securely enter your Gmail credential
$cred = Get-Credential
# Store it off in a file if you want to reuse it later from the same box
# Password is encrypted and only your user on the same box can decrypt it
$cred | Export-CliXml \Path\To\GmailCredential.xml
# Import the credential from the file later
$cred = Import-CliXml \Path\To\GmailCredential.xml
# Send the mail message (use -BodyAsHtml instead of -Body if you have an HTML body)
$sendMailArguments = #{
SmtpServer = "smtp.gmail.com"
Credential = $cred
UseSsl = $true
Port = 587
To = "mailbox#domain.tld"
From = "youremail#domain.tld"
Subject = "Subject of the email"
Body = "Body of the email"
}
Send-MailMessage #sendMailArguments
Note that if you have Multi-Factor Authentication (MFA) set up you will need an app-specific credential to auth to Gmail, which would be a required step as well for setting up an email client for a Gmail account using MFA.
If you can't reach smtp.gmail.com, then it's likely you have a firewall blocking traffic to that server and port.
And if you want to better understand why I'm calling Send-MailMessage with a hashmap of arguments instead of specifying each parameter separately, see the comment discussion on this answer, and read up on Splatting here: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_splatting?view=powershell-6

Related

Office365 SMTP with OAUTH2 client credentials flow returns "Authentication unsuccessful"

We have been trying to use Office365 SMTP OAUTH2 authentication with client credentials flow without success.
The documentation claims that SMTP should work
https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth
but also states the following:
<<Note As per the current test with SMTP Oath 2.0 client credential flow with non-interactive sign in is not supported.">>
We can generate a token using the code interactive flow and with the delegation dynamic scope
https://outlook.office.com/SMTP.Send
The resulting token has scope "SMTP.Send" which can be used in JavaMail to successfully send emails from a specific user.
We are building a non-interactive application, the above does not work for us.
When we try to generate a token with the client credential flow, the only scope format supported is {resource}/.default
HTTP POST https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/token
client_id=...
client_secret=...
grant_type=client_credentials
scope=https://outlook.office365.com/.default
There are no application's permissions for SMTP we can set under the Microsoft Office API.
Authentication always returns "535 5.7.3 Authentication unsuccessful"
This should work like IMAP does.
The only option we have found is to disable Security Defaults under
Azure Active Directory
-> Properties
-> Manage Security Defaults
Which enables PLAIN TEXT authentication.
You also need make sure that your emailbox does not have Smtp Client Authentication disabled with the following powershell command
Set-CASMailbox -Identity -SmtpClientAuthenticationDisabled $false
after these two changes JavaMail can authenticate using user/pwd and can send emails.
Per https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth:
Note As per the current test with SMTP Oauth 2.0 client credential flow with non-interactive sign in is not supported.
I just discovered this myself.
The Microsoft Graph API is an alternative option and I have confirmed it does work with the Client Credentials flow, but it has other limitations related to volume and file attachments to be considered.

Can we change "apikey'" string in sendgrid

I am using sendgrid to send emails. I followed this guide to integrate SMTP relay.
In sendgrid they required "apikey" string to be set as username.
All configurations are successful but I am receiving email with this "apikey" string, like this: apikey <from_email_address>
This should be something like this instead of "apikey" string":
When I change the username (apikey in my case) then it starts showing bad username etc.
I'm new to sendgrid so not sure how we can achieve this but I believe no one would be sending emails to customers with this "apikey" string.
WSO2 Support team helped with this as it's a configuration which we need to set in deployment.toml file in WSO2 Identity server (I tried with version 5.11.0).
This block of code is required to configure sending email from WSO2 Identity server.
[output_adapter.email]
from_address= "wso2iamtest#gmail.com"
username= "wso2iamtest"
password= "Wso2#iam70"
hostname= "smtp.gmail.com"
port= 587
enable_start_tls= true
enable_authentication= true
signature = "ABC.com"
We need to add a value in signature = "Support" in order to receive emails with proper sender name. for example Support <test#support.com>
It is documented here:
https://is.docs.wso2.com/en/latest/setup/configuring-email-sending/

Forward email using MailKit

I am trying to email EML files via Gmail SMTP server using MailKit. I followed example provided by jstedfast to build MimeMesage and send via Gmail SMTP server. I am able to send email using both the simple authentication using (user account, user password) and using OAUTH2. I followed example how to Setting up OAuth2 for use with Google Mail and all works fine, except that it seems that I have to configure access Scopes to include "https://mail.google.com/"
var accessScopes = new[]
{
"https://mail.google.com/",
"https://www.googleapis.com/auth/gmail.send"
};
otherwise sending fails with the following error:
535: 5.7.8 Username and Password not accepted. Learn more at
5.7.8 https://support.google.com/mail/?p=BadCredentials c5sm231676iod.25 - gsmtp
I assumed that I need to configure access scope with the gmail.send only but it doesn't seem to work.
"https://www.googleapis.com/auth/gmail.send"
I don't want to configure "https://mail.google.com/" which implies full access to the gmail account. When the consent screen is presented to users, users may hesitate to accept all access scopes which seems to be required otherwise sending of mails fails.
I tried to configure some of the read only scopes instead of "https://mail.google.com/" but it doesn't seem to work.
What I am missing?
Thank you
The "https://mail.google.com/" scope is the only scope that works with SMTP, POP3 and/or IMAP.
All of the other scopes are only available to use with the Google REST APIs.

Adding an Alias to a Microsoft O365 Group

Wanted to add an answer to what I learned after researching and succeeding with this issue.
I have a Microsoft O365 account where I run my business. I am using Microsoft Teams so my executive team can see information and emails specific to that function. For instance, Human Resources. That team is setup to use humanresources#contoso.com as its email Office 365 Group. I want to add jobs#contoso.com as an alias to the group. But the O365 Admin panel or Exchange Admin Center (EAC) do not have that function available. How do you add an Alias to a Microsoft O365 Group?
There is a link that describes how to use PowerShell to add an alias:
Add Additional SMTP Aliases to Office 365 Groups
Concise Instructions
Open PowerShell.
Allow Remote, Signed scripts so you can import Microsoft O365 Exchange commands. We will set this back to default when done:
Set-ExecutionPolicy RemoteSigned
Enter your credentials so you can manage the O365 environment you are working on. It will prompt you for your username and your password:
$UserCredential = Get-Credential
Create a new PowerShell session to import the Microsoft O365 Exchange commands:
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Import the session. You should see the standard PowerShell progress bar as the commands are imported:
Import-PSSession $Session
Now you are ready to issue your commands. First, make sure you can read the properties of the Exchange Group:
Get-UnifiedGroup -Identity humanresources#contoso.com | FL EmailAddresses
It should output the aliases assigned to the Outlook Group.
To add the alias, enter this command. I will use my example in the question above to show what it looks like:
Set-UnifiedGroup -Identity humanresources#contoso.com -EmailAddresses #{Add="jobs#contoso.com"}
You can then run the Get-UnifiedGroup command and see the alias now listed in the email addresses.
Return to the default execution policy:
Set-ExecutionPolicy Default
Next Steps
At this point the group has an alias. You can email the alias internally to your O365 account. For instance, User1#contoso.com can email jobs#contoso.com and it will work correctly. It will be received in your O365 Human Resources group.
However, if you attempt to send email to the alias from external, you will get a 5.4.1 access denied error. You will get this even if you are able to email humanresources#contoso.com. (If you can't email the primary alias externally, you have another problem where the group is not set to receive external email, that can be set in the EAC.)
The problem where the alias cannot receive external email has to do with Directory Based Edge Blocking (DBEB). Essentially, before O365 performs any of its protection actions (anti-malware, anti-virus, SPAM, etc.) it performs a simple lookup into your Active Directory. It looks to see "Hey, does this user even exist here?"
For instance, if you are sending email to User1#contoso.com, DBEB looks up the directory and say, OK, that user exists, send it on. It does the same for humanresources#contoso.com. However, the lookup fails for additional aliases assigned to O365 Groups. There is a workaround.
Workaround
The workaround is disabling DBEB for the contoso.com domain. This does not disable the additional layers of protection of email hygiene (anti's, spam, etc.). To do so, you need to go into the EAC of your O365 account and change the Accepted Domains from Authoritative to Internal relay.
If you have natively started in O365, this is probably set to Authoritative. If you have a hybrid (O365 and Onsite), or did a migration from Onsite to O365 it is most likely already set to Internal relay (Unless post-migration you changed it to Authoritative). This is why for some people, just adding the alias works for them. DBEB is already disabled. Again, this only disables the first check of a valid user or not and the remainder of the hygiene stack is still in place.
After this change, your O365 Groups should now receive external email to their additional aliases.
Better Ways?
Yes, there should be better ways to add aliases to O365 Groups, like going to the group, selecting aliases, and adding them. That way we aren't in the shell and EAC making things work like they should. Microsoft, make it so!
Another way may be somehow to use New-EOPMailUser to create an entry in the Directory for the alias. When I tried to create a new Contact in the EAC, it stated that the email address was already in use. So, I got it to work and haven't looked at other options. I am assuming Microsoft will get aliases added in a more admin friendly way (PLEASE?!).
Keep Calm and Cloud On!
Wayne is spot on, however, there is a method to work around the DBEB issue. If you cycle each alias as the primary address (Cap SMTP) and then end back on the desired primary, all addresses will receive mail from outside addresses.
Set-UnifiedGroup -Identity "O365 Identity" -EmailAddresses SMTP:email#domain1, email#domain2, smtp:email#domain.onmicrosoft.com
Found the work around Here (The update at the very bottom)
If you are an admin, this works (at least for a Distribution Group) using O365.
Go to Admin
On the left, click Show All and then Exchange
In the Exchange Admin go to Recipients and then Groups
Double click the group.
Click Email Options
Click the + and add the additional email.
I've just done this and didn't have to do anything to allow me to email the alias externally (except configure the O365 Group to be able to be emailed externally). I checked the config of my Accepted Domains and they are both Authoritative. We are a cloud only tenant, so no hybrid, and I didn't muck around with the primary address.
To add to existing answers what worked for me:
Create a shared mailbox with desired e-mail.
Set up auto-forwarding
to O365 Group.
Extra hop, little hassle, same effect.

Accessing a SMTP/IMAP mailbox using powershell

I need a library/API allowing me to connect to a SMTP/IMAP server with authentication using powershell.
I need to adapt a powershell script that uses EWS to access an Exchange server.
This Exchange Server will be shut down and we need to adapt that script for SMTP/IMAP.
This script looks into a mailbox for inbox and sent email and search some mail from their subjects using the EWS objects.
Thanks guys, but i can't find what i need with the APIs you gave me.
Closing the question.