PowerShell: Search for a contact within a mailbox (or multiple mailboxes) No ratings yet.

The attached script shows how to use EWS to search for a particular contact (based on email address) within one or more mailboxes, writing any found occurrences to a log file.  You can process multiple mailboxes in a couple of ways (well, there are probably other alternatives too, but these should cover most requirements!).


Processing mailboxes using Exchange Management Shell

You can use the Exchange Management Shell to retrieve mailboxes and then send to the script.  To do so, you need to run the script from the shell, or import a remote Exchange session into a standard PowerShell session (change the ConnectionUri parameter to an appropriate URL for your system):

$c = Get-Credential
$S = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://ex15cas1.hybrid.local/powershell/ -Credential $c
Import-PSSession $S

The mailboxes can then be processed as follows:

$m = Get-Mailbox
$m | ForEach-Object {
  .\Search-Contacts.ps1 -Mailbox $_.PrimarySmtpAddress -ContactEmail Leesa.Barela@nowhere.com -LogFile “c:\temp\log.txt” -impersonate

You can modify Get-Mailbox accordingly to return just a subset of mailboxes (e.g. limit to database, OU, etc.).


Processing mailboxes using a list of mailboxes

The script can also accept a text file containing the list of mailboxes to be processed (one email address per line in the text file):

.\Search-Contacts.ps1 -Mailbox “c:\temp\mailboxes.txt” -ContactEmail Leesa.Barela@nowhere.com -LogFile “c:\temp\log.txt” -impersonate

In the above, mailboxes.txt contains the list of mailboxes.


The log file (in the above examples, this is c:\temp\log.txt) will contain details of any mailbox that had a contact with the given email address.


Script parameters (complete list)


-Mailbox: the SMTP address of the mailbox being searched, or the location of a text file containing a list of mailboxes

-ContactEmail: the email address that we are searching for

-Delete: if specified, any contact found with this email address will be deleted

-Username: the username for authenticating with EWS (if missing, default credentials will be used)

-Impersonate: if specified, use impersonation to access the mailbox.  This is required if you are accessing a mailbox that does not belong to the authenticating account

-EwsUrl: if specified, this will be used for all EWS request (if missing, autodiscover is used to determine the correct URL for the mailbox)

-EWSManagedApiPath: the path to the EWS Managed API – this shouldn’t be needed as the script searches all default install locations.  Only necessary if not in default location.

-IgnoreSSLCertificate: ignore certificate errors (required if you are using self-signed certificates that are not trusted by the local machine)

-AllowInsecureRedirection: Whether to allow insecure redirects when performing autodiscover

-LogFile: search results and actions taken are logged to this file if specified


Please rate this


2 thoughts on “PowerShell: Search for a contact within a mailbox (or multiple mailboxes)

  1. Hello David,
    I am looking for smart way how to change contact email in all user mailboxes on Exchange 2010. Our main partner has changed their domain, so I need to search all contacts in all user mailboxes with certain domain and change the contact email to desired one. I have tried your script, but parameter ContactEmail does not allow *. Do you know, is possible to use asterix for searching in EWS query ?
    Thank you very much for your time and help.
    Regards Aleš Fíla

    1. You could potentially use the ContainsSubstring comparison (https://docs.microsoft.com/en-us/dotnet/api/microsoft.exchange.webservices.data.searchfilter.containssubstring?view=exchange-ews-api) to check for the domain name, though would need to double-check that this works on email properties.

      In this case, it might be better to simply read all of the contacts from each mailbox and perform the validation client-side (i.e. check each of the EmailAddress properties for the old domain using string comparison on the client). You could do FindItems to return all contact items (limiting to just the email addresses and ids, as you aren’t interested in anything else), and then simply update any that require it.


Leave a Reply

Your email address will not be published. Required fields are marked *