PowerShell: Create Exchange Mailboxes for AD Users

Recently I needed to write a PowerShell script to create Exchange mailboxes for new users in Active Directory. The script needed to create the mailboxes, use different databases, retention policies, and take users from several Organisational Units along with users in child OUs.

This script is also available to download from the Microsoft TechNet Script Center.

Update: 07/06/2017

I’ve updated the code to speed up the mailbox creation process, changed some of the parameters and fully tested it with Exchange 2016. Additionally I’ve learned that when running the script from command prompt or as a Scheduled Task the -file parameter should be used, here’s why:

The -file Parameter And Why It Matters

When running a PowerShell script from the command prompt or as a Scheduled Task without the -file parameter, any user defined parameters which contain spaces, must be surrounded by ‘single quotes’ as using “double quotes” doesn’t result in the script seeing the parameter as a complete string. When running a PowerShell script with the -file parameter, the “double quotes” work as expected. Cue “The More You Know” GIF.

With this in mind, when running the script please use the -file parameter and surround any database & retention policy friendly names “double quotes” if they have spaces. Also the Distinguished Name for the OU you wish to query for users should be surrounded by “double quotes” also because PowerShell will remove the comma’s from the string.

Compatibility and Requirements

I wrote the script for an older Exchange 2010 installation, but it also has been tested and works with Exchange 2013 & 2016. The script is intended to be run locally on an Exchange server and requires the Active Directory PowerShell module be installed and the Exchange PowerShell snap-in.

The Complete Script

# -------------------------------------------
# Script: Create-Mailboxes_v1-3.ps1
# Version: 1.3
# Author: Mike Galvin twitter.com/digressive
# Date: 22/07/2017
# -------------------------------------------

Param(
    [parameter(Mandatory=$true)]
    [alias("ou")]
    $organisationunit,
    [parameter(Mandatory=$true)]
    [alias("datab")]
    $database,
    [alias("rp")]
    $retention,
    [alias("l")]
    $logpath,
    [alias("sendto")]
    $mailto,
    [alias("from")]
    $mailfrom,
    [alias("smtp")]
    $smtpserver,
    [alias("user")]
    $smtpuser,
    [alias("pwd")]
    $smtppwd,
    [switch]$usessl,
    [switch]$compat)

## If compat is configured load the old Exchange PS Module, if not load the current one.
If ($compat) {
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
}

Else {
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn
}

## Count number of users in ou specified without a mailbox
$usersno = Get-ADUser -SearchBase $organisationunit -Filter * -Properties mail | where {$_.mail -eq $null} | Measure-Object

## If users exist without mailboxes run the script
If ($usersno.count -ne 0) {

    ## If logging is configured, configure and start the log
    If ($logpath) {
        $logfile = ("create-mailboxes.log" -f (Get-Date))
        $log = "$logpath\$logfile"
        Start-Transcript $log
    }

    ## Find the users in the OU specified
    $users = Get-ADUser -SearchBase $organisationunit -Filter *

    ## For each user that does not have a mailbox, create one and set the retention policy if it has been specified
    ForEach ($user in $users) {
        If ($(Get-ADUser $user -Properties mail).mail -eq $null) {
            Enable-Mailbox -Identity $user.SamAccountName -Database $database -RetentionPolicy $retention
        }
    }

    ## If log was configured stop the log
    If ($logpath) {
        Stop-Transcript

        ## If email was configured, set the variables for the email subject and body
        If ($smtpserver) {
            $mailsubject = "Create Mailboxes Log"
            $mailbody = Get-Content -Path $log | Out-String

            ## If an email password was configured, create a variable with the username and password
            If ($smtppwd) {
                $smtpcreds = New-Object System.Management.Automation.PSCredential -ArgumentList $smtpuser, $($smtppwd | ConvertTo-SecureString -AsPlainText -Force)

                ## If ssl was configured, send the email with ssl
                If ($usessl) {
                    Send-MailMessage -To $mailto -From $mailfrom -Subject $mailsubject -Body $mailbody -SmtpServer $smtpserver -UseSsl -Credential $smtpcreds
                }

                ## If ssl wasn't configured, send the email without ssl
                Else {
                    Send-MailMessage -To $mailto -From $mailfrom -Subject $mailsubject -Body $mailbody -SmtpServer $smtpserver -Credential $smtpcreds
                }
            }

            ## If an email username and password were not configured, send the email without authentication
            Else {
                Send-MailMessage -To $mailto -From $mailfrom -Subject $mailsubject -Body $mailbody -SmtpServer $smtpserver
            }
        }
    }
}

## End

Command Line Options

As with my previous scripts I’m using command line parameters to configure the script, here’s the possible configuration switches.

Command Line Switch Mandatory Description Example
-ou Yes Enter the DN (Distinguished Name) of the OU that you wish to search for users. The DN must be surrounded by “double quotes.” “ou=Staff,dc=contoso,dc=com”
-datab Yes Enter the friendly name of the database you wish to create the mailboxes in. If the name has spaces, please surround it with “double quotes”. Mail-DB-1 OR “Mail DB 01”
-rp No If you wish to set a retention policy for the new mailboxes, specify the friendly name here. As with the database, if the name has spaces sourround it with “double quotes”. Retention-Policy-01 OR “Retention Policy 01”
-l No Location to store the optional log file. The name of the log file is automatically generated. E:\scripts
-sendto No The email address to send the log file to. me@contoso.com
-from No* The email address that the log file should be sent from.

*This switch isn’t mandatory but is required if you wish to email the log file.

Server-Status@contoso.com
-smtp No* SMTP server address to use for the email functionality.

*This switch isn’t mandatory but is required if you wish to email the log file.

mail01.contoso.com

OR

smtp.live.com

OR

smtp.office365.com

-user No* The username of the account to use for SMTP authentication.

*This switch isn’t mandatory but may be required depending on the configuration of the SMTP server.

example@contoso.com
-pwd No* The password of the account to use for SMTP authentication.

*This switch isn’t mandatory but may be required depending on your SMTP server.

P@ssw0rd
-usessl No* Add this option if you wish to use SSL with the configured SMTP server.

Tip: If you wish to send email to outlook.com or office365.com you will need this.

*This switch isn’t mandatory but may be required depending on the configuration of the SMTP server.

N/A
-compat No Set this switch if you are using Exchange 2010. Do not set this if you are on Exchange 2013 or 2016. N/A

Change Log

22/07/2017 1.3

  • Improved commenting on the code for documentation purposes.
  • Added authentication and SSL options for e-mail notification.

As always I hope this helps in some way. If you’d like to get in touch with me please leave a comment or tweet me.

-Mike

Follow Mike on Twitter: @Digressive

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s