SharePoint 2013 Delete Orphaned Users

Over time users get deleted out of Active Directory but remain in SharePoint. If you manually delete these users out of the database any links to content or library files created by the user will become broken. The only safe way to remove orphaned users is to use powershell and all references to the user gets flagged as inactive in the database.

Sometimes a user can become out of Sync with AD. If a user is deleted and recreated too quickly, or if a user is deleted and another user is renamed with the same name. The only way to fix this problem is use the powershell code below to flag the incorrect users as inactive in SharePoint.

#Powershell to Remove Orphaned Users from SharePoint 2013/2010
#Modified Powershell Code from

#Load SharePoint Management shell 
if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
    Add-PSSnapin "Microsoft.SharePoint.PowerShell"

#Function to Check if an User exists in AD
function CheckUserExistsInAD()
   Param( [Parameter(Mandatory=$true)] [string]$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  
 #Change these variables as desired
 $RemoveUsers = $false
 #Get all Site Collections of the web application
 $WebApp = Get-SPWebApplication $WebAppURL
  $textout = ""
 $textout > ".\SharePointOrphanedUsers.csv"
 #Iterate through all Site Collections
 foreach($site in $WebApp.Sites)  
    if ($site -ne $null)
        $web = $site.AllWebs
        foreach ($webp in $web)
            $OrphanedUsers = @()
            if (($webp.permissions -ne $null) -and ($webp.hasuniqueroleassignments -eq "True"))
                #Iterate through the users collection
                foreach($User in $webp.SiteUsers)
                    #Exclude Built-in User Accounts , Security Groups & an external domain "corporate"
                    if(($User.LoginName.ToLower() -ne "nt authority\authenticated users") -and
                            ($User.LoginName.ToLower() -ne "nt authority\system") -and
								($User.LoginName.ToLower() -ne "sharepoint\system") -and
								  ($User.LoginName.ToLower() -ne "nt authority\local service")  -and
									  ($user.IsDomainGroup -eq $false ) -and
										  ($User.LoginName.ToLower().StartsWith("corporate") -ne $true) )

                        $UserName = $User.LoginName.split("\")  #Domain\UserName
                        $AccountName = $UserName[1]    #UserName
                        #If the user does not exist in Active Directory then it is an orphaned account in the SharePoint Site Collection
                        if ( ( CheckUserExistsInAD $AccountName) -eq $false )
                                $textout = """$($User.Name)"",""$AccountName"",""($($User.LoginName))"",""$($webp.URL)"""
                                #Write-Host $textout
                                $textout >> ".\SharePointOrphanedUsers.csv"
                                #Make a note of the Orphaned user
                # ****  Remove Users ****#
                # Remove the Orphaned Users from the site
                if ($RemoveUsers)
					foreach($OrpUser in $OrphanedUsers)
						Write-host "Removed the Orphaned user $($OrpUser) from $($webp.URL) "



5 thoughts on “SharePoint 2013 Delete Orphaned Users

  1. sthepany

    Hi, the “Domain” field should have some value?
    because I get the following error:

    CheckUserExistsInAD : Cannot bind argument to parameter ‘UserLoginID’ because
    it is an empty string.

    1. Preston Post author

      It should grab your domain based on your current forest. No you shouldn’t change it. You will just have to go through the script and add some WRITE-HOST statements to see where the problem lies. Make sure you are running the script from a user with Permissions to Active Directory and SharePoint. Make sure and change $WebAppURL to point to your SharePoint site and $RemoveUsers =$false while testing.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: