For a long time now I’ve wanted to write a script that would automatically generate email traffic within an Exchange Server test lab environment.
Having realistic email traffic within a test lab environment means you can do such real world activities as:
- test backup and recovery scenarios
- learn how to use message tracking logs
- test archiving solutions
In the past I’ve used some simple VBScripts that just sent random messages via SMTP as a way to fill up test lab mailboxes. That approach had some disadvantages though. The scripts I wrote only sent a stream of email messages at a single rate rather than at varying rates through the day as you would see in the real world. They also filled up inboxes only, never putting the messages in the Sent Items folder for the From address.
So last week I got to work creating a new PowerShell script to generate the email traffic. I tracked some of the development in the forums and can now share the complete script here.
This script does require some setting up before you run it, so please read the instructions to get it working in your test lab. I have only written and tested this script for Exchange 2010 training lab environments on the assumption that most people will be training for the latest version of Exchange.
Before we go further let me be absolutely clear that this script is for test lab environments only. Under no circumstances should you attempt to run this script in a production environment.
Using the Start-MailGen.ps1 Script in Your Test Lab
The scripts uses the Exchange Web Services Managed API so the first step is to download and install that on your test lab server.

EWS Managed API
Next, download the script and extract the three files to your server. I placed mine in C:\Scripts\MailGen.
Download the script file here: Start-MailGen.ps1 (downloaded 1237 times so far)
Open the Start-MailGen.ps1 file in the PowerShell editor or in Notepad and check the following items.
The $dllfolderpath variable is set to the default installation path for the EWS Managed API v1.1. If you install a different version, or to a different path, update this variable.
#Path to the Exchange Web Services DLL $dllfolderpath = "C:\Program Files\Microsoft\Exchange\Web Services\1.1\Microsoft.Exchange.WebServices.dll"
The script uses a switch statement to determine how many emails to send each hour of the day. These values are what I use but you can change them up or down to suit your test lab. The hours 6am to 7pm are individually specified, and then the default value at the end is used for the remaining hours of the day.
06 {$sendcount = 50}
07 {$sendcount = 80}
08 {$sendcount = 600}
09 {$sendcount = 600}
10 {$sendcount = 800}
11 {$sendcount = 1000}
12 {$sendcount = 600}
13 {$sendcount = 600}
14 {$sendcount = 800}
15 {$sendcount = 800}
16 {$sendcount = 900}
17 {$sendcount = 400}
18 {$sendcount = 200}
19 {$sendcount = 80}
default {$sendcount = 10}
You can just specify even numbers like the above because the script varies the send count further by adding a random number each time. This will give you a realistic level of email traffic through the different hours of the day.

Sample email traffic graph
The service account that will be running the script needs impersonation rights granted to it. I run mine as Administrator since it is just a test lab. Open the Exchange Management Shell and run the following command to grant the impersonation rights.
[PS] C:\>New-ManagementRoleAssignment -Name:impersonationAssignmentName -Role:ApplicationImpersonation -User:administrator
You may also need to set your script execution policy to unrestricted.
[PS] C:\>Set-ExecutionPolicy Unrestricted
Also, as the script file was downloaded from the internet you may need to right-click the file and choose Properties, and then click the Unblock button.
The script also depends on the Active Directory remote administration tools. These should be installed already on an Exchange 2010 mailbox server, but if you’re running the script from a non-Exchange server you may need to install them.
Finally, to start generating email traffic open the Exchange Management Shell and run the script.
[PS] C:\Scripts\Mailgen>.\Start-MailGen.ps1
The script begins to send email and will show a progress indicator.

Start-MailGen.ps1 running
The script will select a random sender and recipient from the available mailboxes in your test lab environment, and then construct a random email message using the two files that are provided with the script.
After sending the applicable number of emails for that hour of the day the script will sleep for 5 minute blocks until it reaches the next hour, and will start sending again.
You can leave the script running for several days if you wish, or set it as a scheduled task to ensure that it starts up again if the server is rebooted.
How to Hard-Code the EWS URL
A few people have seen Autodiscover errors in their test lab and, if they have verified that Autodiscover is otherwise working fine, may need to look at hard-coding the EWS URL in the script. To do so find the following line and comment it out with the hash character:
#$service.AutodiscoverUrl($user.Properties.mail)
Now add a new line below it with the following:
$service.Url = "https://ho-ex2010-mb1.exchangeserverpro.net/EWS/Exchange.asmx"
Replace the URL above with the appropriate server FQDN for your own server environment.




Love this! will help so much in terms of testing and developing.
Great article Paul! It will be very helpfull for my labs. Thanks you.-
Thank you so much Paul, I was looking for something like this. Will tell you once tried in my lab.
Hi Paul,
Thanks for the info. I will be setting up my test lab this weekend and I will let you know how it goes.
Cheers.
TP
Thank so much and it is very important for me
Hollo Paul,
This is the error I’m getting while running.. DC on win 2k3 server and Exch 2010 typical roles installed on win 2008 R2. I could not find the solution for this over the internet.. Please suggest me.
************************************************************
[PS] C:\Paul>.\Start-MailGen.ps1
WARNING: Error initializing default drive: ‘Unable to find a default server with Avtive Directory Web Services running.’.
Retrieving mailbox list
Preparing EWS
Exception calling “AutodiscoverUrl” with “1″ argument(s): “The Autodiscover service couldn’t be located.”
At C:\Paul\Start-MailGen.ps1:245 char”25
+ $service.AutodiscoverUrl <<<< ($user.Properties.mail)
+CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+FullQualifiedErrorId : DotNetMethodException
Starting email generation
*** Will send 615 emails this hour
Exception calling "SendAndSaveCopy" with "0" argument(s): "The Url property on the ExchangeService object must be set."
At C:\Paul\Start-MailGen.ps1:245 char"23
+ $mail.SendAndSaveCpy <<<< ()
+CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+FullQualifiedErrorId : DotNetMethodException
*********************************************************
If you’re not running a 2008 R2 domain controller I believe you need to install this on your DC.
http://www.microsoft.com/download/en/details.aspx?id=2852
Thanks for the reply. Sure I will try tonight and let you know the result.
Paul,
Great script – I have been looking for something like this. I have been using this script for the past 2 days and I’m very impressed by the amount of work you put in to generate the script.
My only comment is this: How about using a text file to log all that information that we “write-host” – For two reasons :
a) we can review later if we need to, especially if there are errors – this one just scrolls by and we cannot see it anymore.
b) aslo it frees up screen and runs at the background.
Just my thoughts.
Thanks for the sharing it with us.
Seems like a good idea. I’ll try to include that in the next version.
I am getting this error.
[PS] C:\Scripts\Mailgen>.\Start-MailGen.ps1
Retrieving mailbox list
Preparing EWS
Exception calling “AutodiscoverUrl” with “1″ argument(s): “The Autodiscover service couldn’t be located.”
At C:\Scripts\Mailgen\Start-MailGen.ps1:245 char:25
+ $service.AutodiscoverUrl <<<< ($user.Properties.mail)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Running Exchange on DC with Win 2008 R2.
Does the account that you’re using to run the script have a mailbox?
Sorry for the delay
Iam using administrator account and having mailbox.
Hi paul,
It is working fine.
Thank You for your script.
Raj
Hi Paul,
I’m getting the same error as above and the account does have a mailbox.
You could try hard coding the Autodiscover URL instead of the script trying to discover it.
Hello Paul –
What could be causing this;
Exception calling “SendAndSaveCopy” with “0″ argument(s): “The mailbox that was requested doesn’t support the specified
RequestServerVersion.”
At C:\Scripts\MailGen\Start-MailGen.ps1:186 char:23
+ $mail.SendAndSaveCopy <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
I had the same problem and explicitly specifying version of exchange server fixed it:
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService(“Exchange2010_SP1″)
Other possible values:
http://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.exchangeversion%28v=exchg.80%29.aspx
Where I found out about this argument:
“Note that the EWS Managed API 1.1 defaults to Exchange2010_SP1 as the Exchange version that it is connecting to. If you are running another version of Exchange or another service pack, you must specify the correct version by passing the ArgumentList parameter to New-Object.”
http://blogs.technet.com/b/heyscriptingguy/archive/2011/12/02/learn-to-use-the-exchange-web-services-with-powershell.aspx
Hi Paul ,
Create Efforts
but I got the following error
Exception calling “SendAndSaveCopy” with “0″ argument(s): “The mailbox that was requested doesn’t support the specified RequestServerVersion.”
knowing that version of EWSManged API is 1.2
I successfully solved that error ,I used EWSManaged API version 1.1 instead of 1.2 and your script works fine …the old version (1.1) was not found on Microsoft download center anymore..But got it from “Mike Pfeiffer” Blog “http://www.mikepfeiffer.net/downloads/ExchangeLab.zip” under “bin” folder
I’ll try and update the script for v1.2 if the 1.1 is going to be unavailable for people :-/
Hi Paul
I am getting the same error message but I am unsure how to hard code the URL can you help me out?
Exception calling “AutodiscoverUrl” with “1″ argument(s): “The Autodiscover service couldn’t be located.”
At C:\Scripts\Mailgen\Start-MailGen.ps1:245 char:25
+ $service.AutodiscoverUrl <<<< ($user.Properties.mail)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Thanks
Geoff
Hi Geoff (and others),
Firstly I would double-check that Autodiscover is working at all in your test lab. If there is anything wrong with it, or your SSL cert, then try fixing that first.
Other than that, I am planning to update the script for compatibility with the EWS API v1.2, so I will look to include the manually specified Autodiscover URL option in the next version. Hopefully not far away.
Actually I’ve just added a note to the end of the article with the required script edits to hard-code the URL, if you’re looking for a quick win.
Thanks Paul that helped that problem but now I am having to find out why I am having a permissions/trust Exception calling “SendAndSaveCopy” with “0″ argument(s): “Request failed. The underlying connection was closed: Could not establish trust relationship fo
r the SSL/TLS secure channel.”
Some times this stuff makes me pull my hair out.
Thanks again for your help
Geoff
Geoff, that sounds like a certificate issue to me. The same issue is probably why Autodiscover isn’t working in the first place.
How does one solve this issue?
By installing a valid certificate. It can be from a private CA if its just for a test lab.
http://exchangeserverpro.com/exchange-2010-ssl-certificates
Thanks Paul,
I was able to follow your article and others of your articles about SSL for exchange. Once set up a CA and made a signed cert, then it all worked great. Thanks for making good scripts and such easy and excellent articles. They’re detailed and easy to read. Thanks. Keep up the good work
Paul this is so cool, i can’t thank you enough for this article en the scripts to put a mail load on a
lab test environment.
Very …..very much appriciated was looking for this for quite some time
Nice script, very useful.. Thank you for your time spent.
I’ve been trying to modify the sender to be able to exclude certain addresses, without much sucess. Any pointers would be appricated.
Regards
Gary
This line in the script fetches the list of mailboxes to include.
$mailboxes = @(Get-Mailbox -RecipientTypeDetails UserMailbox -resultsize unlimited)
So you can just modify that Get-Mailbox any way you like to exclude the ones you don’t want. Help info for Get-Mailbox is here:
http://technet.microsoft.com/en-us/library/bb123685.aspx
One way would be to use the -OrganizationalUnit parameter to just get the users in a specific OU, and have the ones you want to exclude be outside of that OU.
Thanks Steve.
It was that simple!
Must make note to self to get head round powershell.
Thanks again.
regards
Gary
Thanks Paul. (no idea why I typed Steve !, to much Red wine)
It was that simple!
Must make note to self to get head round powershell.
Thanks again.
regards
Gary
I’ve made significant progress in getting this script to run in my lab environment. However, I’m now receiving the following error.
I’m running Exchange 2007 with a Windows 2008R2 DC in the environment. I have worked through several other issues but unable to resolve this one.
Any assistance would be great appreciated!
[PS] D:\scripts\mailgen>D:\Scripts\Mailgen\Start-MailGen.ps1
Retrieving mailbox list
Preparing EWS
Starting email generation
*** Will send 822 emails this hour
Exception calling “SendAndSaveCopy” with “0″ argument(s): “An element node ‘soa
p:Envelope’ of the type Element was expected, but node ‘Autodiscover’ of type E
lement was found.”
At D:\Scripts\Mailgen\Start-MailGen.ps1:186 char:23
+ $mail.SendAndSaveCopy <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Hi Eric, I’ve done no testing against Exchange 2007 with this script. I only use it in Exchange 2010 test lab environments.
Paul,
Thanks for the update. I am one step closer to making this work. The problem that was listed above was because I was pointing to the Autodiscover.xml file and it was looking for the ews/exchange.asmx file. Once I pointed that correctly then it is now giving me the error “Exchange Server doesn’t support the requested version.” and I believe that is because I’m running API v1.2 instead of v1.1. Any assistance on finding or obtaining a copy of v1.1 would be greatly appreciated.
Eric
Paul,
First, thank you very much for your time and efforts on this. I have been trying to get this working in a test environment for a couple of days now, and am running into an error that I have not been able to solve. I have a 2008 R2 DC, and a 2008 R2 mail server with Exchange 2010 SP1. I believe I have autodiscover configured correctly, and am using the self signed certificate from the Excahnge server. I have added it to the Trusted Root CA store on the server as well. I installed Exchange Web Services Management API version 1.2 as I could not find version 1.1. When I run the script, I am getting the following:
Retrieving mailbox list
Preparing EWS
Starting email generation
*** Will send 867 emails this hour
Exception calling “SendAndSaveCopy” with “0″ argument(s): “Exchange Server doesn’t support the requested version.”
At C:\scripts\Start-MailGen.ps1:186 char:23
+ $mail.SendAndSaveCopy <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Any ideas?
Thanks again,
Russ
I believe that the API v1.2 requires Exchange 2010 SP2.
Does anyone know where I can get a copy of API v1.1? Everywhere i’m looking all I can find is 1.2 or higher. I’ve almost got Exchange 2007 to work but now i’m receiving the same error “Exchange Server doesn’t support the requested version.” I believe with API v1.1 I will have it functioning correctly and will post the changes that were needed in order to make it work.
Hey Paul,
I executed the following command first and still get the error below. Any idea? By the way, I am using Exchange Web Services Managed API 1.1
[PS] C:\>New-ManagementRoleAssignment -Name:impersonationAssignmentName -Role:ApplicationImpersonation -User:administrator
Exception calling “SendAndSaveCopy” with “0″ argument(s): “The account does not have permission to impersonate the requested user.”
At C:\Scripts\Mailgen\Start-MailGen.ps1:186 char:23
+ $mail.SendAndSaveCopy <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
After granting impersonation rights you’ll need to start a new shell session for it to take effect.
Perfect! That was it. Thanks so much. Its a great script! Any idea when this script will work with Exchange Web Services Managed API 1.2?
If you’re running Exchange 2010 SP2 I think it actually does work fine with the EWS v1.2, you just need to update this variable in the script with the correct path: $dllfolderpath
Paul!
is there a way this script can be modified to target mail enabled public folders? i am trying to prove a point for a customer who has 1000+ public folders and they want to upgrade to 2010!
*** I’ll repeat the warning not to use this script in production environments. ***
On line 236 is the code that determines the mailboxes that are used by the script. You could probably modify that to get mail-enabled public folders instead.
its in a demo environment that is no where near the live environment!
i have tried that but get a long list of errors! it does however pick up the names of the public folders..
“cannot process argument transformation on parameter ‘Identity’. Cannot convert the “PUBLICFOLDERNAME” value of type “Microsoft.Exchange.Data.Directory.Management.MailPublicFolder” to type “Microsoft.Exchange.Configureation.Tasks.MailboxIdParameter”
any ideas?
Hi Paul,
Well I got the script working and ran it for a bit but let it set for a few weeks and now when I try and run the script I get the following error,
Get-Random : Minimum (0) cannot be greater than or equal to Maximum (-1).
At C:\scripts\mailgen\Start-MailGen.ps1:148 char:20
+ $rand = Get-Random <<<< -Minimum 0 -Maximum ($mailboxcount – 1)
+ CategoryInfo : InvalidArgument: (:) [Get-Random], ArgumentException
+ FullyQualifiedErrorId : MinGreaterThanOrEqualMax,Microsoft.PowerShell.Commands.GetRandomCommand
Thanks
Geoff
I would say $mailboxcount is returning 0 for some reason. I assume you’ve still got mailbox users in your test lab?
Hi Paul
Yes I still have mailboxes configured in my test environment
thanks
Geoff
Well Paul, I found my problem. I discovered that I was using the wrong power shell, what a bonehead mistake. its been a long week.
However I get this new error
[PS] C:\scripts\mailgen>.\Start-MailGen.ps1
Retrieving mailbox list
Preparing EWS
Starting email generation
*** Will send 692 emails this hour
Exception calling “SendAndSaveCopy” with “0″ argument(s): “The request failed. The underlying connection was closed: An unexpected error occurred on a sen
d.”
At C:\scripts\mailgen\Start-MailGen.ps1:186 char:23
+ $mail.SendAndSaveCopy <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Any ideas where I might find why it is getting a send error?
thanks
Geoff
Something interrupting the SMTP connection to the Transport server you’ve configured in the script variables?
If you test it with Telnet does it work?
Hi Paul
That is what it appeared to me as well but I can telnet into port 25 and it responds back fine
Thanks
Geoff
Thanks for the tip Paul! I installed SP2 on my test server and the script is now running great!
Do you think it would be possible to run this against at test environment on Microsoft Live@edu?
No.
Has anyone tried this script with Exchange 2013? I need to do some load testing with Exchange 2013 and I’m trying to find tools other than loadsim. This tool works great on Exchange 2010!
Thanks
yes! and it works.. well i had to tweak some things..
i did all of the above, but i was seeing some SendAndSaveAs issues.
i hashed # out
#$mail = New-Object Microsoft.Exchange.WebServices.Data.EmailMessage($service)
#$mail.Subject = $emailSubject
#$mail.Body = $emailBody
#$mail.From = $EmailSender
#[Void] $mail.ToRecipients.Add($EmailRecipient)
#$mail.SendAndSaveCopy()
and added this directly underneath
Send-MailMessage -SmtpServer FRONTENDCAS -From $emailsender -To $EmailRecipient -Subject $emailSubject -Body $emailBody
it was a long shot but it works..
Paul, hope you don’t mind
That will work but its just sending with SMTP so it doesn’t save the item to the sender’s Sent Items, isn’t as useful for generating test traffic for message tracking etc, doesn’t necessarily use multiple HT’s if available, etc etc. Depends whether you need all that or just the ability to send a bunch of raw traffic around.
Paul – do you have a suggestion for how to make this work correctly on Exchange 2013? I did make the changes that Sam suggested and that’s working, but I’d like items to be logged in the sent items if possible. Thanks!
I imagine for Exchange 2013 it will be a simple case of using the latest EWS API DLL and updating the script variable that points to the DLL path. But I haven’t had a chance to test that yet.
I did get this to work on 2013. I had quite a few issues and saw lots of different errors (most of the ones talked about above and a few more) but they were all issues with my lab…mostly caused by a DNS issue on my DC. After resolving those and undoing all the hacks I was doing to the script trying to get it to work, it works like a champ.
To get it to work after other issues were resolved, I just had to update the path to the EWS DLL that’s included in 2013 and it does work as expected. Thanks for this awesome script, it’s going to make my 2013 eDiscovery testing much easier.
Great, thanks for letting us know. And yes, eDiscovery testing is exactly the type of thing this script is designed to create realistic looking traffic for, so that is awesome
Amazing work buddy!
Just add impersonation part to the prerequisite in the script itself, rest is awsome!
Cheers!!!!
Using this script with slight modification, Is there a way to add attachments from a given set of attachment types (.txt, .doc, .img etc)???
I’m sure its possible I just haven’t looked into it. It would be handy though, I might try and include it in the next version.
Is attachment thing possible??