Category: Exchange

Unified Contacts Store (UCS) Deep Dive

I decided to make a bit of a deep dive inside the UCS (Unified Contact Store) in Lync/Skype for Business.

There are two options to store your contacts – in the Lync/SfB SQL store or in the Exchange mailbox.

For me the SQL store is the less problematic one, migrating users between different pools and Office 365 is less likely to cause a problems.

Option 1: Store in Lync/SfB SQL

SELECT UserAtHost, UpdateTime, InsertTime, ExUmEnabled, UcsMode, UcsMigrationAttemptCount, LastUcsMigrationAttempt FROM [rtc].[dbo].[Resource] as r
    INNER JOIN [rtc].[dbo].[ResourceDirectory] as d on (d.ResourceId = r.ResourceId)
    INNER JOIN [rtc].[dbo].[PresenceHomedResource] as h on (h.ResourceId = d.ResourceId)
--- Optional where clause to check specific users
--- WHERE r.UserAtHost IN ( '', '' )

Option 2: Unified Contact Store in Exchange

MrMAPI.exe -ChildFolders -Folder "IPM_SUBTREE\Contacts"

MrMAPI.exe -Folder "IPM_SUBTREE\Contacts\{A9E2BC46-B3A0-4243-B315-60D991004455}"

Export Contacts from Exchange 2013 (with Impersonate rights)

So this is how I managed to export contacts SMTP addresses from a exchange 2013 mailbox using an admin user with impersonate rights:

#admin should have impersonate rights
$admin = ""
$user = ""
#First Find Microsoft.Exchange.WebServices.dll location
$dllpath = "D:\Exchange Server\Bin\Microsoft.Exchange.WebServices.dll"
Import-Module $dllpath
$ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($ExchangeVersion)
#admin account credentials
$psCred = Get-Credential
$creds = New-Object System.Net.NetworkCredential($psCred.UserName.ToString(), $psCred.GetNetworkCredential().password.ToString())
$service.Credentials = $creds
$service.AutodiscoverUrl($admin ,{$true})
$service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress,$user);
$contactsFolder = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Contacts,$user)
$contacts = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$contactsFolder)
$view = new-object Microsoft.Exchange.WebServices.Data.ItemView($contacts.TotalCount, 0)
$results = $contacts.FindItems($view)
$response = $service.LoadPropertiesForItems($results, [Microsoft.Exchange.WebServices.Data.PropertySet]::FirstClassProperties)
foreach ($item in $results){
echo $item.Item.EmailAddresses[[Microsoft.Exchange.WebServices.Data.EmailAddressKey]::EmailAddress1].Address