In this post, I will talk about commonly used parameters of the Send-MailMessage PowerShell cmdlet and a few examples of how to use them.

Update: We have a new post that explains how to send an email with PowerShell in more detail.

Most of the automations that system administrators write generally involve sending email at some point in the script, whether to report errors or to send consolidated output. Given the high usage of this functionality, I would like to describe some of the common use cases of the Send-MailMessage cmdlet (a new cmdlet introduced in PowerShell 2.0).

Send-MailMessage parameters ^

For any cmdlet, we first need to understand the parameters that we should pass to it to get the desired functionality/output. Like any other cmdlet, Send-MailMessage also has both mandatory and optional parameters. I will talk about the ones that are used most.

-FROM: Every email needs a “from” address. Without this, email cannot be sent. Though it is a required parameter, the email ID doesn’t necessarily have to be a valid one. You can use nothing@nothing.com and the cmdlet will still work.

-TO: This is also a mandatory parameter. You can supply a single or multiple email addresses, and you can also specify the name associated with the email address (for example, -To “Sitaram Pamarthi <sitaram @4sysops.com>”).

-SMTPServer: You need to provide the name of the SMTP server through which you want to send the email. If you are in doubt, ask your email administrator for the server to use. If this parameter is not specified, PowerShell tries to pick the value from the $PSEmailServer preference variable, if this variable is set.

-CC and -BCC: You know what they are. If you would like to CC or BCC somebody in the email, pass their email addresses to these parameters.

-Attachments: This parameter takes the full path of the file(s) that you want to attach to the email.

-Subject: This is a simple string that represents the subject of your email.

-Body: This string specifies the body of your email message.

Send-MailMessage examples ^

We have seen some of the frequently used parameters. Now let me take you through some examples, which will come in handy when writing your scripts.

Send email to one recipient

Send-MailMessage -To “Manager 1 <Manager1@xyz.com>" -From “Reports Admin <Reportadmin@xyx.com>" -SMTPServer smtp1.xyz.com -Subject “Daily report” -Body “This is a daily report of server uptime”

Send email to multiple recipients in To and CC

Send-MailMessage -To “Manager 1 <Manager1@xyz.com>", “Manager2 <Manager2@xyz.com>" -CC “Manager 3 <Manager3@xyz.com>”, “Manager4 <Manager4@xyz.com>” -From “Reports Admin <Reportadmin@xyx.com>" -SMTPServer smtp1.xyz.com -Subject “Daily report sent to multiple managers” -Body “This is a daily report of servers uptime”

Send email to one recipient with an attachment

Send-MailMessage -To “Manager 1 <Manager1@xyz.com>" -From “Reports Admin <Reportadmin@xyx.com>" -SMTPServer smtp1.xyz.com -Subject “Daily report” -Body “Attached file has uptime details of all servers” -Attachments “c:\temp\uptime-report.txt”

Send email to one recipient with multiple attachments

Send-MailMessage -To “Manager 1 <Manager1@xyz.com>" -From “Reports Admin <Reportadmin@xyx.com>" -SMTPServer smtp1.xyz.com -Subject “Daily report” -Body “Attached file has uptime details of all servers” -Attachments “c:\temp\server1-uptime-report.txt”, “c:\temp\server2-uptime-report.txt”

Send email via an SMTP relay server that requires authentication

Send-MailMessage -To “Manager 1 <Manager1@xyz.com>" -From “Reports Admin <Reportadmin@xyx.com>" -SMTPServer smtp1.xyz.com -Credentials (Get-Credential) -Subject “Daily report” -Body “This is a daily report of servers uptime”

The above command will prompt for the credentials and send the email after the credentials are validated.

Send status of all services in a server as an email

Send-MailMessage -To “Manager 1 <Manager1@xyz.com>" -From “Reports Admin <Reportadmin@xyx.com>" -SMTPServer smtp1.xyz.com -Subject “Services status of Server1” -Body (Get-Service -ComputerName Server1 | Out-String)

Send high-priority email

Send-MailMessage -To “Manager 1 <Manager1@xyz.com>" -From “Reports Admin <Reportadmin@xyx.com>" -SMTPServer smtp1.xyz.com -Subject “Daily report” -Body “This is a daily report of servers uptime” -Priority High

These use cases are just a few examples. You can do much more with this cmdlet, such as send emails over TLS channels (-UseSSL parameter) or request delivery receipts for emails that you send (-DeliveryNotificationOption parameter).

To obtain help for this cmdlet, type the following command in your PowerShell window:

Subscribe to 4sysops newsletter!

Get-Help Send-MailMessage -Detailed

Update: We have a new post that explains how to send an email with PowerShell in more detail.

+8
avatar
29 Comments
  1. Karthik 5 years ago

    How do I send mail when I do not know the SMTP server host, but know only the LDAP host name

    0

    • Without SMTP server you can't send an email.

      +1

    • Huy M Le 4 years ago

      If you have an email account from anywhere then you can send email.

      To find out the SMTP server you just go to MXtoolbox.com,

      from there enter in you domain name (ie mysmtp.com) where your email is (myname@mysmtp.com).  This will return you the  MX server record (SMTP).  From there you just copy that address as your SMTP server.  You may have to use (credential) option on the PowerShell Command to specify smtp server and have to input your username/password (email + password).  That should work fine.

      0

  2. addison 5 years ago

    Thank you.  This was very helpful.

    0

  3. Sam 5 years ago

    How do I ensure that the from name field that the recipient sees is customized as per the value I provided.
    I have a requirement where I send emails to multiple people but I don't want them to reply to me and spam my mailbox. I tried using 'donotreply@mydomain.com' in the from field but it still ends up with the recipient with my actual email id.

    I have powershell 4 and our smtp server is google (enterprise gmail service).

    0

    • Try another SMTP server. I guess Google's mail server replaces the contents of the from field with your email address. If you ask, they might tell you that they do this to prevent spamming. In reality they want you to pay for another mailbox.

      0

  4. Rick 5 years ago

    I am trying to add a internet header (self-created one, call it x-abc) how would I code that in powershell in the send-mailmessage?

    0

  5. Rick 5 years ago

    This is Rick, what I am trying to do is to add a custom x-header into an outgoing e-mail using the send-mailmessage. The e-mail will be sent via the task scheduler in Win 2012.

    0

  6. Shalaka 4 years ago

    hi, I am using a variable that would have  the list of files to be attached (dynamically generated bases on some other logic) that I want to send to the -Attachements...but it does not seem to work.

    My variable:

    $attachment = "C:\......pdf","C:\.....pdf"

    Then in the send mail I have

    Send-MailMessage `
    -To $emailarray `
    -From ..
    -SmtpServer ...
    -Subject "$subject" `
    -Body "$body" `
    -Attachments $attachment `

    0

  7. Eman 4 years ago

    how can i select 2 multiple random attachments from a folder?

    0

  8. Mike D 4 years ago

    Instead of listing each email address in the -To parameter, is it possible to set this up to read a .txt file of email addresses, or even better a .csv list of emails?

    0

    • If your CSV file looks like this:

      name, email
      YourName1, YourName1@mail.com
      YourName2, YourName2@mail.com

      you could use a script that looks like this:

      $MailAdresses = Import-Csv mail.csv
      ForEach ($mail in $MailAdresses){
        $email = $mail.email
        $name = $mail.name
        $to = "$name <$email>"
        Send-MailMessage -to $to -From "me@you.com"-Body "test" -Subject "test" -SmtpServer "mailout.you.com"
      }
      +1

  9. Terry Bennett 3 years ago

    how can I do error checking on Send-MailMessage?

    IF the message was sent successfully, continue, otherwise, do it again, etc, etc.

    Thanks,

    T

     

    0

  10. kumaraswamy 3 years ago

    while sending  mail through powershell , im getting below error:

    Send-MailMessage : The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.1 Client was not authenticated

     

    0

  11. Chris 2 years ago

    I'm writing a script that does 3 things.

    1. Scans the D:\ drive for viruses
    2.  Scans the D:\  drive for medical records
    3.  Sends out an email with the same subject and slightly different body but the recipient will change. How can I specify a different recipient when running the script
    4.  Bonus points if you also can share how I'd be able to edit the body of the email directly in the shell session when running the script. (just the greeting of the email will change for example email #1 starts off with Dear John and email #2 starts off with Dear Jane)

    Regards,

    Chris

    0

  12. tika 2 years ago

    Hi, I'm trying to send a mail-template file as the body of the message.  How can I do that?

    thanks,

    m:o)

    0

    • You cant do that. The Body parameter only accepts string. You can only create a HTML code and put it as the Body with -BodyAsHTML parameter. File can be only added to attachment with -Attachment parameter.

      0

  13. Cookie 2 years ago

    I had an issue using a variable which contained multiple addresses. Using -To "email1@test.com","email2@test.com" works, but when these where in a variable it didn't work (-To $To)

    I solved it using:

    [string[]]$To=[system.String]::Join(",", $To)

    where $To contains multiple addresses.

    In the send-mailmessage command use -To ($To -split ',')

    You can also use this for Cc and if you want to add multiple attachments from a variable to your email

    +1

  14. Shivam Sharma 8 months ago

    I want to print the output of a script via mail using Send-MailMessage :

    ./demo.ps1 | Send-MailMessage -from xyz -to xyz -smtpserver xyz -port xyz ;

    But it is not getting the output of the script to mail. Any suugestions ?

    0

    • Leos Marek (Rank: 4)
      8 months ago

      If you check the help for Send-MailMessage you will find out that the only attribute that accepts pipeline input is Attachment. So your script would need to produce a file.
      Also, your missing Subject parameter.

      0

  15. Adam 7 months ago

    1. this is so much easier to do on AIX and other POSIX compliant systems..... sigh windows....
    2. I am trying to write a send-mailmessage rubber stamp script that can accept variables and only use what's there, and since I cant use $null ... for some reason... i have to come up with something else

    $To = $args[0]
    $Subject = $args[1]
    $Body = $args[2]
    $Attachments = $args[3]
    
    $sendString = '-from user@domain.com -to $To -Subject $Subject -smtpserver REDACTED -body $Body -Attachments $Attachments'
    
    if ( $Attachments -eq 'noAttachment' ) {$sendString = '-from user@domain.com -to $To -Subject $Subject -smtpserver REDACTED -body $Body'}
    
    send-mailmessage $sendString

    But when I run it, I just get a prompt asking me for a From value, so while I know my sendString variable is populated, it's not expanding in a way that send-mailmessage can read it... why?

    +1
    avatar
    • Leos Marek (Rank: 4)
      7 months ago

      You are using
      $To = $args[0]

      but the $args variable is not defined anywere, thats why.

      0

  16. Olivier 7 months ago

    Here my version
    - Using Param seciton as a function : with this, i can run the script with the default parameters value or run script and and parameter with specific value
    - Param section is on the beginning on the script. No need to read all the script.
    - Mail could be txt mail or html mail;, you can choose by passing the swith -html
    - Using Internal csss as a variable. Easy to customize to have a more beautiful mail
    - Using Attachment and Data collected in the main script. PS gathered object
    - Using splat with the Send-MailMessage cmdlet. More human readable.

    This is just a Just a sample. Feel free to customize for your need.

    [CmdletBinding()]
    #region param
    Param
        (
        # Subjet for the report mail
        [Parameter()]
        [String]
        $Subjet = "This is the daily report on $(Get-Date -Format "MM-dd-yyyy")",
        
        # Mail sender
        [Parameter()]
        [String]
        $From  = "MyAccount@mydomain.com",
    
        # Recipient to send report by mail
        [Parameter()]
        [String[]]
        $To =  @("Copyto@Mydomain.com","Another@other.com"),
        
        # Copy recipient to send report by mail
        [Parameter()]
        [String[]]
        $cc =  "Copyto@Mydomain.com",
    
        # Smtp server used to send report by mail
        [String]
        $smtpserver = "Mysmtp@mydomain.com", 
    
        # Html (switch) : Use html body if passed - Default value $false (txt mail)
        [Switch]
        $html = $false
        )
    #endregion param
    
    #region Internal css for html mail
    $Header = @"
    
    
    
    TABLE { width: 100%; table-layout: fixed; border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse; }
    TH { border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED; }
    TD { border-width: 1px; padding: 3px; border-style: solid; border-color: black; }
    column-count: 4;
    column-gap: 40px;
    
    
    
    "@
    #endregion Internal css for html mail
    
    #region execute
    # do this do that ... including populate a $result var and $Attachment
    #endregion execute
    
    #region prepare mail and sending
    if (-not $html) 
    {
    # send mail (Txt mail)
    $Body = @"
    below the table of daily results. See also the attachment file
    $Result
    
    Regards
    The Admin Team
    "@
    
    $MailParams = @{
     From  = "MyAccount@mydomain.com"
     To = $to 
     cc = $cc
     Subject = $Subject 
     Smtpserver = $smtpserver
     Body = $Body 
     Attachments = $Attachment
     }
    Send-MailMessage @MailParams
    }
    else 
        {
        # send mail (html)
    $BeginningMail = @"
     below the table of daily results. 
     See also the attachment file 
    "@
    # $Result is an object - convert it to html as fragment
    $result = $result | ConvertTo-Html -Fragment
    # ending Mail and closing body and html tag
    $MailEnd = @"
    Regards
    The Admin Team
    
    
    "@
    # Join all fragments
    $Htmlbody = $Header + $BeginningMail + $Result + $MailEnd
    
    $MailParams = @{
     From  = "MyAccount@mydomain.com"
     To = $to 
     cc = $cc
     Subject = $Subject 
     Smtpserver = $smtpserver
     BodyAsHtml = $true
     Body = $Htmlbody
    
     Attachments = $Attachment
     }
    Send-MailMessage @MailParams 
        }
    #endregion prepare mail and sendinga

    Regards
    Olivier

    0

  17. Assuming this is an actual script file, it would be easier to convert it to a "function" script. Everything in powershell is an object, just as everything in *nix is a file.

    [cmdletbinding()]
    param(
        [parameter(position = 0, Mandatory)]
        [string]$To,
    
        [parameter(position = 1, Mandatory)]
        [string]$Subject,
    
        [parameter(position = 2, Mandatory)]
        [string]$Body,
    
        [parameter(position = 3)]
        [string[]]$Attachment,
    
        [parameter(position = 4)]
        [string]$From = user@domain.com
    )
     
    $MailSplat = @{
        From = $From
        To = $To
        Subject = $Subject
        Body = $Body
        SmtpServer = 
    }
    if ($Attachment) {
        $MailSplat.Attachments = $Attachment
    }
    Send-MailMessage @MailSplat
    
    

    Save that as a file, and then just use the file with your command line arguments. The nice thing is that since it is defined as a function, you can also tab-complete the parameters.. i.e. .type in the name of the file name, a hyphen and hit 'Tab' , and the next available parameter pops up.

    The 'From' address can be any email address, but you are correct, it can't be blank or null.

    David F.

    0

  18. Joe 1 month ago

    Hello,
    I have a file that we are monitoring via PowerShell. If the file exceeds 200KB, then email. We are running this script via Windows Task Scheduler on a Windows Server. Is there a way to limit one email per day? The schedule runs every hour M-F 8am-5PM. We want the initial email to be sent, but not repeated to flood our inboxes.

    If 200KB is true > send email > pause/sleep for Xhrs.

    TIA,
    Joe

    0

  19. Sure.. you just need to store a reference value of when it was run with a daily check.
    So, you'd set up your check script for the size.. Code would be something like:

    $LastUpdateParams = @{
        path = HKLM:\Software\MyCompany\FileSizeCheck
        name = 'LastUpdateCheck'
    }
    [datetime]$LastUpdateCheck = Get-ItemProperty @LastUpdateParams
    if ($LastUpdateCheck -lt ( [datetime]::today ) ) {
        if ($CheckedFileSize -gt (200*1kb) ) {
           $WarningEmailParams = @{
               To = 'someemail@domain.local'
                From = 'FileSizeMonitor@domain.local'
                Subject = 'File {0} is currently at {1} size' -f $file.basename, $file.length/1KB
                Body = 'the file got too big'
            }
            Send-WarningEmail @WarningEmailParams
            $LastUpdateParams['Value'] = [datetime]::Now.ToString()
            $LastUpdateParams['Type'] = 'string'
            Set-ItemProperty @LastUpdateParams)
    }
    

    And rather than having the script sleep, I would modify the scheduled task to start at 8am and repeat every hour for 9 hours, and run the whole thing daily.

    David F.

    0

Leave a reply

Please enclose code in pre tags

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2021

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account