PowerShell: Send Mails with Attachments Using Office 365 and Gmail SMTP Server
Introduction
We have the capability to send mails from PowerShell. We can either send body as text or even as attachments in the mail. In order to facilitate the mail sending functionality we can make use of the various SMTP Servers available. In this demo we will see how to make use of Office 365 SMTP Servers to relay mails to business users. As part of the walk through we will see how to send plain text as mail body.
Prerequisite
In the demo, we will be reading JSON data from a REST service and we will be using Office 365 SMTP Server to relay the mail to the business users. Before heading over to the mail sending functionality let’s have a look at the REST Service that we will be using for the demo.
REST Web Service
Though we can create a custom REST service, for the time being, we can try out an already existing one. We will be making use of the Free RESTful web services available here which we will consume from PowerShell. We shall make use of the specific REST web service that gets the states and territories of the US.
The REST end point that we will consume is,
http://services.groupkt.com/state/get/USA/all
PowerShell Version 3.0
We are using the cmdlet ‘Invoke-WebRequest’, which was introduced in V3.0, to invoke REST Web service and get data from the web. So we have to ensure that the system has PowerShell version 3.0 or above. We can check the version by running the below command.
(Get-Host).Version
Invoke REST Web Service from PowerShell
REST web service endpoint can be invoked from PowerShell using the ‘Invoke-WebRequest’ cmdlet. Once we have the returned data, it will be in JSON format but to work with it we have to convert it to PowerShell object. The ConvertFrom-Json cmdlet will be used to convert the JavaScript Object Notation (JSON) formatted string to a custom PSCustomObject object that has a property for each field in the JSON string. Similarly, to generate a JSON string from any object we can use the ConvertTo-Json cmdlet.
Since the properties (country,capital,largest_city) are stored in the ‘RestResponse’ and ‘result’ property as embedded objects, we need to expand those properties using ‘-expand’ attribute and then choose the required properties from the embedded object. Once the JSON data has been retrieved, we will use ‘ConvertFrom-Json’ to convert the data from JSON to PowerShell Custom Objects
Invoking the Web Request and retrieving the required properties after running the ConvertFrom-JSON command will fetch us the below results,
Code :
$request = 'http://services.groupkt.com/state/get/USA/all'
$result = Invoke-WebRequest $request
$JSONResult = $result | ConvertFrom-Json | select -expand RestResponse | select -expand result
$JSONResult | Select country,capital,largest_city| Sort-Object capital
Convert data to HTML
In order to send the above table as mail body, we will convert it to HTML using the ConvertTo-HTML command.
- $Body = $JSONResult | Select country,name,capital,largest_city| Sort-Object name | ConvertTo-HTML
Mail from PowerShell using Office 365 SMTP
In order to send an email from PowerShell, we will need to specify an SMTP Server. We will be using Office 365 SMTP to relay the mails. We will have to fill out couple of parameters before triggering the ‘Send-MailMessage’ command which will relay the email.
- $SmtpServer = 'smtp.office365.com' – This is the address of the Office 365 SMTP server we will be using.
- $SmtpUser = 'Priyaranjan@SharePointChronicle.com' – Specify your Office 365 User ID
- $smtpPassword = ‘<Input Office 365 Password Here>’ – Specify your Office 365 Password
- $MailtTo = 'kspriyaranjan@gmail.com' – Specify the users to which the mails should be sent
- $MailFrom = 'Priyaranjan@SharePointChronicle.com' – Specify the Source Email ID
- $MailSubject = "Test using $SmtpServer" – This is the Mail Subject line
Finally, create a credential object using the User name and the password we have entered above. Since we are using Office 365 SMTP server, we have specified the related credentials. If you are using Gmail SMTP, make sure that you use Gmail credentials.
*$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SmtpUser, $($smtpPassword | ConvertTo-SecureString -AsPlainText -Force) *
Ensure that the credentials are correct else we will get the above error. Thus we have set up the parameters. Now we can call the Send-MailMessage command to send the mail to users as shown below :
Send-MailMessage -To "$MailtTo" -from "$MailFrom" -Subject $MailSubject -Body "$Body" -SmtpServer $SmtpServer -BodyAsHtml -UseSsl -Credential $Credentials
Full Code :
$request = 'http://services.groupkt.com/state/get/USA/all'
$result = Invoke-WebRequest $request -UseBasicParsing
$JSONResult = $result | ConvertFrom-Json | select -expand RestResponse | select -expand result
$Body = $JSONResult | Select country,name,capital,largest_city| Sort-Object name | ConvertTo-HTML
$SmtpServer = 'smtp.office365.com'
$SmtpUser = 'Priyaranjan@SharePointChronicle.com'
$smtpPassword = ‘<Input Office 365 Password Here>’
$MailtTo = 'kspriyaranjan@gmail.com'
$MailFrom = 'Priyaranjan@SharePointChronicle.com'
$MailSubject = "Test using $SmtpServer"
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SmtpUser, $($smtpPassword | ConvertTo-SecureString -AsPlainText -Force)
Send-MailMessage -To "$MailtTo" -from "$MailFrom" -Subject $MailSubject -Body "$Body" -SmtpServer $SmtpServer -BodyAsHtml -UseSsl -Credential $Credentials
write-Output "Custom Message : REST Service JSON Data parsed and Email Sent to Business Users"
Let's save the above code to a ps1 file and run it from the console.
We can see that the mail has been triggered and has reached the inbox.
Thus, we saw how to send mails from PowerShell using Office 365 SMTP Server. Now lets see how to do the same using Gmail SMTP Server.
Mail from PowerShell using Gmail SMTP
In order to send an E-mail from PowerShell, we will need to specify SMTP Server. We will be using Gmail SMTP to relay the mails. We will have to fill out couple of parameters before triggering the ‘Send-MailMessage’ command, which will relay the email.
- $SmtpServer = 'smtp.gmail.com' – This is the address of Gmail SMTP Server, which we will be using.
- $SmtpUser = ‘kspriyaranjan@gmail.com’ – Specify your Gmail User ID.
- $smtpPassword = ‘<Input Gmail Account Password Here>’ – Specify your Gmail account password.
- $MailtTo = ‘priyaranjan.ks@hotmail.com ' – Specify the users to which the mails should be sent.
- $MailFrom = ‘kspriyaranjan@gmail.com’ – Specify the source Email ID.
- $MailSubject = "Test using $SmtpServer" – This is the mail subject line.
Finally, create a credential object, using the user name and the password, which we have entered above.
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SmtpUser, $($smtpPassword | ConvertTo-SecureString -AsPlainText -Force)
Ensure that the credentials are correct, else we will get the error given above. Thus, we have set up the parameters. Now, we can call the Send-MailMessage command to send the mail to the users, as shown below:
- Send-MailMessage -To "$MailtTo" -from "$MailFrom" -Subject $MailSubject -Body "$Body" -SmtpServer $SmtpServer -BodyAsHtml -UseSsl -Credential $Credentials
Full code:
$request = 'http://services.groupkt.com/state/get/USA/all'
$result = Invoke-WebRequest $request -UseBasicParsing
$JSONResult = $result | ConvertFrom-Json | select -expand RestResponse | select -expand result
$Body = $JSONResult | Select country,name,capital,largest_city| Sort-Object name | ConvertTo-HTML
$SmtpServer = 'smtp.gmail.com'
$SmtpUser = 'kspriyaranjan@gmail.com'
$smtpPassword = '<Input Gmail Account Password Here>'
$MailtTo = 'priyaranjan.ks@hotmail.com'
$MailFrom = 'kspriyaranjan@gmail.com'
$MailSubject = "Test using $SmtpServer"
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SmtpUser, $($smtpPassword | ConvertTo-SecureString -AsPlainText -Force)
Send-MailMessage -To "$MailtTo" -from "$MailFrom" -Subject $MailSubject -Body "$Body" -SmtpServer $SmtpServer -BodyAsHtml -UseSsl -Credential $Credentials
write-Output "Custom Message : REST Service JSON data, which is parsed and an Email is sent to the business users.
Send files as the attachments
We can send the files as attachment, while sending the mail from PowerShell. This is done by adding an extra parameter -Attachment’ to the Send-MailMessage command. In addition to the mail body, we can specify the file location of the attachment file, which has to be sent along with the mail. In the code block given below, we are using Gmail relay Server to relay the mail, which contains the file located at the local machine. This attachment location is specified directly in the ‘Send-MailMessage’ command, using the ‘Attachment’ parameter.
Attachment Sending code is given below.
$Body = "Sample Email Body"
$SmtpServer = 'smtp.gmail.com'
$SmtpUser = 'kspriyaranjan@gmail.com'
$smtpPassword = '<Input Gmail Account Password Here>'
$MailtTo = 'priyaranjan.ks@hotmail.com'
$MailFrom = 'kspriyaranjan@gmail.com'
$MailSubject = "Testing Mail Attachments using $SmtpServer"
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SmtpUser, $($smtpPassword |
ConvertTo-SecureString -AsPlainText -Force)
Send-MailMessage -To "$MailtTo" -from "$MailFrom" -Subject $MailSubject -Body "$Body" -Attachments "C:\PS\SampleAttachment.txt" -SmtpServer $SmtpServer -BodyAsHtml -UseSsl -Credential $Credentials
write-Output "Custom Message : Attachment Email Sent to Business Users"
We can save the code given above to a PS1 file and run it from the command line, as shown below,
Heading over to the mail box, we can see that the mail has been delivered with the specified attachment file.
Summary
Thus, we saw how to send the mails from PowerShell, using Office 365/Gmail SMTP Server and also saw how to send the files as the attachments, using PowerShell.