When setting up an Exchange lab, it's easy to create users in bulk using a foreach loop (user1, user2, user3, etc.), but after a while this method can become a little boring. To break up the monotony, I decided to write a PowerShell function that can be used to create mailboxes using realistic names. The name of the function is New-LabMailbox – here is a list of the available parameters and a quick description of each one:
- Count – Specifies the number of mailboxes to create. The default value is 1.
- Password – The password for the AD account. If no value is provided, the password will be automatically generated using the GeneratePassword method from the System.Web.Security.Membership class.
- Database – Specifies the Exchange database used for the mailbox (required with Exchange 2007).
- UpnSuffix – Specifies the upn suffix for the user. If no value is provided the root domain name will be used.
- OrganizationalUnit – The OU for the AD account. If no value is provided the default users container in AD will be used.
This code relies on a CSV file that contains 1000 unique, commonly used, first and last names. I decided to package it as a PowerShell module to keep everything organized in a single location. Here's how to set it up:
- Download the module here.
- On one of your Exchange servers or a machine running the Exchange tools, extract the contents of the zip file into one of your $ENV:PSModulePath directories (for example: C:\Users\%username%\Documents\WindowsPowerShell\Modules).
- Load the module into your Exchange Management Shell session using the Import-Module ExchangeLab command.
Important Note: PowerShell doesn’t trust scripts that you download from the internet. The best way to get around this is to click the unblock button on the properties of the .psm1 and .psd1 files in the module directory.
Below are a few examples of how you might use the New-LabMailbox function to populate your Exchange labs:
Creating a Specified Number of Mailboxes
Use the Count parameter to specify the number of mailboxes to be created. This is an optional parameter and if no value is provided the function will create a single mailbox; user names are generated at random:

Creating Mailboxes in Every Mailbox Database
You can pipe the output from Get-MailboxDatabase to New-LabMailbox to create mailboxes in every Exchange database in the organization:

Creating Mailboxes in Multiple OUs
Another thing I like to do is fill up a bunch of OUs with mailbox enabled users. For example, I load the AD PowerShell module into my Exchange Management Shell session and do something like this:

This module will work with both Exchange 2007/2010. If you are using 2007, just make sure you have SP2 and PowerShell v2. Also, remember that if you are using Exchange 2007, the Database parameter on the New-LabMailbox function will be required, but it is optional with Exchange 2010.
Update 4/29/10 - I added another cmdlet to this module that allows you to generate test data for mailboxes. Check out this post for details.





{ 8 comments… read them below or add one }
RT @mike_pfeiffer: [Blog] Populating #Exchange Labs with Mailboxes using #PowerShell http://www.mikepfeiffer.net/2010/03/popu...
RT @mike_pfeiffer: [Blog] Populating #Exchange Labs with Mailboxes using #PowerShell http://www.mikepfeiffer.net/2010/03/popu...
if i wanted to use non-random names, can I replace the names in the CSV with the names I want to use? or is it mixing the first and last names?
Yeah, this particular function randomizes the first and last name columns to generate the user names. Maybe this is more along the lines of what you are looking for?
http://www.mikepfeiffer.net/2010/02/provision-exchange-mailboxes-from-csv-using-powershell-advanced-functions/
Hi Mike,
thanks for this helpful module. I was wondering whether you could run the EMS cmdlets in a “normal” PowerShell console Window. Is that possible at all? I guess you have to import a snap-in?
Klaus
Hey Klaus, thanks. Yeah, you can as long as you have rights in AD to do whatever it is you need to do. Importing the snap-in bypasses RBAC, so any rights delegated through Exchange are not applied.
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
Of course, the above requires the Exchange tools to be installed. You could import the cmdlets through implicit remoting as well if you do not want to use EMS:
http://www.mikepfeiffer.net/2010/02/managing-exchange-2010-with-remote-powershell/
Hi Mike,
I’m trying to run Get-MailboxDatabase -Server X | %{ New-LabMailbox -Count 45 -Database $_.Name } but I am getting this error:
Pipeline not executed because a pipeline is already executing. Pipelines cannot be executed concurrently.
+ CategoryInfo : OperationStopped: (Microsoft.Power…tHelperRunspace:ExecutionCmdletHelperRunspace) [],
PSInvalidOperationException
+ FullyQualifiedErrorId : RemotePipelineExecutionFailed
Pipeline not executed because a pipeline is already executing. Pipelines cannot be executed concurrently.
+ CategoryInfo : OperationStopped: (Microsoft.Power…tHelperRunspace:ExecutionCmdletHelperRunspace) [],
PSInvalidOperationException
+ FullyQualifiedErrorId : RemotePipelineExecutionFailed
ForEach-Object : Cannot index into a null array.
At line:1 char:45
+ Get-MailboxDatabase -Server X | % <<<< { New-LabMailbox -Count 45 -Database $_.Name }
+ CategoryInfo : InvalidOperation: (0:Int32) [ForEach-Object], RuntimeException
+ FullyQualifiedErrorId : NullArray,Microsoft.PowerShell.Commands.ForEachObjectCommand
Any ideas?
Yeah, I know what the problem is…I’ll post a new version of this module later that should fix this. For now, try this:
foreach($db in Get-MailboxDatabase -Server X) {
New-LabMailbox -Count 45 -Database $DB.Name
}