PowerShell script to send email with attachment

How to start PowerShell?

We are going to use the PowerShell console to send an email message with attachments. First, open the PowerShell window from the Start Menu. Type PowerShell and click on the app.
Screenshot: Start PowerShell from Start Menu

How to send email from PowerShell?

The following script allows you to send an email message using PowerShell. It uses, FROM and TO fields to set the sender and recipient, as well as the subject, body, attachment arguments to create an email message. An SMTP server, username and password are required for the PowerShell script to send email using an SMTP server.

Send-MailMessage -From "Bob <bob@example.com>" `
                 -To "Lee <lee.sanders@example.com>", `
                     "Zoe <zoe.dow@example.com>" `
                 -Subject "Sending the Attachment from PowerShell" `
                 -Body "The body of email goes here." `
                 -Attachment "invoice-001.pdf" `
                 -SmtpServer smtp.example.com `
                 -Port 587 `
                 -UseSsl `
                 -Credential (New-Object `
                   -TypeName System.Management.Automation.PSCredential `
                   -ArgumentList "Your-username-goes-here", `
                   (ConvertTo-SecureString `
                     -String "replace-this-with-your-password" `
                     -AsPlainText -Force))

How to test your script in the command line?

Just copy/paste the script into the PowerShell window you opened in the first step. But keep in mind that you need to adjust some command line arguments and switches. Otherwise the script will not work in your environment.
Screenshot: PowerShell email example

At least, change the following parameters to the values of your email:

  • From address
  • To address
  • SMTP server address and port number
  • SMTP username and password

If you don’t know which values to use for SMTP server and port, check this page for SMTP settings for popular email providers.

How to use PowerShell to send email from a single-line command?

If you look at the example above, you will notice the grave accent (backtick) characters at the end of each line. This is a PowerShell way to split one long command to multiple lines. If you want to use the command as a single line, copy/paste the following code:

Send-MailMessage -From "Bob <bob@example.com>" -To "Lee <lee.sanders@example.com>", "Zoe <zoe.dow@example.com>" -Subject "Sending the Attachment from PowerShell" -Body "The body of email goes here." -Attachment "invoice-001.pdf" -SmtpServer smtp.example.com -Port 587 -UseSsl -Credential (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "Your-username-goes-here", (ConvertTo-SecureString -String "replace-this-with-your-password" -AsPlainText -Force))

PowerShell · the send email function explained

As you noticed, we are using a PowerShell built-in function Send-MailMessage. In the PowerShell world such functions are called cmdlets. Here is an official documentation of PowerShell Email.

Argument Help
-From from address
-To one or more recipients
-Subject subject text
-Body email body plain text
-Attachment or -Attachments one or multiple attachments
-SmtpServer address or IP of the mail server
-Port port number, usually 587 or 465
-UseSsl switch to enable TLS or SSL
-Credential PSCredential object

A little bizarre part that sets SMTP server’s username and password is explained below. The PowerShell’s send email credentials require a PSCredential object, which we construct using a combo of commands that at the end creates the PSCredential object instance from the System.Management.Automation namespace.

Argument/Command Help
New-Object creates an object
-TypeName .NET framework class name
-ArgumentList array of arguments for the object constructor
ConvertTo-SecureString plain text to secure string*
-String input for the ConvertTo function
-AsPlainText  the input is plain text
-Force confirms that you are using a plain text password

* PSCredential class expects us to provide a secure password or string, but what we want is to pass a plain text string, thus we need to convert it.

PowerShell script to send HTML email

With a small change to the above script we can send rich formatted emails in the HTML format. It is easy! Just add a -BodyAsHtml switch, and you can start adding HTML tags in the body text. See the example below.

Send-MailMessage -From "Bob <bob@example.com>" `
                 -To "Lee <lee.sanders@example.com>", `
                     "Zoe <zoe.dow@example.com>" `
                 -Subject "Sending the Attachment from PowerShell" `
                 -Body "The text now can be <b>bold</b> or <i>italic</i>." `
                 -BodyAsHtml `
                 -Attachment "invoice-001.pdf" `
                 -SmtpServer smtp.example.com `
                 -Port 587 `
                 -UseSsl `
                 -Credential (New-Object `
                   -TypeName System.Management.Automation.PSCredential `
                   -ArgumentList "Your-username-goes-here", `
                   (ConvertTo-SecureString `
                     -String "replace-this-with-your-password" `
                     -AsPlainText -Force))

Notice that the body text contains HTML markup. There is an italic and bold text. As you can imagine, it will appear with a cursive font or as a thicker text than the surrounding text. Here is an HTML code:

The text now can be <b>bold</b> or <i>italic</i>.

And this is how it looks in the final email:
The text now can be bold or italic.

You can add other HTML tags too, for example, A, BR, DIV, FONT, H1, IMG, and much more. Ranadeep Bhuyan has compiled a list of allowed HTML tags in the email body.
But of course you need to test it out yourself, because email clients and the internet are evolving rapidly, and the things that work today, may not work at the time of reading this article.

Fine-tune the Send-MailMessage cmdlet

There are more command line arguments to adjust your email message:

  • -Bcc specifies the email address of a blind carbon copy. The address which will receive a copy of email but will not be listed as a recipient of the email message.
  • -Encoding specifies the character set for the email message. The default is UTF-8 without a Byte Order Mark or BOM. To send a plain text message, use -Encoding ASCII argument.
  • -Priority allows to set the priority of the email message. Use -Priority High, or -Priority Low to change the default (normal) priority.
Send-MailMessage -From "John <john@example.com>" `
                 -To "Linda <linda@example.com>"
                 -Priority High `
                 -Encoding ASCII `
                 -Subject "This is a plain text message" `
                 -Body "Notice the priority and encoding arguments..."

How to send email automatically from a PowerShell script?

The obvious choice is to use the Windows built-in Task Scheduler. Just use the “Start a program” action to start your PowerShell script. It does its job, if you need to start a task on a simple schedule, but if you need to react on local files or on remote files that are located on an FTP server, you may need to use the commercial solution.
Screenshot: Start a program from Windows Task Scheduler

To launch the cmdlet from Task Scheduler, you need to adjust your command:

  1. Copy the one-line command example I provided above.
  2. Use this syntax: PowerShell.exe -Command "&{ the_command_goes_here }"
  3. Make sure to change all double quotes ” to single quotes ‘

This is how it looks when the quotes are changed, and the command is ready to be launched from Scheduled Tasks or from the Windows command line:

PowerShell.exe -Command "&{ Send-MailMessage -From 'Bob <bob@example.com>' -To 'Lee <lee@example.com>' -Subject 'Sending the Attachment from Schedulet Tasks' -Body 'The body of email goes here.' -Attachment 'invoice-002.pdf' -SmtpServer smtp.example.com -Port 587 -UseSsl -Credential (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'Your-username-goes-here', (ConvertTo-SecureString -String 'replace-this-with-your-password' -AsPlainText -Force)) }"

In the “Start a program” action you must separate the command into two parts, the PowerShell app and the arguments. Just copy/paste the whole command argument into the small “Add arguments” box. And don’t forget to provide the path where your attachments are located.
Screenshot: Start a program from Windows Task Scheduler with arguments

Alternatives to Windows Task Scheduler

Is PowerShell script to send email deprecated?

As you may noticed the official Microsoft documentation article of the PowerShell script says:

The Send-MailMessage cmdlet is obsolete. This cmdlet does not guarantee secure connections to SMTP servers. While there is no immediate replacement available in PowerShell, we recommend you do not use Send-MailMessage.

You are not in the immediate danger if you are using the PowerShell script to send email automatically on a Local Area Network or LAN. Because no one is sniffing your local network traffic.
But if you are planning to use the PowerShell on the Internet to send out emails, I recommend to use the app called Command Line Email. It is a ready-to-use alternative, that is updated together with Windows Update.

How to automate emails with attachments, but without using scripts?

To use the automation without writing a single line of code, I recommend the intelligent automation solution called Automation Workshop. It is a Windows app that can automate any Windows tasks including email sending.

Screenshot: Automation Workshop Send Email Action

It is available as a Free to try version or a Free for non-commercial use edition. View the detailed step-by-step tutorials on email automation below. You will learn how to send automatic emails with attachments using a point-and-click user interface.

Is PowerShell a good tool for scripting and automation?

If you still prefer to use PowerShell instead of no-code solution Automation Workshop, the question remains: Is it good for automation?
If you are a programmer or software developer, and you can live with the fact that Microsoft sometimes breaks stuff (the Send-MailMessage cmdlet is obsolete and a fix is not available), then the answer is – probably.

Pros of using PowerShell:

  • It is mature – 14 years old scripting language.
  • It is open-source and cross-platform as of 2016.
  • It has reached version v7.1.2 and is still being actively developed.

Cons of using PowerShell:

  • It is not a very popular language. The TIOBE lists it as a number 50 with a very low usage of 0.21% as of Feb 25, 2021. If you are a PowerShell programmer yourself, this may not be a problem. But if you want to hire one, then its low usage may come at the cost of less available workforce.
  • It lacks error handling and logging capabilities that are present in no-code and low-code automation solutions. For example, the Log Manager of Automation Workshop.
  • Writing a program code is a long process, and there are always bugs. Industry average experience is about 1-25 errors per 1000 lines of code for delivered software. This a quote from the book called Code Complete that is written by Steve McConnell. On the other hand, automated tasks that are created using a no-code solution have less defects, because there is no code.

Credits and thanks goes to:

Do you still have unanswered PowerShell questions?

The best place to ask programming questions, including ones that relates to using PowerShell, is the StackOverflow website. As of 2021 they have more than 80,000 questions and answers related to the Microsoft cross-platform scripting tool.

Meet Febooti, Ltd. in many languages

We have started localizing our main website febooti.com, and your feedback is very welcome. We have begun with a few pages, and if everything goes well a lot more will follow. Internationalization and localization or i18n for short is not a trivial task. Besides translating just some sentences, there are very many differences between languages. For example: punctuation characters, spacing between words and their punctuation symbols, date/time formats, number formatting, various text lengths, etc. The last is particularly interesting, because the layout of a website or an app usually has some limited space for a particular navigation item, and it can not be easily stretched to fit the translation that is wider in some other languages.
Currently, we don’t have any translations for the right to left languages, but we are definitely looking in that direction. We have a lot of users from Arabic speaking countries, and that would benefit them greatly.
Here are some examples of already live translations:

Alternative to Solarwinds FTP Voyager JV (serv-u) automation of FTP, SFTP, and FTPS

FTP Voyager JV is an FTP client developed by Solarwinds Inc. It has some basic automation attempts using its built-in Task Scheduler, however as they write in their documentation, there are some severe limitations. Below are citations from the Solarwinds documentation:

  • it is designed to work with  “low to medium” volume sites;
  • it supports fewer than 100 file changes;
  • and total file changes of less than 1GB is expected;
  • it only works for single-direction (“one way”) synchronizations;
  • synchronization is not a very reliable (1-9 minutes desync);
  • there is no way to know, if your files have reached the server or client.

The alternative is Automation Workshop. It is an app for Windows that has very clean and easy to use user interface. You will be able to create FTP, SFTP, and FTPS synchronization tasks in minutes. You can even react on file changes either on server or client, and start the syncing process immediately. It includes Advanced Task Scheduler where you can create any schedule you can imagine. With the File & Folder Watcher trigger you can monitor any local or network folder, and with remote Watchers – SFTP, FTP, FTPS, WebDAV, and even Amazon AWS S3 directories in the Amazon Cloud.

Download a free trial now: start automating right away!
See it in action!

Automation Workshop v4.5 released

We heard your feedback and we’re taking action! We have added your long awaited subscription plans. Now you can split payments to smaller ones: monthly or quarterly.

The new subscriptions come with great benefits. Once subscribed, you will have free minor and major updates available without any additional fees. You can upgrade and downgrade anytime you want. Everything just works!

We also have deprecated OpenSSL libraries. From now Automation Workshop uses Windows built-in TLS/SSL solution, that guarantees that all security and feature updates are automatically included in the Windows Updates.

Security of communication channels are important for businesses, and we have introduced a setting to control the version of TLS/SSL used. You can now opt-in to use insecure and outdated SSLv3 for legacy systems, or to use industry standard TLS 1.2 to connect to modern systems in the most secure way possible.

Download the latest version today!

Automation Workshop v4.0 introduces FTP & Cloud actions

Automation Workshop 4th version is another major milestone that brings a completely redesigned user interface along with new cloud actions and triggers. As Windows 7 EOL is approaching rapidly, we have aligned the user experience to the new UI paradigm that matches Windows 10 and Windows Server 2016/2019 user experience. While the new interface looks very modern and gorgeous, it does not add significant overhead to the very small memory footprint Automation Workshop has. We have even improved some code, so the newest version require event less memory while running complex tasks.

We have crafted four new triggers that can monitor Amazon S3 file service or any FTP server, be it Linux or Windows based, with the latest security standards right out the box.

With our new FTP & Cloud action you can manipulate remote files in easy and secure manner. These actions are solid addition to Automation Workshop’s already existing comprehensive set of file and folder manipulation actions.

Desktop shortcut
We have heard your feedback! It is now possible to create a shortcut to the task on your desktop. Launch a task with a simple click on your desktop, without opening Automation Workshop every time you need to run a task.

As the Windows versions rapidly move on, we have also dropped support for .NET 2.0 and .NET 3.0 frameworks. Official support for Windows Vista and Windows Server 2008 R2 are also ended.

New Website
As you may already noticed, the febooti.com website has also been fully redesigned, it has more pleasant typeface and it is fully compatible with the latest mobile browsing standards.

Stay with us, the year of 2020 will bring many more new features!

View full list of changes. Order now or Download the latest version here.
Free version of Automation Workshop v4.0 will be available after two weeks.

Automation Workshop just passed 1,000,000 (one million) downloads

It was just four years ago when we launched freeware version of Automation Workshop and at that moment the download count of commercial version passed over 300,000 mark.

Today Automation Workshop passed one million downloads (Free+Commercial). That’s about 700,000 downloads in 4 years.

More than a million downloads
More than a million downloads

We are very excited about accelerated growth of our flagship product. It took more than 3 years to achieve 100,000 downloads. And our free software offering clearly expanded our user-base behind what we have initially planned. What now? Setting a new goal – 2,000,000 🙂

Automation Workshop v3.0.0 is available for download

Automation Workshop v3 actions

We have just released Automation Workshop v3.0.0 which introduces 18 new actions in three categories – addition to the File / Folder category, as well as brand new – Loops and Text categories. Long requested actions for text string manipulations and loops are finally there. Now it is possible to use custom named variables and tokens from Split text action. This release also focuses on many improvements and a few bug-fixes. Read detailed information in Release notes for v3.0.0.

Here is a screenshot from Split text action, that is very handy when extracting data from CSV (comma-separated values) files, or when need to get values embedded into filenames.

Split text actions into named tokens
Split text actions into named tokens

Some more highlights below…

Find / Replace test strings with Regular Expressions
Find / Replace test strings with Regular Expressions
Variable Wizard features a new Variables category
Variable Wizard features a new Variables category
A new task examples for latest actions
A new task examples for latest actions