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 (5)

  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. Anonymous 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.