While creating multiple test environments for testing various Exchange versions and products it dawned on me that as I create users, databases, etc, this will be a time-consuming and repetitive process. In order to reduce my own work load, as well as provide a useable public script, I decided to venture into creating a script that would help with lab automation. This script will include such things as creating databases, DAG replicas, shared mailboxes, retention policies, etc. The iteration here is considered a v1.0 script. Use this only in a lab environment as it is NOT intended for production use.
The Script
The first part of the script includes doing basic things like creating databases (and replicas), creating mailboxes (and users in this case), creating distribution groups, shared mailboxes, room mailboxes and populating mailboxes with email for testing. These options are basic at the moment and rely on txt files for generating names for the test environment.
Script Menu for Test Lab Setup
First step is to create a central menu for the lab script:
[string] $menu = @' ****************************************************************** Exchange Server 2013 Lab Setup for Testing ****************************************************************** Please select an option from the list below. 1) Create databases and replicas 2) Create Mailboxes 3) Create Distribution Groups 4) Create Shared Mailboxes 5) Create Rooms 6) Populate email 7) Populate calendars 8) Populate Tasks 9) DLP Policy Creation 10) Create retention Policies 11) Configure quotas 98) All of the above 99) Exit Select an option.. [1-99]? '@
Create Databases and Replicas
In this section of the script (Menu Option 1) we have database creation and an option to create replicas. For now the script will ask for a number of databases and create a rather generically named set of databases (i.e. database1, database 2, etc.). After the databases are created, the script will also ask if replicas are required. The replicas will be created on each mailbox server. Once complete, the script will go back to the main menu.
# Database Creation function create-database { # Create Databases $srvcount = (get-mailboxserver).count $dbcount = (get-mailboxdatabase).count write-host "Currently there are $srvcount Mailbox Servers with $dbcount databases." # New databases will be put on the first server and replicas on other servers $newdb = read-host "How many more databases do you want to create?" $dbloc = read-host "What directory do you want to use for mailbox database files(i.e. d:\exchange\databases)" if ((test-path $dbloc) -eq $false) { write-host "" write-host "Creating file location for database files." -foregroundcolor green mkdir $dbloc write-host "" } $logloc = read-host "What directory do you want to use for mailbox database logs (i.e. d:\exchange\logs)" if ((test-path $logloc) -eq $false) { write-host "" write-host "Creating file location for log files." -foregroundcolor green mkdir $logloc write-host "" } $n = 1 while (($n-1) -lt $newdb) { $dbname = "database"+$n $edbname = $dbname+".edb" $edbfilepath = $dbloc+"\"+$edbname $logpath = $logloc+"\"+$dbname $server1 = (get-mailboxserver).name $server = $server1[0] if ((get-mailboxdatabase $dbname -erroraction silentlycontinue) -eq $null) { new-mailboxdatabase -name $dbname -edbfilepath $edbfilepath -logfolderpath $logpath -server $server } else { $dbname = "database"+$n+"a" $edbname = $dbname+".edb" $edbfilepath = $dbloc+"\"+$edbname $logpath = $logloc+"\"+$dbname new-mailboxdatabase -name $dbname -edbfilepath $dbloc+"\"+$edbname -logfolderpath $logpath -server $server } $n++ } # Validate DAG existence $DAGExistence = get-databaseavailabilitygroup if ($DAGExistence -ne $null) { # Create replicas $n = 1 $databases = get-mailboxdatabase foreach ($line in $database) { $mailserver = get-mailboxserver while ($n -lt $srvcount) { $ap = $n+1 $n2 = $n-1 $server = $mailserver[$n2] add-mailboxdatabasecopy -identity $line.name -activationpreference $ap -server $server } } } else { CLS write-host "No Database Availability Group (DAG) exists so no replicas will be created." -foregroundcolor red } cls write-host "Database creation step complete." -foregroundcolor green write-host " " } # end database and replica creation
Create Mailboxes
This portion of the script will create numerous mailboxes based off a CSV file I’ve constructed with first and last names from lists of popular names over the past century. The mailboxes will add a user account in the default Users OU and create mailboxes in each database as evenly as possible. There is no option for deciding how many mailboxes in this version, but it will be in a future version of the script.
# Create mailboxes function create-mailboxes { # mailboxes will be created in all available databases $track = 0 $database = (get-mailboxdatabase).name $password = read-host "Enter password" -AsSecureString $dbcount = (get-mailboxdatabase).count $domain = read-host "Enter a domain to be used for SMTP routing" $source = import-csv c:\temp\names.csv foreach ($line in $source) { $first = $line.first $last = $line.last $upn = $first+"."+$last+"@"+$domain $alias =$first+"."+$last $displayname = $line.first+" "+$line.last if ((get-mailbox $upn -erroraction silentlycontinue) -eq $null) { new-mailbox -userprincipalname $upn -alias $alias -database $database[$track] -displayname $displayname -Firstname $first -lastname $last -name $alias -password $password $track++ if ($track -ge $dbcount) { $track = 0 } } else { write-host "There is already a mailbox with the UPN of " -nonewline write-host $upn -foregroundcolor red } } cls write-host "Mailbox step complete." -foregroundcolor green write-host " " }
Create Distribution Groups
When creating DL’s for the lab environment, the script will ask for how many groups and if the groups should be populated with random mailboxes (which requires mailboxes to be present – although there is no error checking on this). The DLs are then created and members are added if requested (1 to 10 members).
function create-distributiongroups { $dlcount = read-host "How many distribution groups would you like to create" $members = read-host "Do you want to populate the distribution groups with random members [y or n]" if ($members -eq "n") {write-host "OK. Blank Distribution groups will be created." } else { write-host "OK. Will populate distribution groups with 1 to 10 members." } $alias1 = "DistributionGroup" $displayname1 = "Distribution Group " $dlcounter = 1 while ($dlcounter -lt $dlcount) { $displayname = $displayname1+$dlcounter $alias = $alias1+$dlcounter new-distributiongroup -name $displayname -displayname $displayname -alias $alias -type distribution $dlcounter++ if ($members -eq "y") { $mailboxes = get-mailbox $NumOfMembers = get-random -minimum 1 -maximum 10 while ($NumOfMembers -lt 10) { $usercount = (get-mailbox).count $usernum = get-random -minimum 0 -maximum $usercount $member = $mailboxes[$usernum] add-distributiongroupmember -identity $alias -member $member -erroraction silentlycontinue $numofmembers++ } } } cls write-host "Distribution Groups step complete." -foregroundcolor green write-host " " }
Create Shared Mailboxes
Creating Shared Mailboxes is a similar process to the mailbox creation in that it relies on a pre-created text file. No permissions are assigned with the script in this iteration. A future wish list item would be to randomized permissions for testing.
# Create Shared Mailboxes function create-sharedmailboxes { # mailboxes will be created in all available databases $track = 0 $database = (get-mailboxdatabase).name $password = read-host "Enter password" -AsSecureString $dbcount = (get-mailboxdatabase).count $domain = read-host "Enter a domain to be used for SMTP routing" $source2 = import-csv c:\temp\sharedmailboxes.csv foreach ($line in $source2) { $upn = $line.name+"@"+$domain $alias = $line.name new-mailbox -userprincipalname $upn -alias $alias -database $database[$track] -displayname $alias -name $alias -password $password -shared $track++ if ($track -ge $dbcount) { $track = 0 } } cls write-host "Shared mailboxes step complete." -foregroundcolor green write-host " " }
Create Rooms
Creating Room Mailboxes is a similar process to the mailbox creation in that it relies on a pre-created text file. No permissions are assigned with the script in this iteration. A future wish list item would be to randomized permissions for testing.
# Create Rooms mailboxes function create-roommailboxes { # mailboxes will be created in all available databases $track = 0 $database = (get-mailboxdatabase).name $password = read-host "Enter password" -AsSecureString $dbcount = (get-mailboxdatabase).count $domain = read-host "Enter a domain to be used for SMTP routing" $source2 = import-csv c:\temp\roommailboxes.csv foreach ($line in $source2) { $upn = $line.name+"@"+$domain $alias = $line.name new-mailbox -userprincipalname $upn -alias $alias -database $database[$track] -displayname $alias -name $alias -password $password -room $track++ if ($track -ge $dbcount) { $track = 0 } } cls write-host "Room mailboxes step complete." -foregroundcolor green write-host " " }
Populate Email
For email data population the goal is to have a set number of mail message sent by each and every user to each and every user in Exchange. Just exactly how many messages is up to you as the script will ask you for that number.
# Populate Mailboxes with Email function populate-email { write-host " " write-host "Gathering valid mailboxes for recipient and/or sender of test emails." -foregroundcolor yellow write-host " " $mailboxes = Get-Mailbox -Filter 'RecipientTypeDetails -eq "UserMailbox"' -resultsize unlimited $sendercount = (get-mailbox -resultsize unlimited).count $copies = read-host "How many test email messages to be sent per sender" $transport = (get-transportservice).name $counter = 0 while ($counter -lt $sendercount) { $sender = $mailboxes[$counter].primarysmtpaddress $from = $sender.local+"@"+$sender.domain $counter2 = $counter+1 $recipient = $mailboxes[$counter].primarysmtpaddress $to = $recipient.local+"@"+$recipient.domain $subject = "Populating email from $sender to $recipient" $body = "This is a test message to help populate email in the mailboxes on Exchange 2013." # Need to add an attachment line here --> needs to include the option to pick an attachment $msgcount = 0 while ($msgcount -lt $copies) { send-mailmessage -from $from -to $recipient -subject $subject -body $body -smtpserver $transport[0] $msgcount++ } $left = $sendercount-($counter+1) write-host " " write-host "Test emails to $recipient and from $sender are complete. Only $left more email tests to run." -foregroundcolor green write-host " " $counter++ } write-host "Email population step complete." -foregroundcolor green write-host " " start-sleep 10 cls }
Further Information
This script is meant for a lab environment. It does require some source files to help populate mailboxes. I’ve included a few fixes, however I am not checking for all possibilities when creating mailboxes, databases, etc. There is no undo button for the actions taken.
Go ahead and download the script from here. When the script is completely fleshed out and more advanced features are added, the script will be posted to TechNet Wiki.