PowerShell Tools - Removing Orphaned Users from SharePoint
Here’s a script that will walk through all Site Collections in all Web Applications (i.e. your entire farm) and delete any user from the Site Collection that isn’t in ActiveDirectory anymore.
Note this will not remove them from their user profiles, it just cleans up Site Collections. If you want some great info on how the User Profile service works and the My Site Cleanup Job then check out these resources:
Here’s the code:
[int]$GLOBAL:TotalUsersUpdated = 0;
function Check_User_In_ActiveDirectory([string]$LoginName, [string]$domaincnx)
{
$returnValue = $false
$strFilter = "(&(|(objectCategory=user)(objectCategory=group))(samAccountName=$LoginName))"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry($domaincnx)
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.PageSize = 1000
$objSearcher.Filter = $strFilter
$objSearcher.SearchScope = "Subtree"
$colResults = $objSearcher.FindAll()
if($colResults.Count -gt 0)
{
$returnValue = $true
}
return $returnValue
}
function ListOrphanedUsers([string]$SiteCollectionURL, [string]$mydomaincnx)
{
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null
$site = new-object Microsoft.SharePoint.SPSite($SiteCollectionURL)
$web = $site.openweb()
Write-Host "SiteCollectionURL:", $SiteCollectionURL
$siteCollUsers = $web.SiteUsers
Write-host "SiteUsers:", $siteCollUsers.Count
#Create array to hold non-existant users
$usersToRemove = @()
foreach($MyUser in $siteCollUsers)
{
if(($MyUser.LoginName.ToLower() -ne "sharepoint\system") -and
($MyUser.LoginName.ToLower() -ne "nt authority\authenticated users") -and
($MyUser.LoginName.ToLower() -ne "nt authority\local service"))
{
$UserName = $MyUser.LoginName.ToLower()
$Tablename = $UserName.split("\")
$returncheck = Check_User_In_ActiveDirectory $Tablename[1] $mydomaincnx
if($returncheck -eq $False)
{
Write-Host "User does not exist", $MyUser.LoginName, "on domain"
$usersToRemove = $usersToRemove + $MyUser.LoginName
$GLOBAL:TotalUsersUpdated += 1;
}
}
}
foreach($u in $usersToRemove)
{
Write-Host "Removing", $u, "from site collection", $SiteCollectionURL
$siteCollUsers.Remove($u)
}
$web.Dispose()
$site.Dispose()
}
function ListOrphanedUsersForAllColl([string]$WebAppURL, [string]$DomainCNX)
{
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null
$Thesite = new-object Microsoft.SharePoint.SPSite($WebAppURL)
$oApp = $Thesite.WebApplication
Write-host "Total Site Collections:", $oApp.Sites.Count
$i = 0
foreach ($Sites in $oApp.Sites)
{
$i = $i + 1
Write-Host "---------------------------------------"
Write-host "Collection Number", $i, "of", $oApp.Sites.Count
if($i -gt 0)
{
$mySubweb = $Sites.RootWeb
$TempRelativeURL = $mySubweb.Url
ListOrphanedUsers $TempRelativeURL $DomainCNX
}
}
Write-Host "======================================="
}
function EnumerateAllSiteColl()
{
$farm = Get-SPWebApplication | select DisplayName
foreach($app in $farm)
{
$webapp = Get-SPWebApplication | ? {$_.DisplayName -eq $app.DisplayName}
Write-Host "Web Application:", $webapp.DisplayName
ListOrphanedUsersForAllColl $webapp.Url "LDAP://DC=ca,DC=util"
Write-Host
}
}
function StartProcess()
{
cls
[System.Diagnostics.Stopwatch] $sw;
$sw = New-Object System.Diagnostics.StopWatch
$sw.Start()
EnumerateAllSiteColl
$sw.Stop()
write-host "***************************"
write-host $GLOBAL:TotalUsersUpdated, "users removed in", $sw.Elapsed.ToString()
write-host "***************************"
}
StartProcess
Enjoy!