Powershell Script to Delete Exchange Mailboxes in Mass

By Request: How to delete a large number of mailboxes at once.

First, and I can not stress this enough, this script has the potential to delete production data, namely user and Exchange mailboxes. Please carefully consider the impact of this script before you use it. Make sure you have good backups of your User Accounts and Exchange Mailboxes before use. If it doubt, test with a single account before hand and/or use the -whatif flag. (More about this below) Ok now then, on to the good stuff.

There are a few ways you might approach the task of deleting mailboxes. Much of that comes in the form of how you come up with the list of mailboxes and/or users to delete.

This example assumes the following approach:

  • You are creating a text file with a list of accounts to remove.
  • You want to delete both the user and the mailbox.

So then to create a list of user and their mailboxes you want to delete, simply place a list of users in a text file one user per line. You might fetch the list using a Get-QADuser or Get-Mailbox as a filter, more on this later.

Example text file:



Call the file MailboxesToDelete.txt and we’ll assume its on the C:\ drive.  Then create a script to run, in this example I’ll call it Delete_Mailboxes.ps1

#Add Exchanage snapin
add-pssnapin Microsoft.Exchange.Management.PowerShell.Admin

#Get list of mailboxes to delete
$users=Get-Content C:\MailboxesToDelete.txt

#For Loop to delete them
foreach ($user in $users)
#Print to screen user mailbox to delete
#Delete AD user and Mailbox
Remove-Mailbox -Identity $user -Permanent $true -whatif

#Remove the -whatif if you want to really delete some users.

That is pretty much it.

You should then be able to type [PS]C:> Delete_Mailboxes.ps1 and delete users and their mailboxes based on the text file.

You might also, assuming you have some search criteria, use the Get-QADuser or Get-Mailbox command to filter out the list of users. Say all of those in a specific OU and turn this into a single one liner.


Get-QADUser -SearchRoot 'OU=INTERNATIONAL OFFICE USERS,DC=contoso,DC=com' | Remove-Mailbox -Identity $user -Permanent $true

Or you could use my script and simply Get-QADUser -SearchRoot ‘OU=INTERNATIONAL OFFICE USERS,DC=contoso,DC=com’ >> C:\MailboxesToDelete.txt and then run the above script. Again there are many ways to approach the actual search/list creation. This is just a few ways you might do it.

Be warned:
The -Permanent $true will not only delete the mailbox, it will also delete the user. If you don’t want the user account deleted and just the mailbox just remove -Permanet from the above or set it to $false.

If you just want to test at the end of the Remove-Mailbox statement put a -whatif at the end of the line.

Remove-Mailbox -id jsmith -whatif

I added “-whatif” to the script to hopefully save someone some pain while testing.  Remove it only when you are ready to actually delete some data.

Please reference: Technet if you have questions about the Remove-Mailbox command, it is a delete command so use with care.


Exchange 2007 – Adding a user that use to be a Contact in Exchange can cause some Outlook Cache issues.

So over the past weekend I migrated some international users to our mail server and found these users had issues sending mail to each other as well as a similar issue with folks in the office.

The symptom shows up like this, when a user tries to send a email to a previously known address they get a kick back email that looks like the one below.

Delivery has failed to these recipients or distribution lists:

The recipient’s e-mail address was not found in the recipient’s e-mail system. Microsoft Exchange will not try to redeliver this message for you. Please check the e-mail address and try resending this message, or provide the following diagnostic text to your system administrator.

Sent by Microsoft Exchange Server 2007
Diagnostic information for administrators:

Generating server: COHT1.nsanet.local

#550 5.1.1 RESOLVER.ADR.ExRecipNotFound; not found ##


The last line here is the clue that this is a Outlook Cache issue.  Whats going on is auto complete, while looking correct to the user, on the back side is sending the path to the users AD contact which is no longer validate.  The fix is really simple.

1st: Make sure you have updated the Global Address Book or Offline Address book (Different names = same item)

2nd: Clean up Cache in Outlook, there are two methods which I’ll not cover here but here is the link on what to do.


Or the one liner to clean it up.

Outlook.exe /CleanAutoCompleteCache


Set AD Email Address to PrimarySmtpAddress in matching Exchange Contact

I wrote this little script to address a issue where another admin/help desk/etc created a bunch of exchange contacts for external users and then later we ended up creating some AD accounts for some of those users so they could access some Linux/Unix systems we host. However we ran into a issue where those users had no way to be notified of password’s expire. So to address that I wrote this script Powershell Script to Notify Users of Expired or About to Expire Passwords in Active Directory which worked fine but then I found I couldn’t email some users because I didn’t have a email address for them. I did however have an exchange contact for some of them. So I wrote the follow script to copy their emails from the exchange contact into the AD Email attribute.

Requirements to run script:

Other Notes:
You will see some errors with this script if the Get-MailContact fails to find any info for the user in question. This is ok and is expected.

#Add Snapins
Add-PSSnapin "Quest.ActiveRoles.ADManagement" -ErrorAction SilentlyContinue

$users = Get-QADUser -SearchRoot 'OU=INTERNATIONAL OFFICE USERS,DC=domain,DC=net' -Enabled -PasswordNeverExpires:$false | where {($_.Email -eq $null)}

Foreach ($user in $users)
	$contact = Get-MailContact -Identity $user.Name
	if ($contact -ne $null)
		Set-QADUser $user.Name -Email $contact.PrimarySmtpAddress

How to fix the issue of a user not showing up in the Global Address book.

This little one liner can possibly fix a issue where a user doesn’t show up in the Global Address book.

To run the following powershell script, you must be a Domain Admin and an Exchange Admin.

get-mailbox -resultsize unlimited | Where-Object {$_.PrimarySMTPAddress -ne $_.WindowsEmailAddress} 
| foreach { set-mailbox $_.identity -windowsemailaddress $_.primarySMTPAddress }

This Script will set the Email address field found in Active Directory Users and Computers for a User/Object that has a email account in Exchange to the same value as that set in Exchange as that of the User/Object’s primary SMTP email address.

This will fix the issues where the users doesn’t show up in the global address book.

Finally after running the script you must update the OAB in exchange and all clients must update their local address books by running send and receive.

MS Technet Support Article

Add permissions to public folders in Exchange 2007

So say you want to add permissions to a large group of public folders. Unlike Windows folders, public folders do not replicate permissions down through a tree. So the trick is to recursively go through the tree and apply permissions to the folders. This can be done with a very simple one liner.

Note:You want to run this on the Exchange server with the Mailbox role that houses the Public Folder database.


[PS] C:\Windows\system32>Get-PublicFolder "\IS Department\Software Installs" -recur 
| Add-PublicFolderClientPermission -user lmichel -accessrights Owner

So if you had a folder structure like

Public Folders
  -> IS Department
        -> Software Installs
            -> Lots of folders
  -> Marketing
  -> etc etc..

Then we just gave jsmith permissions to all of the “Lots of folders” under software installs. If you wanted you could go back a single tree or go further down the tree depending on your needs.

Remove Disconnected Mailbox – Exchange 2007

A simple bit of Powershell to remove a Disconnected Mailbox. Normally Exchange will take care of this itself at the predetermined time as set under Database properties, under the limit tab, via the GUI or via Exchange Powershell

[PS]C:\> Get-MailboxDatabase "ExchangeClusterName\DatabaseName" | fl DeletedItemRetention

Note: You must run this on a mailbox server.

This just tells Exchange to hold onto deleted mailboxes for x number of days at which point permanently delete the mailbox. So that said what if you have a really large mailbox that you want to delete, or a mailbox you want to remove more quickly, for some other reason. In that case you can’t use the Exchange gui to select and delete them, instead you’ll need to ID the disconnected mailbox by its Name and then reference its GUID to delete it. The commands to do so are listed below. Nothing fancy here just two lines of code.

You need to make sure the Exchange\DatabaseName is the one where the mailbox actually was stored otherwise nothing will happen.

[PS] C:\> $Temp = Get-MailboxStatistics | Where {$_.DisplayName -eq "John Doe"}
[PS] C:\> Remove-Mailbox -Database "ExchangeClusterName\DatabaseName" -StoreMailboxIdentity 

Exchange 2007 Powershell Mailbox Export to PST in Mass

So today I was asked to delete a bunch of email accounts off of Exchange that were tied to users that are no longer with the company. Due to the security requirements we follow where I work, we have to maintain a list of users that previously worked for the company. We maintain them in a Disabled User OU in AD to easily ID said users. However we are not required to maintain email for nearly as long, so we were asked to make a backup of the mailbox’s to PST files, just in case, and put them on a drive and into a vault prior to removal of the emails. In this 1st run after the policy was created we found we had a bunch of mailboxes to export so we came up with a simple one liner to do this for us.

To that end we used Powershell to export the users in the “Disabled OU” in AD and find any mailboxes associated with those users and export them.

The requirements to make this work under Exchange 2007 are a bit of a pain if you are running Windows 7 64bit those requirements are listed below.

A Windows 7 32bit machine
Exchange tools (sp1) installed on the local machine
Outlook 32bit installed

Once you have that you can actually run the Exchange Powershell script I used:

[PS] C:\>Get-Mailbox -OrganizationalUnit "domain/Disabled User OU" | 
add-mailboxpermission -accessrights fullaccess -user ADAdminAccount -confirm:$false | 
Export-Mailbox -PSTFolderPath "C:\Path\"

So this script, goes in and retrieves a list of mailboxes in a given OU, grants the user running the script “ADAdminAccount” permission to export the mail, and then exports it to a local drive with one pst file per user in the OU in question. Very handy.