Exchange: Automating a Welcome Email to New Users

Since Exchange 2010, it has been possible to use Scripting Agents to perform additional checks/processing when certain cmdlets are run.  This feature can be used to automatically send an email to welcome new users.  An overview of scripting agents and how they work can be found on Technet.

To send an email when a new mailbox is created, we need to respond to New-Mailbox or Enable-Mailbox (New-Mailbox is used when there is no existing AD account, and Enable-Mailbox is used when an existing AD user is mail-enabled).  Attached you'll find a sample Scripting Agent that will respond to both cmdlets, obtain the related mailbox/AD object, and use this information to send a personalised welcome email to the new mail user.

To create the personalised message, the easiest way is to write it using Outlook, then save as HTML.  In the sample agent, I've included code that will replace any occurrence of #UserFirstName# in the welcome message with the actual first name of the user (as read from Active Directory).  This can be extended as needed to include other fields.  If you have any images in the message, then there are some additional steps to take. When the message is saved, you'll find the html file, and then a folder of the same name containing any images (and a few other files, most likely, but these we can ignore).  Both the script and the welcome message need to be modified to be able to send these images.  The steps are as follows:

In the script, go to the part commented "Add any linked resource (e.g. images)".  In the sample script, you'll just find one image (the Microsoft logo, of course!).  For each image, you need to load it as a linked resource and add it to the list.  To make editing the HTML file simpler, set the ContentId to the filename (no path, just the filename).  The ContentType needs to be set to the correct MIME type for the image (e.g. image/jpeg, image/png, etc.).  The image needs to be available to the Exchange server at the given path when it is loaded - so it is usually best to put it on the machine somewhere.  For every image, you'll have four lines in the script to load it into the message:

        $image = New-Object System.Net.Mail.LinkedResource("C:\WelcomeMessage\image001.png")
        $image.ContentId = "image001.png"
        $image.ContentType = "image/png"
The above lines add the image as an attachment to the message, and define it as a linked resource with a specific ContentId.  The next step is to update the message HTML so that the image references point to the correct attachment (which is done by referencing the ContentId of the image).  So, you need to open the html file in your favourite text editor (Notepad is fine for this, though Notepad++ adds syntax highlighting which makes the HTML much easier to follow).  When it is open, do the following for each image in the document:

  • Search for the image filename (e.g. <CTRL><F>, then search image001.png)
  • For each instance of the image (i.e. if the document has the same image repeated, you'll have to do this for each occurrence), you will find two tags.  One is the standard <img> tag, but just before this, in an HTML comment, you'll also find a <v:imagedata> tag (this is used by Word).
  • In both tags (the Word tag and the img tag), replace the src attribute value with cid:contentId (where contentId is the filename, assuming that is what you used).  As an example:
    <v:imagedata src="Welcome_files/image001.png" o:title="MSFT_logo"/>
    is replaced by
    <v:imagedata src="cid:image001.png" o:title="MSFT_logo"/>

    <img width=129 height=43 src="Welcome_files/image001.png" alt="MSFT_logo" v:shapes="Picture_x0020_1">
    is replaced by
    <img width=129 height=43 src="cid:image001.png" alt="MSFT_logo" v:shapes="Picture_x0020_1">

  • Repeat the above process for all images.
  • Save the modified HTML.

Now the HTML is updated, all you need to do it copy it and the images to the folder specified in the scripting agent (for this example, I copied all the files to c:\WelcomeMessage - note that this needs to be present on each Exchange server that the agent is deployed on).  The welcome message preparation is then complete.

Additional scripting agent code needs to be updated to work with your environment.  The things you'll need to check are SMTP server (the script using System.Net.Mail, so sends the message using SMTP), from address, and message subject.  Once these changes have been made, the ScriptingAgentConfig.xml needs to be placed on each Exchange server in the folder C:\Program Files\Microsoft\Exchange Server\V14\Bin\CmdletExtensionAgents (assuming default Exchange installation).  If there is already one there, you'll need to combine the scripts.


Comments (13)

  1. Mark O'Connor says:

    Hi David

    Thanks for your help with this the script and task works like a dream lets hope MS see this as a required part and it wont be so difficult in future versions

  2. Lina says:

    Thanks, work like a charm. Thanks a lot.

  3. Ogej says:

    I have a working PowerShell script that sends automated mail when a new user mailbox is created or enabled on exchange server 2013, this works fine except that the images and logos in the html file does not display.

    I have inserted the code here in my working script but its still not working.

    Anyone know the solution to this?


  4. The technique described here works, as does the sample script.  Unfortunately I'm not able to assist with other scripts, so don't know what the problem may be.  If you need dev. assistance, you can raise a case and we'd then be able to assist you troubleshoot your script.

  5. sewellia says:

    Very usefull script and it worked straight away. However, I am having problems displaying the users SAMAccountname and PrimarySMTPAddress.  Adding the two lines below simply does not work.

    $messageText = $messageText.Replace("#UserName#", $usr.SamAccountName)

    $messageText = $messageText.Replace("#PrimarySMTPAddress#", $usr.PrimarySMTPAddress)

    Syntax error? Or should $usr.SamAccountName and  $usr.PrimarySMTPAddress be defined elsewhere first?

    But then $messageText = $messageText.Replace("#UserFirstName#", $usr.FirstName) works fine even though the variable $usr.FirstName only occurs here.

  6. Johnny D says:

    Hi, thanx so much for the great post , this is exactly what i was trying to do, but how can i make it work with adding authentication ?

  7. Johnny D says:


    I used this for the authentication and it worked, the only bad thing is that the password is in plain text but i suppose its not a big deal since the script will b executed just internally n access to the exchange servers is limited just for dedicated persons.

    $SMTPServer = “your smtp server”
    $SMTPPort = “25”
    $Username = “your username” # user name n password of the email box u wanna use
    $Password = “the password”
    $message = New-Object System.Net.Mail.MailMessage
    $smtpClient = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort)
    $smtpClient.EnableSSL = $false
    $smtpClient.Credentials = New-Object System.Net.NetworkCredential($Username, $Password)

    for info here i didnt use SSL so thats why i used port 25 instead of 587.

    Good Luck

  8. Sreekanth says:

    It worked very well for getting an email. But have 2 issues.
    1. not getting Logo’s
    2.not showing username

    main issue is Logo. Below is the error and script used. I have 3 PNG image files in .htm page All 3 are replaced with CID and Title.
    Please advice. Thanks in advanced for your reply.

    The cmdlet extension agent with the index 5 has thrown an exception in OnComplete(). The exception is: Microsoft.Exchange.Provisioning.ProvisioningException: ScriptingAgent: Exception thrown while invoking scriptlet for OnComplete API: Cannot find a variable with name ‘image’.. —> System.Management.Automation.ItemNotFoundException: Cannot find a variable with name ‘image’.
    — End of inner exception stack trace —
    at Microsoft.Exchange.ProvisioningAgent.ScriptingAgentHandler.OnComplete(Boolean succeeded, Exception e)
    at Microsoft.Exchange.Provisioning.ProvisioningLayer.OnComplete(Task task, Boolean succeeded, Exception exception)

    Exchange Management Shell command completed:
    New-Mailbox -Name ‘xxx’ -Alias ‘xxx’ -OrganizationalUnit ‘xxx/User Accounts/Test’ -UserPrincipalName ‘xxx’ -SamAccountName ‘xxx’ -FirstName ‘starter’ -Initials ” -LastName ‘xxx’ -Password ‘System.Security.SecureString’ -ResetPasswordOnNextLogon $false -Database ‘xxx’

    # If we have the mailbox, we can send the introductory email
    if ($mbx)
    # Mailbox does not have first name property, so we need to get the user account
    $usr = Get-User $mbx.Identity

    # Create the objects we need to create the message and send the mail
    $message = New-Object System.Net.Mail.MailMessage
    $smtpClient = New-Object System.Net.Mail.SmtpClient(“”) # Change this to point to your SMTP server

    # Obtain the message text
    $messageText = [string](Get-Content (“c:\Welcome\Welcome.htm”)) # Change to point to your HTML welcome message
    $messageText = $messageText.Replace(“#UserFirstName#”, $usr.FirstName) # This replaces #UserFirstName# with the user’s first name – you can add further replacements as needed

    # Create the HTML view for this message
    $view = [System.Net.Mail.AlternateView]::CreateAlternateViewFromString($messageText, $null, “text/html”)

    # Add any linked resources (e.g. images)
    $image = New-Object System.Net.Mail.LinkedResource(“C:\Welcome\image001.png”)
    $image.ContentId = “image001.png”
    $image.ContentType = “image/png”

    # Add any linked resources (e.g. images)
    $image = New-Object System.Net.Mail.LinkedResource(“C:\Welcome\image002.png”)
    $image.ContentId = “image002.png”
    $image.ContentType = “image/png”

    # Add any linked resources (e.g. images)
    $image = New-Object System.Net.Mail.LinkedResource(“C:\Welcome\image003.png”)
    $image.ContentId = “image003.png”
    $image.ContentType = “image/png”

    # Create the message
    $message.From = “xxx@xxxx.COM” # Update this to the address you want the welcome message to be sent from
    $message.Subject = “Welcome to IT SUPPORT!” # Update this to your email subject
    $message.IsBodyHtml = $true

    # Send the message

    # Tidy up variables
    Remove-Variable image
    Remove-Variable view
    Remove-Variable messageText
    Remove-Variable message
    Remove-Variable smtpClient
    Remove-Variable usr
    Remove-Variable mbx

  9. Brian Long says:

    I’m looking to implement this, but am wondering about compatibility with Office 365. We are currently on premise Exchange 2010, but are in the offices of upgrading to 2016, and will be migrating to O365 soon after. I’m brand new to O365 so am not even sure what questions to ask. Will it still work? Any gotchas I should look for?

  10. Ahmed says:

    i receive below error:
    The cmdlet extension agent with the index 5 has thrown an exception in OnComplete(). The exception is: Microsoft.Exchange.Provisioning.ProvisioningException: ScriptingAgent: Exception thrown while invoking scriptlet for OnComplete API: Cannot find a variable with the name ‘image’.. —> System.Management.Automation.ItemNotFoundException: Cannot find a variable with the name ‘image’. — End of inner exception stack trace — at Microsoft.Exchange.ProvisioningAgent.ScriptingAgentHandler.OnComplete(Boolean succeeded, Exception e) at Microsoft.Exchange.Provisioning.ProvisioningLayer.OnCompleteImpl(Task task, Boolean succeeded, Exception exception)

    1. Peter says:

      Hash out anything with $image in the script
      in other words change to
      # Add any linked resources (e.g. images)
      # $image = New-Object System.Net.Mail.LinkedResource(“C:\WelcomeMessage\image001.png”)
      # $image.ContentId = “image001.png”
      # $image.ContentType = “image/png”
      # $view.LinkedResources.Add($image)

      # Remove-Variable image

  11. berket says:

    Hi when I only add one image it works without any issues.

    When I add more than one…outlook just blocks the images and adds them as attachments to the email

    # Add any linked resources (e.g. images)
    $image = New-Object System.Net.Mail.LinkedResource(“d:\scripts\welcome email\image002.jpg”)
    $image.ContentId = “image002.jpg”
    $image.ContentType = “image/jpg”

    $image12 = New-Object System.Net.Mail.LinkedResource(“d:\scripts\welcome email\image012.jpg”)
    $image.ContentId = “image012.jpg”
    $image.ContentType = “image/jpg”

    Any ideas?

  12. Mohammed Gayas says:

    I am getting the below error message on exchange 2013 when trying to create a mailbox

    The property “OperatorNumber” on the cmdlet extension agent “6” has already been provisioned by another agent. You can run this cmdlet again with the Verbose switch to find out which agents provision this property.

Skip to main content