Skip to main content

How to Send an Email from a Batch Script (via PowerShell)

A powerful feature for any automation script is the ability to send email notifications. You might want to get an alert when a long backup job is complete, receive a report on a script's daily run, or be notified of an error. The native Windows Batch environment (cmd.exe) has no built-in command to send email. It is not an email client and does not speak the necessary network protocols (like SMTP).

To solve this, the standard and most powerful method is to have your batch script call a helper utility that can send email. This guide will teach you the modern, recommended approach using the built-in PowerShell engine, which provides a single, powerful command to handle all your email needs.

The Challenge: No Native SENDMAIL Command

The batch command processor is a simple shell. It cannot natively create network connections to an SMTP (Simple Mail Transfer Protocol) server, which is the standard protocol for sending email. Any attempt to do this with pure batch commands would be impossibly complex and unreliable. Therefore, the only practical solution is to delegate the task to a more powerful tool.

PowerShell, which is included in all modern versions of Windows, has a dedicated, powerful cmdlet for this exact task: Send-MailMessage. This single command can handle everything from simple text emails to complex messages with HTML, attachments, and authentication.

Syntax: powershell -Command "Send-MailMessage -From 'sender@domain.com' -To 'recipient@domain.com' -Subject 'Subject' -Body 'Message Body' -SmtpServer 'smtp.server.com'"

This one-liner can be called directly from your batch script.

The PowerShell Command Explained

Let's break down the key parameters of the Send-MailMessage cmdlet:

ParameterDescription
-From(Required) The sender's email address.
-To(Required) The recipient's email address. Can be a comma-separated list for multiple recipients (e.g., 'to1@a.com','to2@b.com').
-Subject(Required) The subject line of the email.
-Body(Required) The main content of the email.
-SmtpServer(Required) The address of the SMTP mail server that will send the email. This is often provided by your ISP or email provider (e.g., smtp.gmail.com).
-Attachments(Optional) The full path to a file to attach.
-BodyAsHtml(Optional) A switch that tells PowerShell to interpret the -Body string as HTML.
-Credential(Optional) Used for SMTP servers that require a username and password.
-Port(Optional) The port for the SMTP server (e.g., 587 or 465 for secure servers).
-UseSsl(Optional) A switch to enable an SSL connection.

Basic Example: Sending a Simple Text Email

This script sends a basic notification. This example assumes you have access to an SMTP server that does not require authentication (common in corporate environments with an internal mail relay).

@ECHO OFF
SETLOCAL

REM --- Configuration ---
SET "FromAddress=batch-script@my-pc.local"
SET "ToAddress=admin@example.com"
SET "Subject=Automated Report"
SET "Body=This is an automated message from a batch script."
SET "SmtpServer=smtp.internal.lan"

ECHO --- Sending Email Notification ---
ECHO.

powershell -Command "Send-MailMessage -From '%FromAddress%' -To '%ToAddress%' -Subject '%Subject%' -Body '%Body%' -SmtpServer '%SmtpServer%'"

IF %ERRORLEVEL% EQU 0 (
ECHO [SUCCESS] Email sent successfully.
) ELSE (
ECHO [FAILURE] Failed to send email. Check SMTP server and firewall settings.
)

ENDLOCAL

Advanced Example: Using Authentication and Attachments

Most external SMTP servers (like Gmail or Outlook) require you to log in. This requires creating a credential object in PowerShell. This example is more complex but demonstrates the full power of the command.

@ECHO OFF
SETLOCAL

SET "FromAddress=myaccount@gmail.com"
SET "ToAddress=recipient@example.com"
SET "Subject=Backup Log Attached"
SET "Body=Please find the backup log attached."
SET "SmtpServer=smtp.gmail.com"
SET "SmtpPort=587"
SET "Attachment=C:\Logs\backup.log"

SET "Username=myaccount@gmail.com"
SET /P "Password=Enter password for %Username%: "

ECHO --- Sending Secure Email ---
powershell -Command ^
"$Cred = New-Object System.Management.Automation.PSCredential('%Username%', (ConvertTo-SecureString '%Password%' -AsPlainText -Force)); " ^
"Send-MailMessage -From '%FromAddress%' -To '%ToAddress%' -Subject '%Subject%' -Body '%Body%' -SmtpServer '%SmtpServer%' -Port %SmtpPort% -Credential $Cred -UseSsl -Attachments '%Attachment%'"

ECHO Done.
ENDLOCAL
note

This script prompts for the password, which is more secure than hardcoding it.

Common Pitfalls and How to Solve Them

  • "Unable to connect to the remote server": This is the most common error. It means your script could not reach the SMTP server.

    • Solution: Check for firewall issues. The SMTP ports (typically 25, 587, or 465) might be blocked. Also, double-check that the -SmtpServer address is correct.
  • Authentication Failure: If the SMTP server requires a username and password, a simple command will fail.

    • Solution: You must use the -Credential parameter as shown in the advanced example. For services like Gmail, you may need to generate an "App Password" instead of using your main account password.
  • Special Characters in Variables: If your -Body or -Subject contains characters like " or ', it can break the PowerShell command string.

    • Solution: For complex bodies, it's more robust to write the body to a temporary file and use the -Body (Get-Content 'body.txt') syntax in PowerShell.

Practical Example: A "Task Complete" Notification Script

This script runs a simulated backup, determines if it succeeded or failed, and sends a notification email with the result.

@ECHO OFF
SETLOCAL

REM --- Run a simulated task ---
ECHO Running backup...
REM This is just an example command.
DIR C:\Windows > NUL
SET "TaskStatus=%ERRORLEVEL%"

REM --- Prepare the email content based on the result ---
IF %TaskStatus% EQU 0 (
SET "Subject=SUCCESS: Daily Backup Completed"
SET "Body=The daily backup task completed successfully on %COMPUTERNAME% at %TIME%."
) ELSE (
SET "Subject=FAILURE: Daily Backup FAILED"
SET "Body=The daily backup task FAILED on %COMPUTERNAME% with errorlevel %TaskStatus%."
)

ECHO Sending status email...
powershell -Command "Send-MailMessage -From 'backups@corp.net' -To 'admins@corp.net' -Subject '%Subject%' -Body '%Body%' -SmtpServer 'smtp.corp.net'"

ENDLOCAL

Conclusion

While batch script cannot send email by itself, it can act as a perfect controller for the powerful PowerShell Send-MailMessage cmdlet.

  • This hybrid approach is the modern and highly recommended method for adding email capabilities to your scripts.
  • The most critical requirement is having access to an SMTP server and knowing its address.
  • For secure servers, you must provide credentials using the -Credential parameter.

By leveraging PowerShell, you can easily create sophisticated batch scripts that provide automated reports, alerts, and notifications.