kwizcom banner advertisement

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="https://sharepoint.crescent.com"

#Function to Check if a User exists in AD
Function Check-UserExistsInAD()
{
    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   
 }
 
#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 un-comment and execute the script to delete orphaned users in SharePoint.
Find and Delete Orphaned Users in SharePoint with PowerShell  Find and Delete Orphaned Users in SharePoint with PowerShell Reviewed by Salaudeen Rajack on July 08, 2013 Rating: 5

36 comments:

  1. Hi Salaudeen Rajack,

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








    Sharepoint Developers


    ReplyDelete
  2. How to change script to remove disabled accounts from AD ? :) Thanks!

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

      Delete
  3. 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(ad\9781) from http://stg2-community.com doesn't Exists in AD! and Zevis, Sophi(ad\158) 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?

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

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

    ReplyDelete
    Replies
    1. Simple! Just use: $User.LoginName | out-file "d:\OrphanedUsersRpt.txt" -append after line# 78.

      Delete
    2. Great..it worked..You Are The MAN :)

      Delete
    3. 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.

      Delete
  6. 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.

    ReplyDelete
  7. 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 Domian1\user1 move to Domain2\User1. Domain1\user1 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 ??

    ReplyDelete
  8. 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.

    ReplyDelete
  9. 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:\Powershell\FindOrphanedUsers.ps1:114 char:13
    + $WebsColl = <<<< $site.AllWebs | Where {$_.HasUniqueRoleAssignments -eq $Tr
    ue} | ForEach-Object {
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : OperatorFailed

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

    ReplyDelete
  11. 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

    ReplyDelete
    Replies
    1. 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.

      Delete
  12. 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

    ReplyDelete
  13. 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.

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

      Delete
    2. 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.

      Delete
    3. 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.

      Delete
    4. 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

      Delete
  14. 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 !

    ReplyDelete
    Replies
    1. 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

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

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

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

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

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

    ReplyDelete
    Replies
    1. All documents and List items stays intact - except the created by or modified fields replaced with "System Account"

      Delete
  20. 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.

    ReplyDelete
  21. 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.

    ReplyDelete
    Replies
    1. This script doesn't use User profile service - So should be fine with SharePoint 2013 Foundation as well.

      Delete
  22. 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

    ReplyDelete
  23. 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]:

    ReplyDelete

Please Login and comment to get your questions answered!

Powered by Blogger.