Gino Abraham's Blog

June 2015 Entries

Powershell to Migrate users from One Authentication provider to other in SharePoint

We recently had a project in which we had to migrate a SharePoint farm from Siteminder-Custom STS authentication to ADFS 3.0

Siteminder - is a SAML Single Sign on Solution used by my customer which will authentication a user against any of the ID provider(Enterprise directory in our case) and will send SAML 2.0 back to the trusted applications. Since SharePoint doesnt understand SAML 2.0, they have used a Custom STS built on Asp.net to do the transformation for SAML 2.0 to SAML 1.1 and send back the SAML claims to SharePoint.

When ADFS 3.0 was released and promised a very good support for App Model we decided to move away from Custom STS to ADFS 3.0. The ID provider remained same [ ED], Interface to ID provider remained same [ Siteminder R 12.5], just that we knocked off Custom STS and added ADFS 3.0 into the stack. Now ADFS will do the SAML Transformation for us. 

Now coming back to the topic. When we migrated from Custom STS to ADFS, we had to migrate the existing users. As the Identity provider was same, we dont have any changes in the user's actual identity, it just the user name prefix which is changed. [ From "i:05.t|siteminder|testuser1" to "i:0e.t|adfs|testuser1"]

We did the migration in 2 steps.

Step1 : migrated all the spusers by looping through all spuser from the sitecollection.

$url = "http://xyz.internal.com"

$userprefix = "i:0e.t|adfs|"
$users = Get-SPUser -web $url –Limit All
# Loop through each of the users in the web app
foreach($user in $users)
{    
$a=@()    
$userlogin = $user.UserLogin    
Write-Host $user.UserLogin    
$username = “”
#If the user has old user prefix, it will be modified to new prefix
  if($userlogin.Contains("i:05.t|siteminder|"))
{    
$a = $userlogin.split('|')        
$username = $userprefix + $a[2]
Write-Host $userlogin " Changed as " $username " Name: " $user.Name " DisplayName :" $user.DisplayName
Move-SPUser –Identity $user –NewAlias $username -Confirm:$false -IgnoreSID
}
}

now that the users within the site collection is migrated we should migrate all users in the user profile service DB. if you have more than one site collection, run an outer loop which picks up all site collection and migrate user's within.

Step 2: Migrate users in profile Services DB



#Add SharePoint PowerShell SnapIn if not already added

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

#user prefix for the ADFS users
$userprefix = "i:0e.t|adfs|"
$site = new-object Microsoft.SharePoint.SPSite("http://xyz.internal.com");  
$ServiceContext = [Microsoft.SharePoint.SPServiceContext]::GetContext($site);  
#Get UserProfileManager from the My Site Host Site context
$ProfileManager = new-object  Microsoft.Office.Server.UserProfiles.UserProfileManager($ServiceContext)    
$AllProfiles = $ProfileManager.GetEnumerator()  
$profilCount = $ProfileManager.Count
$LoopCount = 0  
foreach($profile in $AllProfiles)  
{      
$LoopCount = $LoopCount + 1    
$DisplayName = $profile.DisplayName      
$AccountName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::AccountName].Value  
    $Farm = Get-SPFarm    
if($AccountName.Contains("i:05.t|siteminder|"))    
{        
$a = $AccountName.split('|')        
$NewAccountName = $userprefix + $a[2]
        $Farm.MigrateUserAccount($AccountName,$NewAccountName,$false)        
write-host $AccountName " has been changed to " $NewAccountName ". Completed " $LoopCount " of $profilCount"
}
}
write-host "Finished."
$site.Dispose() 





SQl Query to check whether User Principal Name is Blank in SharPoint User Profiles DB

User Principal Name /UPN is a property which is mandatory in SharePoint 2013 for Workflows and Provider Hosted Apps to work fine. When you employ a third party profile sync tool or a custom built one, the below SQL query will be quite handy to check whether the User Principal Name property is populated or not. 


SELECT    dbo.UserProfile_Full.UserID, dbo.UserProfile_Full.NTName, dbo.UserProfileValue.PropertyVal
FROM        dbo.UserProfile_Full WITH (NOLOCK) INNER JOIN
                    dbo.UserProfileValue WITH (NOLOCK)  ON dbo.UserProfile_Full.PartitionID = dbo.UserProfileValue.PartitionID AND           dbo.UserProfile_Full.RecordID = dbo.UserProfileValue.RecordID
WHERE     (dbo.UserProfileValue.PropertyID = 5090) AND (dbo.UserProfileValue.PropertyVal IS NULL OR
                    dbo.UserProfileValue.PropertyVal = '') 

Error: feature with ID is not installed in this farm and cannot be added to this scope

While working on a SharePoint 2013 development server which is a multi server farm, we will face issues in doing auto deployments from visual studio. There is a workaround for the same posted here. http://www.youvegotcode.com/2014/11/error-feature-with-id-is-not-installed.html