onsdag den 1. oktober 2014

Getting rid of those duplicate "Lync contacts" in Outlook

(And everywhere else they sync, for that matter) (Updated 19/102015)

A lot of customers are experiencing the duplicate contacts issue - the issue itself was fixed in this patch http://support2.microsoft.com/kb/2916650

However, patching the LYNC client does not get rid of the duplicate entry's - this has to be done afterwards - and can be a bit of a challenge.
Here are 4 different methods of how to accomplish this task.
Choose what fits, in some cases method 1 will do, and in some cases more extreme measures are needed :)



Method 1:
Sign out of the LYNC client, and wait for a few moments - now switch to outlook and go to "people" and delete the folder "LYNC contacts" don't worry unless you are using UCS, this will not delete your contacts in LYNC, they are stored in your SQL database.

If that fails goto Method 2



Method 2
Log into the light version of OWA by using this link - replace generic address with the correct owa address for your installation

Now go to "contacts" and click manage contacts
Next you select the "Lync Contacts" folder in the drop down and press delete
If this folder is "greyed out" goto Method 3.



Method 3 - the hardcore way.
If the above fails, you will have to script the folder deletion.

Install Exchange EWS managed API - can be downloaded from here
http://www.microsoft.com/en-in/download/details.aspx?id=42951
Can be installed on one of the existing exchange servers, or even on your own client.

Next you open a notepad and paste the following script, remember to change exchange version according to your specific needs, and also please make sure that the path for the API dll is correct.
And most important if you a running other language change the name of the "lync contacts" folder

Save this as deletefolder.ps1


$MailboxName = 'Name@Mailbox'
$dllpath = "D:\EWS\Microsoft.Exchange.WebServices.dll"
[void][Reflection.Assembly]::LoadFile($dllpath)
 $Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1)
$Service.AutodiscoverUrl($MailboxName,{$true})
$RootFolderID = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root,$MailboxName)
$RootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$RootFolderID)
$FolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1000)
$FolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep
$Response = $RootFolder.FindFolders($FolderView)
ForEach ($Folder in $Response.Folders) {
   if($folder.DisplayName -eq "Lync contacts") {
     $folder.delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::SoftDelete)
   }
}


You must either run the script as the user owning the mailbox from where you want to delete the folder OR, run the script as a user with full mailbox permissions for the user with the duplicate entrys.
To make sure that the user running the script has the correct permission, try running the below version instead which will enumerate the folders - if you have insufficient permissions, the script will return "Free busy"
By doing this you also can verify the name of the folder in the specific mailbox.

Save this as enumeratefolder.ps1

$MailboxName = 'name@mailbox'
$dllpath = "D:\EWS\Microsoft.Exchange.WebServices.dll"
[void][Reflection.Assembly]::LoadFile($dllpath)
$Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1)
$Service.AutodiscoverUrl($MailboxName,{$true})
$RootFolderID = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root,$MailboxName)
$RootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$RootFolderID)
$FolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1000)
$FolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep
$Response = $RootFolder.FindFolders($FolderView)
ForEach ($Folder in $Response.Folders) {
write-host $folder.DisplayName
}

To run either script open powershell and cd to the directory where you have placed the ps1 file and run them.

If the script finishes successfully (and permissions are ok) the folder is deleted and the user can reopen outlook and verify this.

UPDATE: June 2015
A friendly reador of my blog send me a great updated version of the script, where he added the possibility to specify several targets, through an array, aswel as an output - thanks to Nikolaj Pabst for contributing to the community.

Save this as Deletecontactswitharray.ps1
$MailboxList = @(
"user1@domain.com"
, "user2@domain.com"
, "user3@domain.com"
)

$dllpath = "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll"
    [void][Reflection.Assembly]::LoadFile($dllpath)
    $Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1)
$FoundAmount = 0
$StartTime = Get-Date
Foreach ($MailboxName in $MailboxList)
{
    Write-Host "Handling " $MailboxName
    $Service.AutodiscoverUrl($MailboxName,{$true})
    $RootFolderID = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root,$MailboxName)
    $RootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$RootFolderID)
    $FolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1000)
    $FolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep
    $Response = $RootFolder.FindFolders($FolderView)
    $FoundFolder = $FALSE
    ForEach ($Folder in $Response.Folders) {
        if($folder.DisplayName -eq "Lync contacts") {
            $FoundFolder = $TRUE
            ++$FoundAmount
            $folder.delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::SoftDelete)
        }
    }
    if($FoundFolder) {
        Write-Host "Found lync contacts folder!"
    }
    else {
        Write-Host "No lync contacts folder found!"
    }
}
$StopTime = Get-Date
$TimeDiff = New-TimeSpan -Start $StartTime -End $StopTime
Write-Host "Deleted"$FoundAmount "folders in"$TimeDiff



Method 4 (Thanks to Frank Detleff)
MFCAPI
Download MFCAPI http://mfcmapi.codeplex.com/|leo://plh/http%3A*3*3mfcmapi%2Ecodeplex%2Ecom*3/OIu3?_t=tracking_disc  
1. Run MFCMAPI.exe.
2. Click on the Tools menu, and then click Options.
3. Click to enable the following option: Use MDB_ONLINE when calling OpenMsgStore
4. On the Session menu, click Logon.
5. If you are prompted for a profile, select your profile name, and then click OK.
6. In the top pane, locate the line that corresponds to your mailbox, and double-click it.
7. In the navigation pane (left-side pane), expand Root Container then expand Top of Information Store.
8. Expand Contacts, and then find the Lync contacts, right click it, click Delete Folder. Select Hard Deletion then click Ok.
9. Open Outlook client to check if the Lync contacts folder has been deleted.

1 kommentar:

Sridhar Parimi sagde ...

Thank you. Method 2 has worked for me