Notes from the field–Bulk create 2000 mailboxes and their associated AD accounts from a CSV file + generating 2000 messages in the queues of an Exchange 2007 server in a Lab (to be continued)



- The prerequisite step is to create a “Test” OU

- Then the first step is to create a CSV file using Excel containing 2000 test user names and a minimum set of attributes for these users (Display Name, sAMAccountName, UserPrincipalName, First Name, Last Name). Easy with the “fill series function” of Excel




Then save the file as a CSV file using Excel.

- The second step is to import that CSV file as 2000 mailboxes using the following script from David Hall from his Signal Warrant blog (giving back to Caesar what is Caesar’s Smile thank you very much David for this simple script !– Just comment my article if you want me to remove your script from my blog page). I modified it very slightly, you can refer to David’s blog for the original one, or create one on your own from scratch using this Technet article - Using the Exchange Management Shell for Bulk Recipient Management.

Here is a paste from the slightly modified Dave’s script, I left the comments anyways as they are very useful to make it work:






          Create new mailboxes in Exchange 2010 and the corresponding user in Active Directory.



          Use the New-Mailbox cmdlet to create mailboxes. The script will prompt you for the default password for all users.

        All accounts are set to prompt the user to change the password at first logon. It then prompts for what OU you want to put the users in,

        change the OU variable AD paths and variable names to correspond to your AD structure. 

        Once the users are created a log file is written to the $logPath.



        1.  If you run this script from somewhere other than Exchange server you will need Exchange Management tools installed.

        2.  The mailbox.csv file filled out.

        3.  The proper Exchange RBAC role (Exchange 2010) or permission (Exchange 2007) to create mailboxes.

        4.  The CSV file will need the following columns; Display Name, sAMAccountName, UserPrincipalName, First Name, Last Name

        5.  set-executionpolicy remotesigned

        6.  Customize the $csvPath, $userDB, $logPath and the OU names and variables to match your infrastructure.



        Tested with Exchange 2010, Windows 7, Windows Vista, Windows Server 2003, Windows Server 2K8 and 2K8 R2



            David Hall |






# If not called, install the Exchange PSSnapin – Exchange 2007 only – use the “Import-Module” commandlet appropriately for Exchange 2010

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin -ErrorAction SilentlyContinue


# Supply the password for all the newly created accounts

$password = read-host "Enter Default Password for all accounts created" -AsSecureString

$ou = ""


# Define these as you wish

# You'll need a provisionned Mailbox.csv file, and a test database

$csvPath = "C:\TEMP\mailboxes.csv"

$userDB = "TestDB"

$logPath = "c:\TEMP\log.txt"


# you can change the OU and associated variable names to fit your needs




Import-CSV "$csvPath" | ForEach {

New-Mailbox `

-Password $password `

-Name $_.'Display Name' `

-Alias $_.'sAMAccountName' `

-OrganizationalUnit $ou `

-sAMAccountName $_.'sAMAccountName' `

-FirstName $_.'First Name'`

-LastName $_.'Last Name'`

-DisplayName $_.'Display Name' `

-UserPrincipalName $_.'UserPrincipalName' `

-Database $userDB `

-ResetPasswordOnNextLogon $true

} | out-file $logPath -append


Write-Host -foregroundcolor Cyan "Users created, view the log at $logPath"




- The third step is to create a Distribution Group containing these 2000 mailboxes (very easy as well using the Active Directory Users and Computers console)

- Then the last step is to use a quick Powershell script (a very simple script that wraps the Send-MailMessage default commendlet) to send one message to this DL, or simply to use an OWA connection to the “Administrator” mailbox or whichever mailbox you have on your Lab environment)

As an example, here is a script that John Milner wrote and posted on one of his blog’s article (thank you very much John ! – Just comment my article if you want me to remove your script from my blog page).

One handy feature of John’s script is that he use a parameter that allows to specify the size of the attachment, and create an attachment using the fsutil command within the script. Neat ! Smile


# If not called, install the Exchange PSSnapin – Exchange 2007 only – use the “Import-Module” commandlet appropriately for Exchange 2010

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin -ErrorAction SilentlyContinue


function Send-MailMessages {



Generate a constant flow of messages for diagnostic purposes.



This script is designed to assist in generating email messages for testing external message flow to and from your messaging infrastructure.

The ability to quickly send a batch of messages with an attachment on a schedule can help track flow issues or to simply be used to confirm mail routing.



Send-MailMessages -To -From -MessageCount 10 -SecondsDelay 10 -AttachmentSizeKB 1

Send 10 emails to every 10 seconds with a 1MB Attachment



Send-MailMessages -MessageCount 48 -SecondsDelay 1800

Send an email every 30 minutes for 24 hours.





File Name: Send-MailMessages.ps1


Author: jfrmilner



Requires: Powershell V2

Requires: Exchange Managemnent Shell (Only used to auto find the smtpServer)

Legal: This script is provided "AS IS" with no warranties or guarantees, and confers no rights. You may use, modify, reproduce, and distribute this script file in any way provided that you agree to give the original author credit.

Version: v1.0 - 2010 Aug 08 - First Version*

Version: v1.1 - 2012 April 26 - Fixed when only a single HT Server is available. Added check for existing file. Fixed attachment parameter to use varible.



param ( [Parameter(Mandatory=$false)] $To = "", [Parameter(Mandatory=$false)] $From = "", $AttachmentSizeKB=$null, $MessageCount=2, $SecondsDelay=10 )


$messageParameters = @{

 Body = $null | ConvertTo-Html -Body "<H2> Test Message, Please ignore </H2>" | Out-String

 From = $from

 To = $to

 SmtpServer = @(Get-TransportServer)[0].Name.ToString()



if ($AttachmentSizeKB) {


if ((Test-Path $Env:TMP\$($AttachmentSizeKB)mbfile.txt) -ne $true)


      fsutil file createnew $Env:TMP\$($AttachmentSizeKB)mbfile.txt $($AttachmentSizeKB * 1KB)



$messageParameters.Add("attachment", "$Env:TMP\$($AttachmentSizeKB)mbfile.txt") }


1..$MessageCount | % { sleep -Seconds $secondsDelay ; Send-MailMessage @messageParameters -Subject ("Mailflow Test Email - " + (Get-Date).ToLongTimeString() + " Message " + $_ + " / $MessageCount") -BodyAsHtml }




Then execute John’s function :

Send-MailMessages -To -From -MessageCount 1 -SecondsDelay 0 -AttachmentSizeKB 150


The problem is :

  • - A Distribution List with 2000 recipients won’t be deflated by a hub server if the recipients are on a mailbox serer on the same AD site as the HUB
  • - We have to either :
    • Put 2000 mailboxes in a DB, dismount that DB, send a message to these 2000 mailboxes
    • Or put 1 mailbox in a test DB, dismount that DB, send 2000 messages to that mailbox
    • Or create 2000 .EML files, and put all of these on the Pickup directory of the HUB server.
    • Or have a lab with 2 AD sites, with HUB/CAS/MBX server in that sites, and send a message to a DL with 2000 members from the other AD site.


Then what I tried that worked so far:

- Put one user in a temp DB (named “TempDB”)

- dismount TempDB

- Using the function brought by John Milner’s script above (I slightly modified his script a bit to change the “AttachmentSizeMB” parameter with “AttachmentSizeKB” to have smaller attachments), type :

Send-MailMessages -To -From -MessageCount 2000 -SecondsDelay 0 -AttachmentSizeKB 150

That works as the Perfmon testimonies it (Messages Queued for Delivery counter):




To be continued …

Comments (0)

Skip to main content