Problem:
You need to know which Active Directory groups your MOSS 2007 (SharePoint) user belongs to. (This can be useful for security management, Infopath forms, etc.).
However, out of the box in SharePoint, you can’t set up a mapping from Active Directory to SharePoint and retrieve a list of AD groups that the user belongs to. Active Directory stores this information in the memberOf property of the user account; however, this property cannot be mapped to a SharePoint profile property. (See this TechNet forum post for more details.)
Solution:
You can set up a custom property in SharePoint and run a PowerShell script which will update your SharePoint user profiles with the memberOf value from AD. I tested this solution in our Dev environment with over 2,000 SharePoint profiles and it worked as expected.
Here’s how to do it.
1. Create a new custom property in SharePoint. Navigate to your CA site > SSP administration page > User profiles and properties > View Profile Properties and click on “New Property”.
2. Create a new custom property (mine is called “ADSecurityGroups”). Make sure to specify sufficient field length (I used 255), and leave “Allow multiple values” checkbox cleared.
When finished entering values, click OK.
4. Create the following PowerShell script and modify it with your values for $ADdomain, $siteUrl, $SSP, and $propName. Execute the script using a domain account with Read access to AD and farm administrator access to SharePoint. If you copy and paste the script, check for wrapping code.
This script will have to be executed regularly (nightly) as a scheduled task on your SharePoint server, to keep your SharePoint profile properties sync’d with AD.
Warning: Make sure to test this script carefully in your TEST environment, before executing in Production!
[void][reflection.assembly]::Loadwithpartialname("Microsoft.SharePoint") | out-null [void][reflection.assembly]::Loadwithpartialname("Microsoft.Office.Server.Search") | out-null [void][reflection.assembly]::Loadwithpartialname("Microsoft.Office.Server") | out-null # Step 1: Defining Get-UserDN function. # Function: Get-UserDN # Description: This function accepts as input user's samAccountName value, # finds the user in Active Directory, and returns their DistinguishedName. function Get-UserDN($SAMName) { $root = [ADSI]'' $searcher = new-object System.DirectoryServices.DirectorySearcher($root) $searcher.filter = "(&(objectClass=user)(sAMAccountName=$SAMName))" $user = $searcher.findone() return $user.GetDirectoryEntry().DistinguishedName } # *** Script routine starts here... *** # Step 2: Assigning values to Active Directory domain, siteUrl, SSP, and SharePoint custom property name. # *** Enter your own domain values here *** # Enter domain name, SharePoint URL, SSP name, and AD security group property name $ADdomain = "AD" $siteUrl = "http://sharepoint/" $SSP = "SharedServicesProvider" $propName = "ADSecurityGroups" # Step 3: Connecting to the User Profile manager and get a collection of user profiles $ServerContext = [MIcrosoft.Office.Server.ServerContext]::GetContext($SSP) $UserProfileManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($ServerContext) $Profiles = $UserProfileManager.GetEnumerator() # Step 4: Enumerating through each of the user profiles foreach($oUser in $Profiles) { $groupList = "" # get username property value, usually mapped to samAccountName property in AD $user = $oUser.Item("UserName") # call Get-UserDN function to get the user's DistinguishedName $userDN = Get-UserDN($user) # Step 5: Use Distinguished Name value to obtain a list of AD groups # where the user is a member (using memberOf property) $ADgroups = ([ADSI]"LDAP://$userDN").memberOf # Step 6: Enumerate through each of the AD groups and get the group's samAccountName, # appending it to the results string, separated by ";" foreach($ADgroup in $ADgroups) { $groupName = [ADSI]("LDAP://$ADgroup") $groupList = $groupName.sAMAccountName.ToString() + ";" + $groupList } # Step 7: Updating the SharePoint custom property with AD security groups info. if ($UserProfileManager.UserExists("$ADdomain\$user")) { $userProfile = $UserProfileManager.GetUserProfile("$ADdomain\$user"); $tempProp = $UserProfileManager.Properties.GetPropertyByName($propName); $userProfile[$propName].Value = $groupList; $userProfile.Commit(); Write-Host "'$propName' User Profile Property updated to '$groupList' for '$ADdomain\$user'" } else { Write-Host "User '$ADdomain\$user' does not exist in User Profiles!"; } } # Finished! write-host "Job is complete."