Auto Create Exchange Mailboxes v1.7

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

This utility is available to download from the Microsoft TechNet GalleryPowerShell Gallery and GitHub.

-Mike

Twitter – @Digressive

 

Features and Requirements

  • This script is designed to be run locally on an Exchange Server.
  • The Exchange Server management tools must be installed.
  • The Active Directory management tools must be installed.

This script has been tested on Windows Server 2016 with Exchange 2016, Windows Server 2012 R2 with Exchange 2013, and Windows Server 2008 R2 with Exchange 2010.

 

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” results in the script not 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” because PowerShell will remove the comma’s from the string.

 

Generating A Password File

The password used for SMTP server authentication must be in an encrypted text file. To generate the password file, run the following command in PowerShell, on the computer that is going to run the script and logged in with the user that will be running the script. When you run the command you will be prompted for a username and password. Enter the username and password you want to use to authenticate to your SMTP server.

Please note: This is only required if you need to authenticate to the SMTP server when send the log via e-mail.

$creds = Get-Credential
$creds.Password | ConvertFrom-SecureString | Set-Content c:\scripts\ps-script-pwd.txt

After running the commands, you will have a text file containing the encrypted password. When configuring the -Pwd switch enter the path and file name of this file.

 

Configuration

The table below shows all the command line options available with descriptions and example configurations.

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 No 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”. If a database is not configured the script will use the smallest one available. 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. C:\foo
-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.

example@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 location of the file containing the encrypted password of the account to use for SMTP authentication.

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

c:\foo\ps-script-pwd.txt
-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

 

Change Log

2018-01-13 1.7

  • Fixed an issue where the script would not load the Exchange PowerShell snap-in and PowerShell would unexpectedly quit.
  • Added the capability for the script to create mailboxes in the smallest database available.
  • The ability to configure a specific database if required remains.

2017-10-16 1.6

  • Changed SMTP authentication to require an encrypted password file.
  • Added instructions on how to generate an encrypted password file.

2017-10-07 1.5

  • Added necessary information to add the script to the PowerShell Gallery.

2017-09-27 1.4

  • Added improved, cleaned logging. Log output is no longer handled by PowerShell’s Transcript functionality.
  • Cleaned up code formatting.

2017-07-22 1.3

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

 

PowerShell Code


<#PSScriptInfo .VERSION 1.7 .GUID 2905a44a-0932-41e9-9d09-b6339a9f0143 .AUTHOR Mike Galvin twitter.com/digressive .COMPANYNAME .COPYRIGHT (C) Mike Galvin. All rights reserved. .TAGS Exchange Mailbox Active Directory Syncronization .LICENSEURI .PROJECTURI https://gal.vin/2017/06/07/powershell-create-mailboxes .ICONURI .EXTERNALMODULEDEPENDENCIES Exchange Management PowerShell module. Active Directory Management PowerShell module. .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #>

<# .SYNOPSIS Create Exchange mailboxes for users with no mailbox contained within an OU tree. .DESCRIPTION Create Exchange mailboxes for users with no mailbox contained within an OU tree. This script will: Create mailboxes for users contained witin an OU tree. You can configure the database and retention policy to use. Output and e-mail a log file. This script is designed to be run locally on an Exchange Server. Please note: to send a log file using ssl and an SMTP password you must generate an encrypted password file. The password file is unique to both the user and machine. The command is as follows: $creds = Get-Credential $creds.Password | ConvertFrom-SecureString | Set-Content c:\foo\ps-script-pwd.txt .PARAMETER Ou The AD Organisational Unit (including child OUs) that contains the users to create Exchange Mailboxes for. .PARAMETER Datab The Exchange database to create the mailboxes in. If you do not configure a Database, the smallest database will be used. .PARAMETER Rp The retention policy that should be applied to the users. .PARAMETER Compat Use this switch if you are using Exchange 2010. .PARAMETER L The path to output the log file to. The file name will be "Create-Mailboxes.log" .PARAMETER SendTo The e-mail address the log should be sent to. .PARAMETER From The from address the log should be sent from. .PARAMETER Smtp The DNS name or IP address of the SMTP server. .PARAMETER User The user account to connect to the SMTP server. .PARAMETER Pwd The txt file containing the encrypted password for the user account. .PARAMETER UseSsl Connect to the SMTP server using SSL. .EXAMPLE Create-Mailboxes.ps1 -Ou "OU=NewUsers,OU=Dept,DC=contoso,DC=com" -Datab "Mail DB 2" -Rp "1-Month-Deleted-Items" -L E:\scripts -Sendto me@contoso.com -From Exch01@contoso.com -Smtp smtp.live.com -User Exch01@contoso.com -Pwd P@ssw0rd -UseSsl This will create mailboxes for users that do not already have one in the OU NewUsers and all child OUs. It will create the mailbox using Mail DB 2 and apply the retention policy "1-Month-Deleted-Items". If you do not configure a Database, the smallest database will be used. A log will be output to E:\scripts and e-mail using a secure connection. The powershell code to get the smallest database is by Jason Sherry: https://blog.jasonsherry.net/2012/03/25/script_smallest_db/. #>

[CmdletBinding()]
Param(
    [parameter(Mandatory=$True)]
    [alias("Ou")]
    $OrganisationalUnit,
    [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 $OrganisationalUnit -Filter * -Properties mail | Where-Object {$_.mail -eq $null} | Measure-Object

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

    ## If logging is configured, start log
    If ($LogPath)
    {
        $LogFile = "Create-Mailboxes.log"
        $Log = "$LogPath\$LogFile"

        ## If the log file already exists, clear it
        $LogT = Test-Path -Path $Log
        If ($LogT)
        {
            Clear-Content -Path $Log
        }

        Add-Content -Path $Log -Value "****************************************"
        Add-Content -Path $Log -Value "$(Get-Date -Format G) Log started"
        Add-Content -Path $Log -Value ""
    }

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

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

                ## Logging
                If ($LogPath)
                {
                    Add-Content -Path $Log -Value "$(Get-Date -Format G) Creating mailbox for User: $($User.SamAccountName) in Database: $Database with Retention Policy: $Retention"
                }
            }
        }
    }

    ## If a database is not configured, find the smallest database
    Else
    {
        $MBXDbs = Get-MailboxDatabase

        ForEach ($MBXDB in $MBXDbs)
        {
            $TotalItemSize = Get-MailboxStatistics -Database $MBXDB | %{$_.TotalItemSize.Value.ToMB()} | Measure-Object -sum
            $TotalDeletedItemSize = Get-MailboxStatistics -Database $MBXDB.DistinguishedName | %{$_.TotalDeletedItemSize.Value.ToMB()} | Measure-Object -sum
     
            $TotalDBSize = $TotalItemSize.Sum + $TotalDeletedItemSize.Sum

            If (($TotalDBSize -lt $SmallestDBsize) -or ($SmallestDBsize -eq $null))
            {
                $SmallestDBsize = $TotalDBSize
                $SmallestDB = $MBXDB
            }
        }

        ## 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 $SmallestDB -RetentionPolicy $Retention

                ## Logging
                If ($LogPath)
                {
                    Add-Content -Path $Log -Value "$(Get-Date -Format G) Creating mailbox for User: $($User.SamAccountName) in Database: $SmallestDB with Retention Policy: $Retention"
                }
            }
        }
    }

    ## If log was configured stop the log
    If ($LogPath)
    {
        Add-Content -Path $Log -Value ""
        Add-Content -Path $Log -Value "$(Get-Date -Format G) Log finished"
        Add-Content -Path $Log -Value "****************************************"

        ## 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)
            {
                $SmtpPwdEncrypt = Get-Content $SmtpPwd | ConvertTo-SecureString
                $SmtpCreds = New-Object System.Management.Automation.PSCredential -ArgumentList ($SmtpUser, $SmtpPwdEncrypt)

                ## 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

 

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 )

Google+ photo

You are commenting using your Google+ 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 )

w

Connecting to %s

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