Contents tagged with PowerShell

  • 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!

  • Applying Quotas Across all My Sites

    Just a quick snippet this morning. If you need to apply a new quota template to all users My Sites here's a quick script to do it. Changing an existing quota is fine but if you're migrating users from another system or you just want to up everyone's storage a bit here's what you do.

    1. Create a new quota template. This is found in Central Admin under Application Management | Site Collections | Specify quota templates. There's already a default "Individual Quota" created you might want to create your own or have a special one for your users
    2. Open up the PowerShell Management Console and enter "Get-SPWebApplication". This will list all your web applications on the farm. 
    3. To apply it to all My Sites (each site is a site collection of its own) run this script below.

       1:  $webapps = Get-SPWebApplication;
       2:   
       3:  $webapp = $webapps[4];
       4:   
       5:  foreach ($site in $webapp.Sites) {
       6:      Set-SPSite -Identity $site.url -QuotaTemplate "Your Quota Template"
       7:  }

    The first line gets all the web applications on the server. In our case, the forth one is the mysite web app (yours will probably be a different number). Just run Get-SPWebApplication from the console to figure out which one to use. You could get fancy and pipe the name to find it but I'm too lazy for that.

    Then we loop through all the sites on the list using the $site.url property and pass it to the Set-SPSite cmdlet and specify the name of the our custom QuotaTemplate.

    Easy. Now all users are updated with the new quota template.