1. Detect mysites whose users who are no longer active in AD (Active Directory)
2. Update the site owner to someone else
3. Delete the user profile (to clean up organizational chart)
4. Remove/archive the mysite after x days.
Practically all articles on the WWW on this topic was to adopt an approach using the UserProfileManager to detect users removed from AD. However, this approach did NOT address my particular need.
This approach assumes that:
1. ALL of your mysites follows the same naming convention e.g. http://mysites/personal/username
2. The inactive users were either (1) totally removed; or (2)still in AD, but was moved to a separate OU (Organizational Unit)
First you need a function that queries AD:
#---------------------------------------------------------------------------------
# Function to Check if an User exists in AD
#---------------------------------------------------------------------------------
function CheckUserExistsInAD()
{
Param( [Parameter(Mandatory=$true)] [string]$UserLoginID )
#Cleanup ID
$UserLoginID = $UserLoginID -replace "DOMAIN\\", ""
#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)
{
$s = $result.path
$s = $s.substring($s.indexOf("OU=")+3).split(",")
if ($s[0] -like "*Disabled User*")
{
return $false
}
#Write-Host "Organizational Unit:" $s[0]
return $true
}
}
return $false
}
Now for the action. Load the sharepoint powershell module.
#Add SharePoint PowerShell SnapIn if not already added
if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}
This step is optional. Create a file for logging.
# Create Log File
$LogDirectory = "D:\Logs"
$LogFile = "CleanupUserProfile_" + (Get-Date -UFormat "%Y%m%d") + ".txt"
$LogPath = $LogDirectory +"\" + $LogFile
if([IO.Directory]::Exists($LogDirectory))
{
}
else
{
New-Item $LogDirectory -type directory
}
New-Item $LogPath -type file -force
# Write Headers
Add-Content $LogPath "Status,MySiteUrl,PrimarySiteOwner,SecondarySiteOwner,Account,Manager"
Next load all site collections from the mysites web application and loop through each site.
Parse the User ID from the site URL and call the function CheckUserExistsInAD() to make sure the user is valid
$web = Get-SPWebApplication http://mysites
foreach($site in $web.Sites)
{
if ($site.Url -like "*/personal/*")
{
#Check original user, and owner is still with the company
$MySiteUrl = $site.Url
$UserID = $MySiteUrl.substring($MySiteUrl.indexOf("/personal/")+10)
$primaryOwner = $site.Owner
$secondaryContact = $site.SecondaryContact
Write-Host "Mysites: " $UserID
#Get manager
try {
$ServiceContext = [Microsoft.SharePoint.SPServiceContext]::GetContext($site)
#Get UserProfileManager from the My Site Host Site context
$ProfileManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($ServiceContext)
$profile = $ProfileManager.GetUserProfile($UserID)
$manager = $profile.GetManager()
$ManagerID = $manager[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::AccountName].Value
#$ManagerID = $ManagerID -replace "DOMAIN\\", ""
} catch {
$ManagerID = ""
}
$blnUserExists = CheckUserExistsInAD($UserID)
$blnOwnerExists = CheckUserExistsInAD($primaryOwner)
if ([string]::IsNullOrEmpty($secondaryContact)) { $blnSecondaryOwnerExists = $false }
else { $blnSecondaryOwnerExists = CheckUserExistsInAD($secondaryContact) }
$CurrStatus = "Active"
#If user is marked for deletion
if (!$blnUserExists)
{
Write-Host "Tagged for deletion" -foregroundcolor "magenta"
$blnUpdateRequired = $false
$CurrStatus = "Inactive"
$OwnerID = ""
$SecondaryContactID = ""
Write-Host "Primary Owner:" $primaryOwner $blnOwnerExists
Write-Host "Secondary Owner:" $secondaryContact $blnSecondaryOwnerExists
#If primary owner is already newowner, double check manager is the secondary owner
if ($primaryOwner -contains "DOMAIN\newowner" -and $secondaryContact -contains $ManagerID)
{
# No update action required
}
else
{
$blnUpdateRequired = $true
if ([string]::IsNullOrEmpty($ManagerID)){ $blnManagerExists = $false }
else { $blnManagerExists = CheckUserExistsInAD($ManagerID) }
Write-Host "Manager:" $ManagerID $blnManagerExists
$UserIDTmp = "DOMAIN\" + $UserID
#Write-Host "|"$UserIDTmp"|"$primaryOwner"|"
#If Manager (or someone else) is primary owner, switch them to secondary and assign primary to spadmin
if ($primaryOwner -contains $UserIDTmp)
{
Write-Host "Reassignment detected." -foreground "cyan"
$OwnerID = "DOMAIN\newowner"
if ($blnOwnerExists)
{
Write-Host "Owner account is active, re-assign as secondary contact"
$SecondaryContactID = $primaryOwner
}
elseif ($blnSecondaryOwnerExists)
{
Write-Host "Secondary owner account is active, remain as secondary contact"
$SecondaryContactID = $secondaryContact
}
elseif ($blnManagerExists)
{
Write-Host "Manager account is active, assign as secondary contact"
$SecondaryContactID = $ManagerID
}
}
else
{
$OwnerID = "DOMAIN\newowner"
if ($blnSecondaryOwnerExists)
{
Write-Host "Secondary owner account is active, remain as secondary contact"
$SecondaryContactID = $secondaryContact
}
elseif ($blnManagerExists)
{
Write-Host "Manager account is active, assign as secondary contact"
$SecondaryContactID = $ManagerID
}
}
}
#Assign ownership
if ($blnUpdateRequired)
{
#Perform the rest of the actions here...
}
}
Add-Content $LogPath "$CurrStatus,$MySiteUrl,$primaryOwner,$secondaryOwner,$UserID,$ManagerID"
}
$site.Dispose()
}