SharePoint: Considerations when switching from FIM Sync to AD Import

Many times we end up battling “SharePoint Profile Synchronization” (aka: “FIM Sync”) for a while before we realize that “SharePoint Active Directory Import” (aka: “AD Import”, aka: “ADI”) was a better fit all along.

Why switch?  Or for new farms, why go with AD Import?

“SharePoint Active Directory Import” (“AD Import” from here on) is the preferred and recommended user profile import mechanism for SharePoint 2013 and above.  In fact, in SharePoint 2016, the “FIM Sync” option no longer exists, so if you’re on SharePoint 2013 and still clinging to FIM Sync, you’ll need to start looking into either AD Import or an external identity manager like “Microsoft Identity Manager” (MIM) 2016.

Here are some really good reasons for using AD Import:

  • It’s fast.  I mean, really fast compared to FIM Sync.  Mileage will vary, but in many cases something on the order of 10x faster.
  • There’s no Synchronization Service to battle.  The User Profile Synchronization Service is still around in SharePoint 2013, but AD Import doesn’t use it, so you don’t have to worry about starting it, which is almost always a pain.
  • It also does not use the Sync database.  Your User Profile Service Application (UPA) will still have a Sync database, but it will remain empty and unused.  All AD Import configuration is stored in the Profile database.
  • Did I mention it’s fast?  That’s usually the seller.  Customers with 500,000+ profiles would previously wait a week or more for a Full Sync to complete.  With AD Import, the same Full Import generally takes a day or less.

It’s not a free meal.

To be fair, AD Import is not for everyone.  There are some configurations where AD Import just doesn’t have the ability to meet some profile import requirements, and therefore you must use FIM Sync (or an external identity provider if you’re using SharePoint 2016).  The list of those drawbacks is in the “Situations unsupported by AD Import” section here:

There are a number of things listed there, but we’ve found that the primary limitations that cause customers to go with FIM Sync are the following:

  • AD Import only supports Active Directory as the identity store.  So if you have any 3rd party LDAP provider, you need to use FIM / MIM.
  • AD Import is import only.  You can’t export values to AD.
  • AD Import cannot import BDC / BCS data.
  • AD Import cannot import user profile pictures.

We’ve found that the profile picture one is a major hang-up, but there are alternative solutions:

Important: While it’s perfectly ok to switch an existing UPA from FIM Sync to AD Import, I strongly recommend disabling the My Site Cleanup Job (timer job) until you’ve run through a few AD Imports and are happy with the results.

So now lets assume you’ve decided to switch to AD Import.

Good for you.  However, AD Import does work a bit differently, so here are some additional considerations.  — These are not necessarily “drawbacks”, just differences to be mindful of.

  • The connection filters are implemented differently.  Instead of the FIM exclusion filters, you just set a standard LDAP filter on the import connection page.  Those familiar with LDAP find this a welcome change as it’s a standardized syntax.  Not to mention, it’s much easier to replicate (just copy and paste) between farms.
    • Note: when using AD Import, the “Edit Connection Filters” drop-down still exists on the import connection.  However, it won’t work and throws this error:

    • Like I said, AD Import filters are implemented differently.  You define the LDAP filter on the edit import connection page:

  • Troubleshooting is different.  There is no “FIM Client” to look at when things go wrong.  All importing is done by a timer job called “<UPAName> – User Profile Active Directory Import Job”.  To figure out what happened with the import, you should be reviewing the SharePoint ULS logs from the server that ran the timer job — check timer job history first to make sure you have the correct server and correct instance of the timer job.
    • Here’s some PowerShell you can use to see when and where the last 5 runs of the AD import timer job ran. Just keep in mind the time stamps shown are in UTC, so you’ll need to convert to local server time zone.
      #Check which server has been running the AD import job:
      Add-PSSnapin microsoft.sharepoint.powershell
      $tjs = Get-SPTimerJob | ? {$_.displayname -match “ActiveDirectory”}
      foreach ($tj in $tjs)
      $tj.historyentries | select StartTime, EndTime, ServerName, status -first 5 | sort -Descending starttime}

  • Property mappings look different.  The out-of-box mappings are pretty much the same as when using FIM Sync.  However, it’s hard to tell because you can’t see them in Central Administration.  I explain in more detail in another post here.
  • “Out of Scope” (deleted, filtered, moved to a non-imported OU) users do not have their profiles automatically cleaned up by an incremental import.  With AD Import, we don’t use the Sync database to store “state” information about each user.  As such, the only way AD Import can tell if a user has fallen “out of scope” is to import them.  Luckily, AD Import is fast, so running a Full import is usually not a big deal.  For more on this, see this post by one of my colleagues. Also, check out my 4-part series on cleaning up user profiles:
  • You must create one import connection per-domain.  You can’t just create one connection at the Forest-level anymore. 
    You must create a separate connection for each domain.

Lets talk about that last point a bit more.

If you have a lot of domains, that initial setup can be a bit painful.  To add to that, any custom profile property mappings you create must be done per-import connection.  This means that if you have 10 domains and 10 custom mappings you want to make, you’re making 100 total mappings.  Ouch.  But… once again, PowerShell is your friend.  While there isn’t a great way to use PowerShell to create the import connections for SharePoint on-premise environments, you certainly can (and should) use it to create any custom property mappings.

There are several examples out there showing how to create AD Import connection property mappings, but I found that none of them really accounted for handling multiple mappings or multiple import connections, so I wrote one.

A couple of notes about this script:

  • First off, it’s a sample only.  I’m not going to “support” it.  Test it, tweak it, and make it your own.
  • It makes a few assumptions like:
    • If you’re trying to map to custom profile properties, those properties have already been created in the UPA.
    • You are trying to map the same AD attributes to the same profile properties for each domain / import connection.  If you need to make different mappings for one or more domains, this script is not for you as-is, but can still be used as a starting point.
  • It reads AD-Attribute / SharePoint-Property pairs from a CSV and creates the property mappings.  It also loops through each import connection and makes the same mappings for each connection.
  • The idea here, is that after your import connections are created, you could run this script once and all your custom mappings will be made across all import connections.

Here’s what an example input CSV file looks like:

Note: The first row (ad,sharepoint) is a “header” row and should be left as is.  The additional rows hold the name of each AD attribute and then the comma-separated name of the SharePoint profile property you want to map it to.

Here’s the SAMPLE script:

############################## -- Script -- ##############################
 #Author: Joroar
 #Date: 8/13/17
 #This script is provided as-is with no warranties expressed or implied. Please have good and current backups.
 #Synopsis: Use this to create profile property mappings for Active Directory Import from a list of profile properties and AD attributes stored in a CSV
 #The CSV should have a 'header row' and look something like this with a single AD attribute / SharePoint property pair on each line:
    #  ad,sharepoint
    #  streetaddress,sps-location
    #  givenname,firstname
    #  sn,lastname
 #It will also loop thorough each AD Import connection you have and make the same mappings there.
 #Important!  The script assumes that the mappings you want to create have the same AD attribute name in EVERY domain. 
 #If you want to make different mappings for each connection, this script is NOT for you, but could still be a good starting point.
 #The “$URL” variable can really be any site collection in the farm that is associated with the target User Profile Service App.  
 #Just set the top three variables: $url, $path, $logfile
$path = "C:\Temp\mappings\Properties.csv"  #This is the CSV that contains the mappings
$logfile = "C:\Temp\mappings\PropertyMappingLog.txt"  #This is the output log file
$URL = "" #Any site associated with the UPA
#Shouldn't need to change anything below this line:
Add-PSSnapin microsoft.sharepoint.powershell
$date = Get-Date -Format U
"Started creating property mappings at " + $date + " (UTC time)" | out-file $logfile -append
"=================================================================" | out-file $logfile -append
$ErrorActionPreference = "stop"
$csv = Import-Csv -Path $path
[array]$Properties = @()
foreach($line in $csv)
{$Properties += $line}
$Total = $Properties.Count
$site = get-spsite $url
$context = [Microsoft.SharePoint.SPServiceContext]::GetContext($site)
$configManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileConfigManager $context
$UPAConnMgr = $configManager.ConnectionManager
foreach($Connection in $UPAConnMgr)
"Creating Mappings For Connection: "  + $connection.Displayname | out-file $logfile -Append
Write-host "Creating Mappings For Connection: " $connection.Displayname 
    for($j=0; $j -lt $Total; $j++)
    $adAttribute = $Properties[$j].ad
    $spsProperty = $Properties[$j].sharepoint
        "Creating mapping between " + $adAttribute  + " and " + $spsProperty | out-file $logfile -Append
        Write-host "Creating mapping between  $adAttribute and $spsProperty"
        catch [system.Exception]
        {"ERROR!!! adding mapping for property: " + $spsProperty + " -- " + $_.Exception.Message | out-file $logfile -append
        Write-host "we seem to have hit an error.  Check the log file"}
    "---------------------------------" | out-file $logfile -Append
    catch [system.Exception]
    {"ERROR!!! updating connection " + $connection.Displayname + $_.Exception.Message | out-file $logfile -append
    Write-host "we seem to have hit an error.  Check the log file"
############################## -- Script -- ##############################

More Keywords for Bing:

Forefront Identity Manager FIM

Microsoft Identity Manager MIM

SharePoint Server 2013 2016

Miisclient.exe FIM Client

Active Directory Import AD Import ADI

One Comment

Add a Comment