Office 365 for IT Pros

Three Ways to use PowerShell to Send a Welcome Message to New Office 365 Users

Advertisements

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.

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:

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:

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:

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-Mailbox -Filter "WhenMailboxCreated -gt '$CheckDate'" -RecipientTypeDetails UserMailbox -ResultSize Unlimited | Select WhenMailboxCreated, DisplayName, UserPrincipalName, PrimarySmtpAddress)

The Get-Mailbox cmdlet returns a lot of properties, so we only select those that we need to process. If you’d like to use Get-ExoMailbox, apart from changing the cmdlet name, we also need to request that the WhenMailboxCreated property is returned because it is not in the minimum property set:

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

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="
     "
#Header for the message
$HtmlBody = "
     

Welcome to Our Company

Generated: $(Get-Date -Format g)

We're Pleased to Have You Here

" # Find all mailboxes created in the target period $Users = (Get-Mailbox -Filter "WhenMailboxCreated -gt '$CheckDate'" -RecipientTypeDetails UserMailbox -ResultSize Unlimited | Select WhenMailboxCreated, DisplayName, UserPrincipalName, PrimarySmtpAddress) ForEach ($User in $Users) { $EmailRecipient = $User.PrimarySmtpAddress Write-Host "Sending welcome email to" $User.DisplayName $htmlHeaderUser = "

New User " + $User.DisplayName + "

" $htmlline1 = "

Welcome to Office 365

" $htmlline2 = "

You can open Office 365 by clicking here

" $htmlline3 = "

Have a great time and be sure to call the help desk if you need assistance.

" $htmlbody = $htmlheaderUser + $htmlline1 + $htmlline2 + $htmlline3 + "

" $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.

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.

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!