Home > Lync Server/Skype for Business Server > One Liners: Finding AD Disabled Accounts Who are Still Lync/Skype for Business Enabled

One Liners: Finding AD Disabled Accounts Who are Still Lync/Skype for Business Enabled

Lync 2013 logo 128x128Fellow MVP Jeff Guillet wrote an article about the fact that disabling a user’s Active Directory account doesn’t mean they can’t log into Lync/Skype for Business. This is due to the way Lync uses certificates and authentication based on them. I highly recommend you read the article.

I recently was writing some documentation for a customer and wanted to include this important information, including methods for resolving the problem after the fact.

If you’ve not been disabling users in Lync while disabling them in AD, here’s a one liner to find those users:

Get-CsAdUser -ResultSize Unlimited | Where-Object {$_.UserAccountControl -match "AccountDisabled" -and $_.Enabled -eq $true} | Format-Table Name,Enabled,SipAddress -auto

You can shorten it somewhat by not checking if $_.Enabled is $true, but just that it exists. You can get a count of the users using:

Get-CsAdUser -ResultSize Unlimited | Where-Object {$_.UserAccountControl -match "AccountDisabled" -and $_.Enabled} | Measure-Object

and, if you want, can disable them in one line using

Get-CsAdUser -ResultSize Unlimited | Where-Object {$_.UserAccountControl -match "AccountDisabled" -and $_.Enabled} | Disable-CsUser

Update 09-14-2012: Be careful using that last option if you’ve configured test accounts for synthetic testing using the New-CsHealthMonitoringConfiguration cmdlet as I mention in Lync Synthetic Tests: What They are and When They Don’t Work – Part I.

Update 04-12-2014: Replaced aliases with full cmdlet per best practices.

Update 09-19-2014: Added -ResultSize Unlimited

  1. Tim B
    November 2nd, 2012 at 12:39 | #1

    Just what I was looking for! Thanks for the script.

  2. Phila
    April 15th, 2014 at 11:31 | #2

    How can you create an automation on this to have it run weekly and email the result to myself like every Monday morning?

  3. August 19th, 2014 at 11:17 | #3


    You can pipe that information to Export-CSV which will yield a Comma Separated File you can view with Excel

    Get-CsAdUser | Where-Object {$_.UserAccountControl -match “AccountDisabled” -and $_.Enabled -eq $true} | Export-CSV C:\Temp\WeeklyReport.csv

    Then afterwards you can leverage the Send-MailMessage from Powershell to automatically send off the email

    Send-MailMessage -Attachments C:\Temp\WeeklyReport.csv -To ‘somebodyimportant@contoso.local’ -Body ‘Weekly Report for Old Lync users’ From ‘lyncadmin@contoso.local’ -Subject ‘Weekly Lync Report’ -SmtpServer ‘mylocalsmtpserver.contoso.local’

    You would embody the whole thing as a single .PS1 file and then using standard Scheduled Tasks, schedule it as a recurring task.

    PowerShell.exe -executionpolicy Bypass -file LyncReport.ps1


    • Pat Richard
      August 19th, 2014 at 11:19 | #4

      I’d want to include the -NoTypeInformation switch when calling Export-Csv.

  4. Tony Hart
    June 15th, 2015 at 13:26 | #5

    Hi Pat. I love your Lync/S4B powershell scripts and have found quite a few of them useful. This little gem came in particularly useful. After a little bit of tweaking I managed to make something a little more eye friendly using your script and following some script voodoo from Exchange Server Pro.

    $a = “”
    $a = $a + “BODY{background-color:peachpuff;}”
    $a = $a + “TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}”
    $a = $a + “TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:thistle}”
    $a = $a + “TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:PaleGoldenrod}”
    $a = $a + “”

    $smtpServer = “smtp.watsammattau.edu”
    $smtpFrom = “Lync_Support_Team@watsammattau.edu”
    $smtpTo = “Lync_Support_Team@watsammattau.edu”
    $messageSubject = “Weekly Disabled AD Users”
    $message = New-Object System.Net.Mail.MailMessage $smtpFrom, $smtpTo
    $message.Subject = $messageSubject
    $message.IsBodyHtml = $true
    $message.Body = Get-CsAdUser -ResultSize Unlimited | Where-Object {$_.UserAccountControl -match “AccountDisabled” -and $_.Enabled -eq $true} | Select-Object Name,Enabled,SipAddress | ConvertTo-HTML -head $a
    $smtp = New-Object net.mail.smtpclient($smtpServer)

    Get-CsAdUser -Filter {UserAccountControl -eq “AccountDisabled, NormalAccount” -and Enabled -eq $true} | Set-CsUser -Enabled $false

  5. Tony Hart
    June 16th, 2015 at 10:27 | #6

    The one thing it lacks is a mechanism that says if there are no names to list, not run or send the email.

  6. Joseph
    June 26th, 2017 at 17:57 | #7

    Thank you very much for this, all 3 of these commands worked flawlessly and did exactly what I needed. We sadly did not have a very good termination policy in place up until mid last year and this really covered us to make sure none of these accounts slipped past. A shocking 183 were still active up until I ran this. Again thanks for powershell commands, they helped a bunch.

  1. May 4th, 2015 at 15:13 | #1
  2. May 16th, 2015 at 05:20 | #2
  3. May 29th, 2015 at 17:06 | #3