How to Use PowerShell to Send a Welcome Message to New Office 365 Users

Three PowerShell Modules to Choose From

A recent appeal from a reader for a PowerShell script to send a welcome message to new people joining an Office 365 tenant forced me to think about the best solution. The issue isn’t finding a script to do the job because there’s plenty of scripts published in places like the TechNet Gallery (here’s an example).

The issue boils down to deciding how to identify new users. Three approaches are available to find new users.

  • Use the Get-MsOlUser cmdlet from the Microsoft Online Services module (which is what the script pointed to above does).
  • Use the Get-AzureADUser cmdlet from the Azure Active Directory module.
  • Use the Get-Mailbox cmdlet from Exchange Online (or the new Get-ExoMailbox cmdlet from the Exchange Online Management module).

My preferred approach is the last. It’s the simplest and most straightforward. Let’s see why.

Microsoft Online Services

The basic steps in this approach are:

  • Run Get-MsOlUser to return a set of accounts from Azure Active Directory that have been created in the recent past.
  • Calculate an email address for the user from the proxy addresses for the account.
  • Call Send-Message to send the welcome email.

One immediate issue that we face with Get-MsOlUser is to only select user accounts. Azure Active Directory includes all sorts of accounts that we don’t want to send welcome messages to, like the accounts created for shared and room mailboxes or those created for guest accounts. This snippet finds user accounts created in the last 7 days. The check for licensed accounts is an effective filter to focus on user accounts. In general, guest accounts and shared accounts don’t need Office 365 licenses.

# Find Office 365 user accounts created in the last 7 days
$CheckDate = (Get-Date).AddDays(-7)
$Users = Get-MsolUser -All | Where-Object {$_.WhenCreated -ge $CheckDate -and $_.isLicensed -eq $True }

After finding the user accounts, we can select an email address from the ProxyAddresses property. The primary SMTP address is marked with a prefix of “SMTP:,” but you can send to any proxy address registered for an account and Exchange Online will deliver the message. We can therefore do something like:

# Get Email address from the first proxy address in a user account
$EmailAddress = $User.ProxyAddresses[0].Split(":")[1] 

Alternatively, if your organization assigns User Principal Names to accounts that match their email addresses, you can send the message to the address stored in the UserPrincipalName property.

Azure Active Directory

I prefer to use the Azure Active Directory module whenever possible because code written with this module is likely to last longer. Microsoft hasn’t said when they will deprecate the Microsoft Online Services module, but I assume this will be done in the future because it doesn’t make sense to have two modules that essentially do the same job. For these cmdlets, we need to:

  • Run Get-AzureADUser to return a set of accounts.
  • Check the creation date of each account to see if it’s been created recently.
  • Get the address for each matching account and send the email.

The command to fetch the set of accounts is as follows. We initially filter on UserType to exclude guest accounts. If we did no more, the set of objects would include accounts for shared and resource mailboxes, so we include an extra filter against ProvisionedPlans. This property holds details of the Office 365 plans assigned to the account and is empty when the account has no licenses.

# Find set of Azure Active Directory accounts
$Users = (Get-AzureADUser -All $True | ? {$_.UserType -eq "Member" -and $_.ProvisionedPlans -ne $Null} | Select ObjectId, DisplayName, UserPrincipalName, ProxyAddresses)

Get-AzureADUser doesn’t return a WhenCreated property for an account (it’s included in the ExtensionProperty property), so we need to call the Get-AzureADUserExtension cmdlet to extract the creation date.

# Calculate the age of the account
CreationDate = (Get-AzureADUserExtension -ObjectId $User.ObjectId).Get_Item("createdDateTime") 
$AccountAge = ($CreationDate | New-TimeSpan).Days

After figuring out how old the account is, we decide whether to send the email and can use the same method to find an address for the message.

Exchange Online Cmdlets

Exchange Online has its own directory (EXODS) synchronized with Azure Active Directory. EXODS holds information for all mail-enabled objects. Given that we want to send email to new users, it’s reasonable to say that we can:

  • Run the Get-Mailbox or Get-ExoMailbox cmdlets to find recently-added mailboxes.
  • Send a message to those mailboxes.

Finding our mailboxes is easy and we can do some extra processing as we create the set of objects. This command applies a server-side filter (for better performance) based on the mailbox creation date (i.e. WhenMailboxCreated is used instead of WhenCreated). User mailboxes are selected if they were created in the last seven days.

# Get list of mailboxes created recently
[string]$Checkdate = (Get-Date).AddDays(-7)
$Users = (Get-ExoMailbox -Filter "WhenMailboxCreated -gt '$CheckDate'" -RecipientTypeDetails UserMailbox -ResultSize Unlimited -Properties WhenMailboxCreated | Select WhenMailboxCreated, DisplayName, UserPrincipalName, PrimarySmtpAddress)

The Get-Mailbox cmdlet returns a lot of properties, so we only select those that we need to process. In this case, we use Get-ExoMailbox, so we need to request that the WhenMailboxCreated property is returned because it is not in the minimum property set.

Being able to use a server-side filter to select a set of mailboxes is not only convenient; it’s also best in terms of performance, especially when a tenant supports large numbers of accounts.

Sending The Welcome Message

Now that we’ve figured out how to find the people we want to welcome, we can proceed to send the welcome message. I wrote a script to define some variables for HTML formatting and then assemble the elements of a HTML messages from details of each user. The script is shown below.

# Date to Check for new accounts created in the last 7 days
[string]$CheckDate = (Get-Date).AddDays(-7)
# Make sure that we have valid credentials
If (-not $O365Cred) { #Make sure we have credentials
    $O365Cred = (Get-Credential)}
# Message is from the logged in account
$MsgFrom = $O365Cred.UserName ; $SmtpServer = "smtp.office365.com" ; $SmtpPort = '587'

# Define some variables for the message
#HTML header with styles
$htmlhead="
     <style>
      BODY{font-family: Arial; font-size: 10pt;}
	H1{font-size: 22px;}
	H2{font-size: 18px; padding-top: 10px;}
	H3{font-size: 16px; padding-top: 8px;}
    </style>"
#Header for the message
$HtmlBody = "
     <h1>Welcome to Our Company</h1>
     <p><strong>Generated:</strong> $(Get-Date -Format g)</p>  
     <h2><u>We're Pleased to Have You Here</u></h2>"

# Find all mailboxes created in the target period
$Users = (Get-ExoMailbox -Filter "WhenMailboxCreated -gt '$CheckDate'" -RecipientTypeDetails UserMailbox -ResultSize Unlimited -Properties WhenMailboxCreated | Select WhenMailboxCreated, DisplayName, UserPrincipalName, PrimarySmtpAddress)

ForEach ($User in $Users) {
      $EmailRecipient = $User.PrimarySmtpAddress
      Write-Host "Sending welcome email to" $User.DisplayName
      $htmlHeaderUser = "<h2>New User " + $User.DisplayName + "</h2>"
      $htmlline1 = "<p><b>Welcome to Office 365</b></p>"
      $htmlline2 = "<p>You can open Office 365 by clicking <a href="http://www.portal.office.com">here</a> </p>"
      $htmlline3 = "<p>Have a great time and be sure to call the help desk if you need assistance.</p>"
      $htmlbody = $htmlheaderUser + $htmlline1 + $htmlline2 + $htmlline3 + "<p>"
      $HtmlMsg = "" + $HtmlHead + $HtmlBody
     # Construct the message parameters and send it off...
        $MsgParam = @{
         To = $EmailRecipient
         From = $MsgFrom
         Subject = "A Hundred Thousand Welcomes"
         Body = $HtmlMsg
         SmtpServer = $SmtpServer
         Port = $SmtpPort
         Credential = $O365Cred }
         Send-MailMessage @msgParam -UseSSL -BodyAsHTML}

Only accounts enabled for SMTP AUTH connections can use the Send-MailMessage cmdlet to send email with Exchange Online.

You can download the complete script from GitHub.

The Welcome Message

An example of a welcome message is shown in Figure 1. It’s easy to tweak the script to add appropriate text for your organization, including links, graphics, and other elements.

 An example welcome message sent to a new mailbox
Figure 1: An example welcome message sent to a new mailbox

What is evident from this experience is that multiple ways exist to find out a list of new accounts/mailboxes. The number of PowerShell modules available for Office 365 sometimes makes it difficult to decide what the right tool is for any particular job. Some experimentation and testing helps to understand the strengths and weaknesses of each approach. In this case, if you want to send a welcome message to new Office 365 accounts, my recommendation is to use the Exchange Online cmdlets.


This is a great example of the in-depth consideration the Office 365 for IT Pros team gives to topics we cover in the book as well as those that never end up being covered. Our dedication (or obsession) benefits everyone!

6 Replies to “How to Use PowerShell to Send a Welcome Message to New Office 365 Users”

  1. I know this is an old post, but had a question around the credential prompt you get at the end of the script. We’d like to run this on a scheduled task and how would I go about adjusting the script so I didn’t get that prompt?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.