Find and Delete Orphaned Users in SharePoint with PowerShell

Some times back, I posted an article on Orphaned Users in SharePoint. in short, SharePoint orphaned users are those who are deleted from Active Directory, but still have permissions to SharePoint sites!  Read more here: Find and Delete Orphaned Users in SharePoint

find and delete orphaned users in sharepoint

PowerShell to Find and Delete Orphaned Users in SharePoint

Now, with PowerShell, We can Find and Delete orphaned users in SharePoint. Here is the script:

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Parameter
$WebAppURL="http://intranet.crescent.com"
 
#Function to Check if a User exists in AD
Function Check-UserExistsInAD()
{
    Param( [Parameter(Mandatory=$true)] [string]$UserLoginID)
    Write-host $UserLoginID
    #Search the User in AD
    $Forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
    foreach ($Domain in $forest.Domains)
    {
        $context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain", $Domain.Name)
        $domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($context)
    
        $root = $domain.GetDirectoryEntry()
        $search = [System.DirectoryServices.DirectorySearcher]$root
        $search.Filter = "(&(objectCategory=User)(samAccountName=$UserLoginID))"
        $result = $search.FindOne()
 
        if ($result -ne $null)
        {
           return $true
        }
    }
  return $false  
 }
  
#Get all Site Collections of the web application
$WebApp = Get-SPWebApplication $WebAppURL
 
#Iterate through all Site Collections
Foreach($site in $WebApp.Sites)  
{
    #Get all Webs with Unique Permissions - Which includes Root Webs
    $WebsColl = $site.AllWebs | Where {$_.HasUniqueRoleAssignments -eq $True} | ForEach-Object {         
    $OrphanedUsers = @()         
    #Iterate through the users collection
    ForEach($User in $_.SiteUsers)
    {
        #Exclude Built-in User Accounts , Security Groups 
        if(($User.LoginName.ToLower() -ne "nt authority\authenticated users") -and
            ($User.LoginName.ToLower() -ne "sharepoint\system") -and
                ($User.LoginName.ToLower() -ne "nt authority\local service")  -and
                    ($user.IsDomainGroup -eq $false ) )
                {
                    $UserName = $User.LoginName.split("\")  #Domain\UserName
                    $AccountName = $UserName[1]    #UserName
                    if ( ( Check-UserExistsInAD $AccountName) -eq $false )
                    {
                                Write-Host "$($User.Name)($($User.LoginName)) from $($_.URL) doesn't Exists in AD!"
                                     
                                #Make a note of the Orphaned user
                                $OrphanedUsers+=$User.LoginName
                    }
                }
        }
    }
}
        
# ****  Remove Users ****#
# Remove the Orphaned Users from the site
# foreach($OrpUser in $OrphanedUsers)
#   {
#        $_.SiteUsers.Remove($OrpUser)
#        Write-host "Removed the Orphaned user $($OrpUser) from $($_.URL) "
#   }

Executing this script will scan and give the list of orphaned users in a SharePoint web application. It can be used in SharePoint 2010 also to find & delete orphaned users.

SharePoint orphaned users cleanup:
I’ve commented out the “Remove Users” section at the bottom of the script.  Just remove # tags to uncomment and execute the script to delete orphaned users in SharePoint.

Salaudeen Rajack

Information Technology Professional with Two decades of SharePoint Experience.

36 thoughts on “Find and Delete Orphaned Users in SharePoint with PowerShell

  • July 19, 2018 at 2:54 PM

    I am getting below message after running orpahnuser.ps1 script above.I would like to know if we need to pass each user details or it will give all inactive user list.

    cmdlet ForEach-Object at command pipeline position 2
    Supply values for the following parameters:
    Process[0]:

    Reply
  • February 7, 2017 at 11:01 AM

    Hi Salaudeen,

    I have sharepoint 2013 foundation running in my environment, can I use this script ? I am sure that it will not work. can you please help me with creating a new script for finding orphan user were the user profile is not configured.

    Thanks you.

    BR
    MDA

    Reply
  • February 7, 2017 at 9:59 AM

    Hi Salaudeen,

    I have sharepoint 2013 foundation running in my environment, can I use this command to find orphan user, if not then can you help me in this regards, or how can I append this command to find orphan users on the sharepoint site.

    Reply
    • February 8, 2017 at 8:10 AM

      This script doesn’t use User profile service – So should be fine with SharePoint 2013 Foundation as well.

      Reply
  • October 31, 2016 at 10:19 PM

    Can you put this as an attachment on the blog post?

    Copying and pasting from your blog post removes all carriage returns and makes the script unrunable without a half an hour of line break adding.

    Reply
  • September 14, 2016 at 5:52 PM

    what will happen to the documents or list items modified by the now orphan user? the created by and modified field to be specific?

    Reply
    • September 15, 2016 at 7:05 AM

      All documents and List items stays intact – except the created by or modified fields replaced with “System Account”

      Reply
  • September 14, 2016 at 5:51 PM

    What will happen to the document or list items modified by orphan user, will the field get updated with system account?

    Reply
  • June 22, 2016 at 5:58 PM

    I received unexpected token and parser errors on vglnk and wondering if anyone could tell me why and how to fix? Thanks in advance!

    Reply
  • June 17, 2016 at 11:48 AM

    I run this but get the error CheckUserExistsInAD : Cannot bind argument to parameter ‘UserLoginID’ because it is an empty string. Any idea why?

    Reply
  • March 9, 2016 at 1:24 AM

    Anyone else getting an unexpected token or expression error on line 49?

    Reply
  • November 24, 2015 at 10:24 AM

    Hello, I’m very newbie on this part. I want to remove in my SP2010 sites, all users that have been deleted in AD. Can you help me please ? The above code works ? How to run it ? Regards & Thx !

    Reply
    • January 17, 2016 at 10:30 AM

      Hi Serenade,
      1. Change the Web Application URL in Line#49
      2. Uncomment the code between Line#83 to 89
      3. Save and Run the script with PowerShell

      Reply
  • November 2, 2015 at 5:41 AM

    Hello,

    The above script reports deleted users from active directory. Could you please help me in modifying the script to consider both disable and delete users in active directory and compare with sharepoint and output to CSV.

    Thanks in Advance.

    Reply
    • November 2, 2015 at 10:53 AM

      Hello,

      How do i modify the script to consider disable users as well.

      $root = $domain.GetDirectoryEntry()
      $search = [System.DirectoryServices.DirectorySearcher]$root
      $search.Filter = “(&(objectCategory=User)(samAccountName=$UserLoginID))”
      $result = $search.FindOne()

      if (($result -ne $null) )
      {
      return $true
      }
      }
      return $false
      }

      Above lines of script considers only deleted user and if user is deleted it returns false. But i need for disable users also like if user is disabled (Enabled=false) then it should return false.

      Thanks in Advance.

      Reply
    • November 2, 2015 at 11:19 AM

      Import-Module ActiveDirectory

      #Function to Check if the user account is enabled or not
      Function Check-UserEnabled($LoginID)
      {
      Return Get-ADUser -LDAPFilter “(samaccountname=$LoginID)” | Select-Object -ExpandProperty enabled
      }

      #SamAccountName
      $UserID=”Salaudeen”

      Check-UserEnabled $UserID

      Reply
    • November 2, 2015 at 10:35 AM

      To find all disabled users, use:
      Get-ADUser -Filter {Enabled -eq $false} | FT samAccountName

      Reply
    • November 2, 2015 at 10:44 AM

      Hello,

      Thanks a lot for your response. Could you please let me know how can i modify the above script.

      Above script which you have written in this blog gives me exactly all the details of deleted users and compares with sharepoint. In the same way i need both disable and deleted users to be compared with sharepoint and output to CSV.

      Do i need to change the filter condition in above script (line #43). Please help me.

      Thanks in Advance.

      Reply
  • May 5, 2015 at 1:38 PM

    Is it possible to target the script to only report orphans for a single sub site only? I tried changing AllWebs to RootWeb and changed the URL to the subsite URL, but it still delivers just the Root users/orphans only

    Reply
  • April 8, 2015 at 9:17 AM

    hi thanks for this nice script , it gives normal users who are in AD also as orphaned users in my 2010 SP . Anything wrong ?

    Cheers 🙂
    SA

    Reply
    • April 9, 2015 at 5:38 AM

      The user account which runs this script MUST have Read-Only access at least to AD to retrieve AD objects. Make sure you are able to connect with AD and retrieve user objects from the WFE server runs this script.

      Reply
  • February 4, 2015 at 9:56 PM

    This script was a great starting point. Thanks for sharing.

    Reply
  • December 23, 2014 at 11:24 AM

    The script works fine in check/preview mode and returns lots of oldstaff as expected, but near the end I get lots of errors like this – any idea why?

    The ‘=’ operator failed: Exception has been thrown by the target of an invocation..
    At C:PowershellFindOrphanedUsers.ps1:114 char:13
    + $WebsColl = <<<< $site.AllWebs | Where {$_.HasUniqueRoleAssignments -eq $Tr ue} | ForEach-Object { + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : OperatorFailed

    Reply
  • October 10, 2014 at 3:58 AM

    Hi am getting below error while executing the script “The term ‘CheckUserExistsInAD’ is not recognized as a cmdlet, function, operable program, or script file. Verify the te
    rm and try again.
    At line:18 char:47
    + if ( ( CheckUserExistsInAD <<<< $AccountName) -eq $false ) The term 'CheckUserExistsInAD' is not recognized as a cmdlet, function, operable program, or script file. Verify the te rm and try again. At line:18 char:47" Please suggest , Thanks in advance.

    Reply
  • February 13, 2014 at 8:07 PM

    In line 57 change Allwebs to RootWeb

    I have diffrent sitution is there any way to check againts each DC in AD, we have 5 DC. So in same case Domian1user1 move to Domain2User1. Domain1user1 is removed from AD, but still on site collection as orphan user, but when i run above script it dosnet give me result since it running againts Global AD and looking for Loginname (user1) and user1 is active in Domain2 it not coming back as orphan for USER1 in domain1 ??

    Reply
  • February 5, 2014 at 4:57 PM

    Thanks for Shareing great Script, one quesiton though why its checking all webs for orphan user ?
    I ran this script in my enviroment and it taking while to find orphan user, some all of the are same user at different location. Is there anyway just to check at User Information List where all user reside , to find and delete from there, once you delete from site collection it will be gone from everywhere.

    Reply
  • January 13, 2014 at 8:52 PM

    can we write the output in a csv file? if yes then please share

    Reply
    • January 14, 2014 at 7:50 AM

      Simple! Just use: $User.LoginName | out-file “d:OrphanedUsersRpt.txt” -append after line# 78.

      Reply
    • January 14, 2014 at 12:09 PM

      Great..it worked..You Are The MAN 🙂

      Reply
    • October 23, 2014 at 6:26 PM

      You can also include the User’s full name and URL of where the orphaned account is located, just use: “$($User.Name);$($User.LoginName);$($_.URL)” | out-file “d:OrphanedUsersRpt.txt” -append after line# 78.

      Reply
  • November 18, 2013 at 7:22 PM

    Ya know. Forget I said anything – it works! Just let it sit for a while. Thanks for the awesome script.

    Reply
  • November 18, 2013 at 7:08 PM

    I don’t really understand. I ran this script against 2 developement environements to test – and both times – the script enumerated through the list (e.g. Zenis, Linda(ad9781) from http://stg2-community.com doesn’t Exists in AD! and Zevis, Sophi(ad158) from http://stg2-community.com doesn’t Exists in AD!) but, every time – the script HANGS on “removed orphaned user % from %webapp%.

    I have rebooted , and it STILl does this. I would anticipate it wouldn’t be very time consuming – and i am also getting nothing in the ULS. I am also running as farm account with full rights into UPA. ideas?

    Reply
  • September 15, 2013 at 3:18 PM

    How to change script to remove disabled accounts from AD ? 🙂 Thanks!

    Reply
    • November 18, 2013 at 7:58 PM

      Just change the Filter parameter in the function CheckUserExistsInAD() to:
      (&(objectCategory=person)(objectClass=user)( !(userAccountControl:1.2.840.113556.1.4.803:=2)))

      Reply
  • July 9, 2013 at 1:48 PM

    Hi Salaudeen Rajack,

    Great sharepoint Blog, Nice Article,thanks for sharing.Looking forward for more posts like this.

    Sharepoint Developers

    Reply

Leave a Reply