Exchange: Access Mailbox Contacts using PowerShell and EWS
Introduction
This article contains an example of using PowerShell, EWS (Exchange Web Services) and Impersonation, to get contact information for a collection of users. The example in this article demonstrates how to get contacts from a single user's mailbox, while the downloadable code contains an example using functions and collections of custom objects used to store contact information to produce reports.
Source Code
You can download the source code from the Microsoft TechNet Gallery, here: http://gallery.technet.microsoft.com/Get-Contacts-from-Exchange-88efa647
Example - Searching an Exchange mailbox for all contacts that have one or more email addresses.
To work with EWS and PowerShell, you'll need to meet the following requirements
- You need to install the Exchange Web Services API before using the script. This can be installed from here: Microsoft Exchange Web Services Managed API 2.0
- You need to have the Exchange Management tools installed (for this example)
- You need to have Exchange Impersonation privileges to run this script. You can find out more on how to give yourself those permissions, here: http://msdn.microsoft.com/en-us/library/bb204095(EXCHG.80).aspx (you'll only need this if you need to access other peoples mailboxes).
$Identity = Get-Mailbox ima.plonker@company.com
$dllpath = "C:\Program Files\Microsoft\Exchange\Web Services\1.1\Microsoft.Exchange.WebServices.dll";
[void][Reflection.Assembly]::LoadFile($dllpath);
$Service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1);
$mailAddress = $Identity.PrimarySmtpAddress.ToString();
$Service.AutodiscoverUrl($mailAddress);
$enumSmtpAddress = [Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress
$Service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId($enumSmtpAddress,$mailAddress);
$pageSize=100;
$pageLimitOffset=0;
$getMoreItems=$true;
$itemCount=0;
$propGivenName = [Microsoft.Exchange.WebServices.Data.ContactSchema]::GivenName;
$propSurname = [Microsoft.Exchange.WebServices.Data.ContactSchema]::Surname;
$propEmail1 = [Microsoft.Exchange.WebServices.Data.ContactSchema]::EmailAddress1;
$propEmail2 = [Microsoft.Exchange.WebServices.Data.ContactSchema]::EmailAddress2;
$propEmail3 = [Microsoft.Exchange.WebServices.Data.ContactSchema]::EmailAddress3;
$propDisplayName = [Microsoft.Exchange.WebServices.Data.ContactSchema]::DisplayName;
while ($getMoreItems)
{
$view = new-object Microsoft.Exchange.WebServices.Data.ItemView($pageSize,$pageLimitOffset,[Microsoft.Exchange.WebServices.Data.OffsetBasePoint]::Beginning);
$view.Traversal = [Microsoft.Exchange.WebServices.Data.ItemTraversal]::Shallow;
#Added properties to be returned with the query results
$view.PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet($propGivenName,$propSurname,$propEmail1,$propEmail2,$propEmail3,$propDisplayName);
#Added three filter properties for the contacts Email fields (there are three of them).
$searchFilterEmail1 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+Exists($propEmail1);
$searchFilterEmail2 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+Exists($propEmail2);
$searchFilterEmail3 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+Exists($propEmail3);
#Add the filter objects to the filters collection using the OR operator
$searchFilters = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::Or);
$searchFilters.add($searchFilterEmail1);
$searchFilters.add($searchFilterEmail2);
$searchFilters.add($searchFilterEmail3);
#Perform the search against the default Contacts folder, and store the results in a variable
$contactItems = $Service.FindItems([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Contacts,$searchFilters,$view);
#Foreach contact, print the contacts display name and email addresses.
foreach ($item in $contactItems.Items)
{
if ($item.GetType().FullName -eq "Microsoft.Exchange.WebServices.Data.Contact")
{
Write-Host ([String]::Format("************** {0} ******************",$item.DisplayName));
Write-Host "First Name:"$item.GivenName;
Write-Host "Surname:"$item.Surname;
Write-Host "Email 1:"($item.EmailAddresses[[Microsoft.Exchange.WebServices.Data.EmailAddressKey]::EmailAddress1]).Address;
Write-Host "Email 2:"($item.EmailAddresses[[Microsoft.Exchange.WebServices.Data.EmailAddressKey]::EmailAddress2]).Address;
Write-Host "Email 2:"($item.EmailAddresses[[Microsoft.Exchange.WebServices.Data.EmailAddressKey]::EmailAddress3]).Address;
}
}
if ($contactItems.MoreAvailable -eq $false){$getMoreItems = $false}
if ($getMoreItems){$pageLimitOffset += $pageSize}
}
See Also
- ExchangeService class
- Microsoft.Exchange.WebServices.Data class
- ContactSchema class
- SearchFilter class
- Microsoft Exchange Web Services Managed API 2.0
References
- Original content from Matthew Yarlett's blog, Access Mailbox Contacts with PowerShell and EWS (Exchange Web Services)