Two interesting problems with Lync in the past few months, and both had a similar solution.

First, we had returning employees (they left and then came back to the company) who could not sign into Lync with their same SIP address. If we added something like a 1 to the end of the address, they could sign in just fine. After spending some time with Microsoft support, we were able to determine that the SIP address was still present on the Front End and Director servers in the RTCLocal instance even though the SIP address was not assigned to an active Lync account.

To resolve this issue, first disable and remove the Lync user account by running Disable-CsUser. Once the Lync account is removed, wait 15 minutes for replication to complete.

Next, to see if the SIP address is still present in the RTCLocal instance after disabling the Lync account, run the following SQL query on theFront End or Director server to see if it still exists:

Select * from [rtc].[dbo].[Resource] WHERE [UserAtHost]='<SIPURI>'

If it returns a result, run the following SQL command to remove it:

execute rtc.dbo.RtcDeleteResource '<SIPURI>'

Now recreate the Lync account and verify the user is able to log in. According to the support engineer I worked with, the accounts not being cleaned up properly can occur if we use Disable-CsUser versus Set-CsUser -Enabled $false for terminated people. If the Active Directory account is deleted, use Disable-CsUser. If the Active Directory is reused when the employee returns, use Set-CsUser -Enabled $false when de-provisioning a user. In our case, we reuse the same Active Directory account when the employee returns for employment, so we had to modify our de-provisioning process to use Set-CsUser -Enabled $false.

The next issue got a little tougher. When someone was trying to make a Lync VoIP call or join a conference using Lync audio, they got the message saying “Cannot complete the call”. When you clicked the error, it displayed the message “There is more than one contact with your phone number”:

Weird, Lync is pretty good about not letting you reuse phone numbers and extensions in the LineURI.

First, let’s check everyone’s LineURI and see if there happens to be anyone with the same extension or phone number:

Get-CsUser -ResultSize Unlimited | Where-Object {$_.LineURI -like "*<PhoneNUmber>*"} | select Identity, LineURI

Note the asterisks (*) on each side of the extension. More than likely this will only return the user who is having the issue.

So back to Microsoft support. We gathered logs and did troubleshooting for two months before the solution came to me. Maybe there was an old user account who previously had the same phone number attached to their account, and it was still present out on the Front End and Director servers. The trick is finding the phone number. I caught a break for one person who knew who previously had the phone number assigned to them. I did the “Select” statement from above to find that the previous user’s SIP address was still present in the RTCLocal instance but they did not have a Lync Account or Active Directory account. I performed the RtcDeleteResource command and the user could now use Lync audio. Awesome!

Now how do I find the person who previously had the phone number if it is unknown? I started looking around the other database tables in RTCLocal and found “ResourcePhone”. I ran the following SQL query using a partial phone number for the affected user:

SELECT * FROM [rtc].[dbo].[ResourcePhone] WHERE [PhoneNum] like '%5551234%'

This would return two records. Unfortunately it did not list the name or SIP URI of the user, just the ResourceID. I took each ResourceID and ran the following statement to find the SIP URI of the person it belonged to:

SELECT * FROM [rtc].[dbo].[Resource] WHERE [ResourceId]='<ResourceID>'

Here I could see SIP URI of the user who was no longer with the company. From there I could rerun the RtcDeleteResource to remove their entry from RTCLocal:

execute rtc.dbo.RtcDeleteResource '<SIPURI>'

After performing the cleanup of the user who was no longer here, the existing user could now make Lync phone calls and join Lync Audio on conferences. This has also prompted us to clear a Lync user’s LineURI when they are terminated.

Running RtcDeleteResource command can be tedious on each server, especially in a larger environment where you might have multiple Front End and Director pools. Import the SQL PowerShell module on a system with either SQL or SQL Management Studio installed so you can use Invoke-Sqlcmd to easily run the command against multiple SQL instances. Here’s what a basic script could look like:

# List all Front End and Director Servers
$LyncServers = @("Server1","Server2")
# Import SQL Module
Import-Module "sqlps" -DisableNameChecking
# Get SIP URI of user to remove
$sipURI = Read-Host "Enter the SIP URI of the user to remove"
# Run RtcDeleteResource against each Lync Server's RTCLocal instance
foreach ($LyncServer in $LyncServers)
    Write-Host "Performing user removal on $LyncServer"
    Invoke-Sqlcmd -Query "execute rtc.dbo.RtcDeleteResource '$sipURI'" -ServerInstance "$LyncServer\rtclocal"

The longer script I’ve written does checking to see if the Lync user account still exists and prompts to run Disable-CsUser before continuing. It also gathers other user account details such as their conferencing policy, voice policy, LineURI, etc. so I can reuse it later when I recreate their account.

Edit 11/7/2017:

Finally wrote and published a full script to automate this task across multiple servers. See the blog post here:

The Script for Cleaning Up Lync & Skype for Business Accounts