Well, this was a bit of a nightmare to debug. I started the whole project with some googling on how to (automatically) remove AD-disabled users from Lync (SfB) Server. This procedure is by no means automatic, and If you disable a user in AD they can still use Lync (at least for some time). Have a look at https://ucgeek.co/2014/04/lync-users-can-login-after-domain-account-disabled/ for some deeper details.
My concern wasn’t about the fact that the users still could use Lync however, it was more about the fact that they are “hanging around” like ghosts on the Lync Server for no good reason. In plain English – users should be disabled if their AD account is also disabled.
I’ll now present MANY different ways to get rid of the unwanted users in the Lync/SfB Address Book. One method might work for someone, and another method might work for someone else. Hell, you might even need to use all the methods combined ?
Method 1: Disable AD-disabled users on Lync/SfB Server
This idea led me to some PowerShell scripts. Here are a couple of examples that will disable users on the Lync Server if they are disabled in Active Directory:
http://www.markc.me.uk/blog/files/ADDisabled.html
https://www.ucunleashed.com/265
https://trogjels.wordpress.com/2012/08/16/lync-disable-ad-disabled-users/
This worked just fine and I got all the accounts removed from the Lync Server. A little addition to the above links is that I now use this script from a Scheduled Task:
The PowerShell “script” itself looks like this:
# disable_ADdisabled.ps1 , source http://www.markc.me.uk/blog/files/ADDisabled.html
# J.S. 13.9.2017
Import-Module ‘C:\Program Files\Common Files\Microsoft Lync Server 2013\Modules\Lync\Lync.psd1’
Get-CsAdUser -ResultSize Unlimited | Where-Object {$_.UserAccountControl -match “AccountDisabled” -and $_.Enabled} | Disable-CsUser
Well, still no luck. You think your users wouldn’t show up when searching in Lync (Address Book) if they are no longer activated on Lync Server (and also has the –HiddenFromAddressListsEnabled flag, see next chapter). Well, they do. At least for us. This was getting pretty weird. I tried googling but all I could come up with was “Update-CsAddressBook” and so forth. Examples:
http://lyncinsider.com/lync-server-2010/updating-lync-contacts-sync-error-fixes-part-2-of-3/
http://www.fots.nl/lync-address-book-sync-process-information/
http://blog.schertz.name/2010/09/updating-the-lync-2010-address-book/
https://social.technet.microsoft.com/Forums/sharepoint/en-US/2e0d1200-b924-42dd-8700-55893b8cfc03/deleted-lync-user-still-in-list-showing-presence-unknown?forum=officeitpro
https://technet.microsoft.com/en-us/library/gg429695(v=ocs.15).aspx
No. Still no luck. I could see the “old” users which aren’t enabled in AD nor on the Lync Server. This was getting frustrated. Better turn to my old friend Event Viewer. Yes, some hits indeed:
Event ID 21054, Error:
Users are not indexed in the database that should be.
Expected indexed user count: 0
Actual indexed user count: 1999
Cause: User replication issue.
Resolution:
Run Update-CsAddressBook to synchronize all accounts.
Well, what command did I just run? Did it help? No. Then again if you Google the message you’ll soon notice that this error is nothing to worry about:
“As long as “Objects not indexed that should be” and “Abandoned Objects” are zero, the database is okay.” I did run the Debug-csAddressBookReplication and “my” objects were zero. Fine.
Source: https://social.technet.microsoft.com/Forums/lync/en-US/49de4752-a73e-4a55-98d6-a48409a02d94/alert-lync-users-are-not-indexed-in-the-database-that-should-be?forum=lyncdeploy (you can find this information in many other sources as well…)
Method 2: HiddenFromAddressListsEnabled PowerShell command
There are many different flavors of this command, but the one we’re using is something like the one found at https://stackoverflow.com/questions/7974204/powershell-command-to-hide-user-from-exchange-address-lists (and the answer “I use this as a daily scheduled task to hide users disabled in AD from the Global Address List”). We also use it in a Scheduled Task.
This HiddenFromAddressListsEnabled –method was applied at an earlier stage, as we had “problems” with Outlook / Exchange showing disabled users in Global Address List (GAL). The above PowerShell-trick solved the problem on the Outlook/Exchange-side. It SHOULD however also work with Lync/SfB if you are using the Unified Contact Store, UCS. More information about UCS in the next chapter. However, it didn’t work for us. We still saw disabled users in Lync’s Address Book ?
Method 3: Rollback from UCS
What now? I’m ok with just ignoring the event in Event Viewer, but I still have the same problem. My disabled users are visible in Lync’s Address Book. This got me thinking about the Exchange <-> Lync relationship. I know they are a tight fit. Like all MS products. The https://social.technet.microsoft.com/Forums/sharepoint/en-US/2e0d1200-b924-42dd-8700-55893b8cfc03/deleted-lync-user-still-in-list-showing-presence-unknown?forum=officeitpro post had some hints at the end also. Many, MANY Google searches later got me to https://support.office.com/en-us/article/Set-Personal-options-c09b21ac-7334-49cf-a510-d8c432fcaf01
And there it was. The answer I was (partly) looking for:
You specify how Skype for Business interacts with other Office programs.
-
In Personal options, under Personal information manager, select either Microsoft Exchange or Microsoft Outlook or None from the drop-down list. When you select Microsoft Exchange or Microsoft Outlook, the Skype for Business search feature uses the Microsoft Outlook Contact list as a source of contacts, in addition to the global address list.
When you select None, the Skype for Business search feature returns contacts only from the global address list. It doesn’t use either the Windows Address Book or the Outlook Contact list.
Source: https://support.office.com/en-us/article/Set-Personal-options-c09b21ac-7334-49cf-a510-d8c432fcaf01
So, was my solution setting this setting to “None”? You’d think so. Think again. This setting is different in the SfB client. You CAN’T set it to none. Have a look at https://answers.microsoft.com/en-us/msoffice/forum/msoffice_sfb-mso_winother/skype-for-business-2016-personal-information/67d14b5e-23d7-4d23-ab6e-5710739cb0d3 for example.
Well, as my integration is controlled “by my administrator” (which would be myself thank you very much), it got me thinking that it HAS to be a server setting. Now the question was, WHICH setting specifically? Now I honestly don’t remember what I googled to find this, but in the end it got me to http://techgenix.com/integrating-exchange-server-2013-and-skype-business-server-2015-part6/
Well well well. This was all new to me. I ran the command Get-CSUserServicePolicy and found out that UcsAllowed was set to true. It was indeed enabled for ALL our users. I also checked from the SfB client itself, and yes, (not surprisingly) same result:
So, what is UCS?
“The unified contact store introduced in Lync Server 2013 gives administrators the option of storing a user’s contacts in Exchange instead of in Skype for Business Server 2015; in turn that allows the user to access the same set of contacts in Outlook and Outlook Web Access as well as. (Alternatively, you can continue to store contacts in Skype for Business Server 2015. In that case, users will have to maintain two separate sets of contacts: one for use with Outlook and Outlook Web Access, and one for use with Skype for Business.)”
Source: https://technet.microsoft.com/en-us/library/jj205414.aspx
Now the big problem here is that our user accounts used in different systems aren’t disabled at the same time. Users aren’t automatically disabled in Exchange if they get disabled in AD (at least not yet, but this will probably change when our imap-server retires). See the pattern here? What this means is that if a user is still “active” (from Exchange’s point of view), it ALSO lists this person in LYNC’s Address Book. This also means that I’ve found the root problem for our “ghost users”.
The solution is NOT using UCS, and rollback to the system where the contacts are stored on the Lync Server instead of Exchange. Well yeah, you COULD disable UCS, but it feels like going the wrong way. If you still want to test however, the information for this procedure is available here:
https://technet.microsoft.com/en-us/library/jj205224(v=ocs.15).aspx (To rollback unified contact store contacts from Exchange 2013 to Lync Server 2013).
https://technet.microsoft.com/en-us/library/jj688083.aspx
I myself only tried it for a single user as a test, and it worked just fine.
Step one:
New-CsUserServicesPolicy -Identity “NoUCS” -UcsAllowed $False
Step two:
Grant-CsUserServicesPolicy -Identity “mytestuser” -PolicyName “NoUCS”
Step three:
Invoke-CsUcsRollback -Identity “mytestuser”
This removes UCS Address Book from the user and the contacts will be retrieved from the Lync Server instead. This method did INDEED WORK. I did NOT see the disabled users anymore in Lync’s Address Book.
I thought this was the perfect solution/method. However, it feels like going against Microsoft’s thoughts about a more unified Address Book on all MS platforms. I therefore buried this idea.
Method 4: ABSConfig
Even further googling led me to:
http://www.justin-morris.net/how-to-hide-users-from-the-lync-address-book/
https://social.technet.microsoft.com/Forums/lync/en-US/269159b0-3850-4bd6-83ed-1a00516417b8/using-the-abs-configuration-tool-to-limit-the-address-book-to-accounts-which-have-a-sip-address?forum=ocsaddressbook
which use yet another method to hide unwanted users from the Address Book, namely ABSConfig. I changed the configuration to this:
…and was then greeted with:
Ok, so I did the following:
- Restart RtcSrv = Restarted Lync Server Front-End service
- Update-CsUserDatabase (https://social.technet.microsoft.com/Forums/lync/en-US/5cb81b13-bed4-4068-af9b-d917a65094a8/lync-server-user-regeneration?forum=ocsaddressbook)
- Update-CsAddressBook
Was this finally the solution to all Address Book problems? Well yes, actually it was ?
To sum it up: In our case the problem was solved by using methods 1,2 and 4. Results may vary though – what worked for us might not work for you.