Automating Exchange mailbox creation and provisioning step-by-step

If you're looking to steal more valuable time to put toward other more important tasks, take a look at these cmdlets that can automate mailbox creation and provisioning for your users.

In many Exchange organizations, the Active Directory team creates new user accounts, with mailboxes then created...

by the Exchange administrator. In other organizations, Exchange and Active Directory personnel are one-in-the-same. In both cases, it makes sense to automate new mailbox creation and provisioning. Fortunately, it’s easily done using four simple steps and the Exchange Management Shell.

Step 1: Create a PowerShell script

Our goal is to completely automate mailbox provisioning. Because that might require several commands, it makes sense to use a PowerShell script. Use a text or script editor to create a new script and name it something like NewMailboxes.ps1. Also, make sure the machine running the script can actually execute PowerShell scripts. Don’t laugh, I’ve seen people make this mistake plenty of times.

To begin, use the Get-ExecutionPolicy cmdlet to determine your current execution policy setting. Also, run Get-Help about_Execution_Policies to learn about the various execution policy settings and how they work.

Step 2: Define a data source for the script

New users are the data source for our script. If these users already exist in Active Directory, it’s a simple task. The Exchange Management Shell (EMS) has a built-in cmdlet called Get-User, which contains native filtering capabilities. Consider the following command:

Get-User -RecipientTypeDetails User -OrganziationalUnit company.local/sales

This command retrieves Active Directory users from the “Sales” organizational unit (OU). Since the -RecipientTypeDetails parameter is set to “User,” it will return only the first 1,000 users in the Sales OU that don’t have a mailbox. You can also add the -ResultSize parameter and set it to either a specific value or “Unlimited.”

If users do not exist in Active Directory, I recommend using a .csv file. You can manually create .csv files with a text editor, but I recommend Microsoft Excel.

Create a new spreadsheet and add multiple columns that define the settings for each mailbox. For example, if you are creating mailbox-enabled Active Directory users, you must provide a few pieces of information like name, alias and user principal name (UPN).

You can add other parameters as well, but here is what a bare bones sample file might look like:

Name Alias UPN
Jerald Franklin jfranklin [email protected]
Patti Byrd pbyrd [email protected]
Christopher Beasley cbeasley [email protected]
Woodrow Stevenson wstevenson [email protected]

Remember, the New-Mailbox cmdlet has over 50 available parameters, so this can easily be extended. Save the spreadsheet as a comma-delimited .csv file, then import it into the EMS using the following cmdlet:

Import-CSV c:\new_users.csv -NoTypeInformation

This command returns each row in the .csv file as an object. Each object has three properties: Name, Alias and UPN. Each object is defined by the column names in the .csv file. The next step is to process the results and provision a new mailbox for each user.

Step 3: Use the data source to create the mailboxes

Since the data source is a list of user accounts retrieved from Active Directory, you need the following command to create the mailboxes:

Get-User -RecipientTypeDetails User -OrganziationalUnit company.local/sales | Enable-Mailbox

The output (user accounts) from the first command is piped to the Enable-Mailbox cmdlet, which in turn creates mailboxes for each user. Again, multiple parameters may be added to the Enable-Mailbox cmdlet if you need to define additional settings.

Provisioning new mailboxes often requires multiple tasks. The first step is to create the mailbox, but you may also need to add it to a distribution group or execute an additional command. Let’s extend our previous code sample a bit:

Get-User -RecipientTypeDetails User -OrganziationalUnit company.local/sales | %{
  $mb = Enable-Mailbox $_
  Add-DistributionGroupMember -Identity Sales -Member $mb

This time, I’ve piped the output from Get-User to the percent (%) character. The percent character is an alias for the Foreach-Object cmdlet. This lets you run multiple commands in a script block (the code inside the brackets) for each user returned.

Inside the script block, I’m running two commands: One to create the mailbox and one to add the newly created mailbox to the “Sales” distribution group. Note that I’ve referenced the input object (the user sent over the pipeline) using the $_ variable. This is a temporary variable; it allows you to reference each user as it comes across the pipeline.

If using a .csv file, you can take a similar approach. You want to import the file, iterate over each row and create the required user accounts and mailboxes. Again, you can use the ForEach-Object cmdlet to process the collection of items:

Import-CSV c:\new_users.csv –NoTypeInformation | %{
  $password = ConvertTo-SecureString [email protected] –AsPlainText –Force
  $mb = New-Mailbox –Name $_.Name –UserPrincipalName $_.UPN –Password $password
  Add-DistributionGroupMember -Identity Sales -Member $mb

The New-Mailbox cmdlet requires you to assign a password as a secure-string object, so this time I’ve used three commands within the script block. One command creates an initial secure password object, the second creates the mailbox and the third adds the mailbox to the “Sales” group.

Notice that I used the $_ variable again. This time, I’m accessing the properties of the $_ variable, which map directly to the column headers in the .csv file.

Step 4: Schedule the script to run automatically

To automate the script, simply add a new scheduled task. Make sure you’re running PowerShell.exe and that the new provisioning script is specified as the command to be executed. Here’s a command line approach to using the schtasks.exe utility to create the task:

schtasks /create /tn "Mailbox Provisioning" /tr 
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command 
c:\NewMailboxes.ps1" /sc daily /st 00:00 /rl highest

In this example, I’ve created a task called “Mailbox Provisioning,” that runs the New-Mailboxes.ps1 script daily, at 12:00 a.m.

It might be more convenient to manage scheduled tasks with the graphical task scheduler, but this command gives you an idea of the settings you should use. If you decide to use the .csv file, overwrite it with one that defines a new set of users before the script runs again the next day.

In addition to checking your execution policy, you should also make sure that your EMS environment loads when the script executes. This can be done at the beginning of the script or from a profile associated with the user account running the task.

Mike Pfeiffer is a Microsoft Certified Master on Exchange 2010 and a Microsoft Exchange MVP. In addition to being an author and IT conference speaker, Mike delivers Exchange, Lync, and PowerShell courses through Interface Technical Training in Phoenix, AZ. You can find many of his thoughts online at mikepfeiffer.net, where he blogs regularly about Exchange Server and PowerShell-related topics.

Dig Deeper on Exchange Server setup and troubleshooting