In the following two article series, we review the subject of – how to use…
Send E-mail to office 365 using PowerShell script and saved encrypted password |Part 2#2
In the following article, we will review how to write and run PowerShell script; that will address the Office 365 mail servers (Exchange Online).
Vs. the scenario that we have examined in the previous article, we review a situation, in which we address the Office 365 mail server anonymously (without providing user credentials).
In the current scenario, we want to implement more advanced configuration.
In the current scenario, we want to add two components to the mail communication
Table of contents
- PowerShell script and user credentials
- Method 1 – Send E-mail via Office 365 mail server using TLS session and authenticated session | Providing user credentials while running the script
- Method 2 – Send E-mail via Office 365 mail server using TLS session and authenticated session | Using saved encrypted user credentials
- Running PowerShell script using windows task scheduler
- The next article in the current series
1. Office 365 user credentials
The main reason for proving the Office 365 user credentials have been, that in case that the “element” (the PowerShell script) that address the Office 365 mail server consider as “identified user \ recipient,” the mail server relates to this element as a trusted entity.
Using the procedure in which we provide the user credentials, enables us to avoid from scenarios in which the E-mail that we sent by the PowerShell script will identify as a “problematic mail,” and for this reason, will be blocked or redirected to the user’s junk mail.
An additional advantage is that when we use an authenticated session, we can send the E-mail to external recipients, meaning recipients who are not hosted by the Exchange Online server.
2. Creating an encrypted communication channel
An additional layer of security that we will add is that in the current scenario, we want to use a secure communication link between the desktop that runs the PowerShell script and the Office 365 mail server. The implementation of the secure communication link is by using the TLS protocol.
By using TLS protocol, we can ensure that the communication channel between the host that sends the E-mail and the Office 365 mail server is encrypted.
In Office 365 based environment, when we want to address the Office 365 mail server using TLS, we will need to address the hostname – smtp.office365.com
PowerShell script and user credentials
In a scenario in which we need to use a PowerShell script that needs to use user credentials, we can choose one of three options:
1. Write the password as part of the PowerShell script
Add the password to the PowerShell script file – this is the simplest option but, from the security perspective, this is the worst option because the password kept in a text file in a non-encrypted format. (We will not review this option)
2. Provide user credentials when running the PowerShell script
In this scenario, the PowerShell script includes an “empty variable” that will contain the required user credentials.
When we run the PowerShell script, a pop out window will appear.
The person the execute the PowerShell script will need to provide the required credentials.
The information about the user credentials will be saved in encrypted format in the desktop RAM and will be “removed” when we close the PowerShell session.
From the security perspective, this is a better option because the credentials are encrypted.
The main disadvantage of this method is, that in case that we need to run the PowerShell automatically by using mechanisms such as windows task scheduler, we can not use this option because we need a “human element” that will need to provide the required credentials.
3. Saving the credentials in an encrypted file
In this method, we provide in advance the required user credentials by saving the credentials in an encrypted file that stored on the desktop from which we run the “Send E-mail PowerShell script.”
In this scenario, we implemented a two-phase procedure:
Phase 1 – saving the password using encrypted format
In this step, we use a PowerShell command that will encrypt the user credentials.
If we want to be more accurate, we will encrypt only the part of the “password,” and not the username.
We will need to provide PowerShell the “user password” and the PowerShell command will take this password, encrypt the password and save it in a text file.
In other words, the information is not readable by a human.
Phase 2 – creating to “Send a mail PowerShell script”, that will read the credentials
In this second phase, we create a “Send mail PowerShell script,” that will address the Exchange Online server using a secure communication channel – using TLS + provides user credentials.
We will need to provide the “Send mail PowerShell script” the path to the encrypted password file.
The “Send mail PowerShell script” will – access the encrypted password, read the information and decrypt the password.
General guideline and requirements for using the “Send mail PowerShell script
Before we run the “Send mail PowerShell script,” we will need to make sure that the following requirements are implemented:
1. PowerShell console and Set-ExecutionPolicy
By default, the PowerShell console doesn’t allow to run a PowerShell script.
In case that we didn’t use in the past the PowerShell console for – running PowerShell script, we will need to configure the PowerShell console to “allow” PowerShell script execution.
In case that you need instruction reading how to enable the PowerShell script execution, you can use the instruction in the previous article
2. Network Firewall and outbound communication
The communication channel to the Exchange Online server based on port 25.
We will need to verify that our network firewall, include a rule that enables our desktop to implement SMTP session (port 25) with the Office 365 mail server.
3. Dynamic vs. static IP Address
In case that you run the “Send E-mail PowerShell script” from a desktop that uses “dynamic Public IP address” such as Home network, the Office 365 mail server (Exchange Online) will not accept the communication requests.
You will need to use a host who located on a network that uses a static IP address for representing internal hosts.
Scenario description
To be able to demonstrate the way that we use “Send E-mail PowerShell script” for sending
E-mail via the Office 365 mail server (Exchange Online), we will use the following scenario:
Organization information
- Our organization public domain name is – o365info.com
- Our mail infrastructure is hosted at Office 365 (Exchange Online).
User credentials
The Office 365 recipients whom we will use his credential is –admin@o365info.com
Source sender and destination recipient
In our scenario, we will use the following recipients:
- The sender E-mail address is – admin@o365info.com
- The recipient E-mail address is – admin@o365info.com
Office 365 mail infrastructure
In the Office 365 environment, we use the hostname – smtp.office365.com for addressing the Office 365 mail server that provides an encrypted communication channel by using TLS.
- The communication port that we use is 25 (TLS)
Note: The use of the “Send E-mail PowerShell script” in non-Office 365 environment. The demonstration implemented by relating to Office 365 based environment. The procedure for running the “Send E-mail PowerShell script” can implement for any existing mail infrastructure. All you need to do is adjusting the required parameter such as the sender E-mail address, the mail server hostname, the port number and so on.
Method 1 – Send E-mail via Office 365 mail server using TLS session and authenticated session | Providing user credentials while running the script
In the following section, we will review the process of creating “Send mail PowerShell script.”
The main character of the current scenario is that we are going to provide the required user credentials in “real time” when the PowerShell script executes.
The “Send mail PowerShell script” that we create include the PowerShell command that will:
- Display “credentials windows” which we use for providing the required credentials.
- Initializes the authenticated TLS communication session with the Exchange Online server.
Task 1#2 – Create a “Send mail PowerShell script.”
The “Send mail PowerShell script” is created using the following PowerShell syntax:
$cred = Get-credential
Send-MailMessage –From <sender E-mail address> –To <recipient E-mail address> –Subject “<text>” –Body “Text>” -SmtpServer <Mail server> -Credential $cred
-UseSsl -Port <Port number>
In our scenario, we define a variable named “$cred”, that will serve as a container for the credentials that the user provides.
The “$cred” variable will call the PowerShell command – Get-credential which will be used for displaying the credentials pop out window.
In our scenario, we will use the PowerShell command syntax using the following parameters:
$cred = Get-credential
Send-MailMessage –From admin@o365info.com –To admin@o365info.com –Subject "Test Email" –Body "Test SMTP Relay Service" -SmtpServer smtp.office365.com -Credential $cred -UseSsl -Port 25
In the following screenshot, we can see an example of the PowerShell script.
Saving the PowerShell script file
The next step is – saving the text file as a PowerShell script.
We use notepad for creating the PowerShell script.
In our scenario, we will name the PowerShell script – Sendmail.ps1.
- In the section – Save as type” select the option – All Files (*.*).
- The additional recommended option is, to save the PowerShell script
using UTF-8
This is not a mandatory requirement, but, from my experience, when saving the PowerShell script using standard formats such as ANSI, we can experience a problem when we try to run the PowerShell script from the PowerShell console.
In our scenario, we save the PowerShell script in a folder named – script that located in C: drive.
Task 2#2 – Running the “Send mail PowerShell script”
We will run the PowerShell script from the PowerShell console, by using the following commands:
1. Access the PowerShell script by navigating to the path in which the PowerShell script located.
In our scenario, the PowerShell script is located in the C:\script folder.
Type the following command:
cd c:\script
2. Run the PowerShell script
To execute the PowerShell script, we can write the full name of the script – Sendmail.ps1 or use the PowerShell autocomplete feature.
For example, to call a PowerShell script we need to write the following characters – .\ , type the first letter of the PowerShell script (“s“) and hit the Tab key.
After “hitting” the TAB key, the PowerShell console will complete the rest of the PowerShell script name automatically.
In the following screenshot, we can see that when we try to run the Send mail PowerShell script” a “credentials window'” appear.
We will need to provide the required credentials and only then; the PowerShell script will continue to the phase of – sending the required E-mail.
In the following screenshot, we can see that the E-mail message successfully sent to the destination recipient.
Method 2 – Send E-mail via Office 365 mail server using TLS session and authenticated session | Using saved encrypted user credentials
In this scenario, we want to implement a solution, in which the PowerShell script will be able to access a predefined credential stored in a file.
The user credentials will be saved using an encrypted text file.
The tasks that we need to complete are as follows:
- Get the host name of the mail server, which we will address
As mentioned, in an Office 365 based environment, the host name that we use for creating authenticated TLS session is – smtp.office365.com
- Execute a PowerShell that will save our password in an encrypted file
- Create a PowerShell script, that will use the encrypted credentials and includes the required parameters such as the sender E-mail address, the recipient E-mail address, the mail server name, the mail server port number, the user credentials, etc.
- Running the “Send E-mail PowerShell script,” and verify that the E-mail successfully sent to the destination recipient.
Task 1#3 – using the PowerShell command for encrypting the text file that includes the password
To be able to encrypt the user credentials, we will use a combination of two PowerShell command
- Get the user password
We will use the PowerShell command:
- Read-Host -Prompt "" -AsSecureString
- The second PowerShell command will take the input from the previous command and will implement the following tasks:
- Create a new text file.
- Save the password to the text file.
- Encrypt the password.
We will use the PowerShell command:
- ConvertFrom-SecureString | Out-File "Path"
An example of the complete PowerShell command syntax is:
Read-Host -Prompt "<text>" -AsSecureString | ConvertFrom-SecureString | Out-File "Path"
In our scenario, we will use the PowerShell command with the following parameters:
- The text file will be named – credtxt
- The cred.txt will be created and saved in the following path – C:\users\administrator
Read-Host -Prompt "Enter your tenant password" -AsSecureString | ConvertFrom-SecureString | Out-File "C:\users\administrator\cred.txt"
In the following screenshot, we can see an example of using the command in the PowerShell console:
As a result, a prompt appears, asking as to type the password
In the following screenshot, we can see that the password saved to a file named cred.txt.
In the following screenshot, we can see the content of the encrypted text file that created.
Task 2#3 – Create a “Send mail PowerShell script”
In this phase, we create the “Send mail PowerShell script” that include two parts:
Part 1 – user credentials
In this part, we define three variables.
- $AdminName – the Office 365 UPN name of the user who use for the authentication before Exchange Online server.
- $Pass – a variable that containing the PowerShell command that access the encrypted password file and “fetch” the password.
- $Cred – a variable that will store the credentials that include the user name + password
Note: The variable names are just an arbitrary names, whom I use. You can define other variable names that will suit your needs.
The PowerShell command syntax that we use is:
$AdminName = "UPN Name"
$Pass = Get-Content "<Path>" | ConvertTo-SecureString
$Cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $AdminName, $Pass
In our scenario, we will use the PowerShell command with the following parameters:
$AdminName = "admin@o365info.com"
$Pass = Get-Content "C:\users\administrator\cred.txt" | ConvertTo-SecureString
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $AdminName, $Pas
Part 2 – the Send mail PowerShell commands
The second part of the “Send mail PowerShell script” include the PowerShell commands that will Initializes the authenticated TLS communication with the Exchange Online server.
The PowerShell command syntax that we use is:
Send-MailMessage –From <sender E-mail address> –To <recipient E-mail address> –Subject "<text>" –Body "Text>" -SmtpServer <Nail server> -Credential <credentials> -UseSsl -Port <Port number>
In our scenario, we will use the PowerShell command with the following parameters:
Send-MailMessage –From admin@o365info.com –To admin@o365info.com –Subject "Test Email" –Body "Test SMTP Relay Service" -SmtpServer smtp.office365.com -Credential $cred -UseSsl -Port 25
In the following screenshot, we can see an example to the “complete” send mail PowerShell script, which includes the two parts.
Lest focus on the “second part” which includes the PowerShell commands that will execute the authenticated TLS session with the Exchange Online server:
- From (number 1) – we will use the E-mail address – admin@o365info.com
for representing the sender E-mail address. - To (number 2) – we will use the E-mail address – admin@o365info.com
for representing the destination recipient E-mail address. - Subject (number 3) – this is the text of the E-mail subject.
- Body (number 4) – this is the text that will appear on the E-mail message “body”
- SmtpServer (number 5) – this is the host name or the IP address of the mail server that we want to address. In our scenario, we want to address the Exchange Online server as the “mail server.” server”. We will provide the host name smtp.office365.com
- Credentials (number 6) – this command uses the $cred variable that contains the user credentials (user name + password).
- UseSSL (number 7) – the PowerShell command that defines a TLS session instead the default SMTP session.
- Port (number 8) – this is the port number of the mail server that will “listen” to our communication requests. In the Office 365 environment, the Exchange Online will listen using port 25. Notice that we use port 25 for TLS communication, we don’t need to use the standard TLS port number such as 587.
Saving the PowerShell script file
Assuming that we add all the required PowerShell commands to the editor, the next step is – saving the text file as a PowerShell script.
In our scenario, we will name the PowerShell script – Sendmail-Encrypted.ps1
- In the section – Save as type” select the option – All Files (*.*).
- The additional recommended option is, to save the PowerShell script using UTF-8
This is not a mandatory requirement, but, from my experience, when saving the PowerShell script using standard formats such as ANSI, we can experience a problem when we try to run the PowerShell script from the PowerShell console.
In our scenario, we save the “Send E-mail PowerShell script” in the script folder, that we have created in drive C:
Task 3#3 – Running the “Send mail PowerShell script”
We will run the “Send mail PowerShell” from the PowerShell console, by using the following commands:
- Access the PowerShell script by navigating to the path in which the PowerShell script located.
In our scenario, the PowerShell script is located in the C:\script folder.
Type the following command:
cd c:\script
- Run the PowerShell script
To execute the PowerShell script, we can write the full name of the
script – Sendmail-Encrypted.ps1 or use the PowerShell autocomplete feature.
For example, to call a PowerShell script, we need to write the following characters – .\ , type the first letter of the PowerShell script (“s“) and hit the Tab key.
After “hitting” the TAB key, The PowerShell console will automatically complete the rest of the PowerShell script name by himself.
To verify if the E-mail message successfully sent, we will login to the admin mailbox using OWA mail client.
In the following screenshot, we can see that the E-mail successfully sent to the destination recipient
Running PowerShell script using windows task scheduler
In the following section, I would like to review the procedure, in which we can use the windows built in component – the windows task scheduler, for running a PowerShell script periodically.
In our scenario, we would like to use the “Send mail PowerShell script” that we learn how to create in the previous section so that the script will send E-mail daily.
To be able to fulfill this requirement, we will create a new window task scheduler task.
The scheduled task will run once a day, and execute the following task – “Call” the OS PowerShell component that will run the “Send E-mail PowerShell script.”
In the scenario in which we want to run a PowerShell script, we will need to “tell” the scheduled task what is the path in which we save our PowerShell script.
Creating a windows task scheduler task
- Start the Windows Task Scheduler
- Right click on the folder named – Task Scheduler Library
- Select the option – Create Basic Task…
- Write the name of the scheduled task
- In our scenario, we choose the option – Daily
- Specify the time in which the task will run
- Select the option – Start a program
- In the section named – “Program/script:” write – PowerShell
- In the section named – “Add arguments (optional):“, add the path to the PowerShell script
- Click Finish to save the scheduled task
In the following screenshot, we can see that a new task added to the existing task list
In case that you want to test the scheduled task that was created you can right click on the particular task and select the option – Run
The next article in the current series
Send E-mail to office 365 using PowerShell script | Part 1#2
Very detailed article. Much appreciated!!
HI,
Script works well !
The steps well documented!
I would be super if you could update your script for port 587
Thank you for this very helpful and detailed article!
When I run this script from my machine, i get this error :Send-MailMessage : The operation has timed out
When i run it from an Azure VM, it is working with no issues.
I added my ip (whatismyip) to connection filter — IP allow list , no luck