Here is one of my first Powershell scripts (so improvement suggestions welcome 🙂
The requirement was to script the creation of SharePoint Organization Profiles from Active Directory Organizational Units, including building the hierarchy and setting the Profile Subtype appropriately. Creation of the Organizational Profiles was based on the C# code in the How to: Create User Profiles and Organization Profiles MSDN article.
Before running this note that i had a predefined list of profile subtypes that corresponded to the level of the organizational unit in the hierarchy. The top level was Root, next level was Group, then Division, Branch & finally Section. The following is an example of the organizational structure in terms of Profile Subtypes.
- Department (Root Level)
- Group #1
- Division #1
- Branch #1
- Section #1
- Branch #1
- Division #2
- Branch #2
- Section #2
- Section #3
- Section #4
- Branch #3
- Section #5
- Section #6
- Branch #2
- Division #4
- Branch #7
- Division #1
- Group #2
- Division #5
- Branch #8
- Section #9
- Branch #8
- Division #6
- Branch #9
- Section #10
- Section #11
- Section #12
- Branch #9
- Division #6
- Branch #9
- Division #5
- Group #1
#Create All Organisation Profiles from AD OU's #Load Sharepoint Snapin Add-PSSnapin Microsoft.SharePoint.PowerShell #Declare Some Globals for Profile Management $context = Get-SPServiceContext -Site http://{sharepointwebappurl}/ $psm = [Microsoft.Office.Server.UserProfiles.ProfileSubtypeManager]::Get($context); $opm = New-Object Microsoft.Office.Server.UserProfiles.OrganizationProfileManager($context) $rootOrg = $opm.RootOrganization #Find All Children OU's Based on Parent OU's Distinguished Name (DN) function Find-Child-OUs { Param ([string]$sParentDN) $ldapPath = "LDAP://" + $sParentDN $query = new-object system.directoryservices.directorysearcher([ADSI]$ldapPath) #Only Search for OUs $query.filter = "(objectClass=organizationalUnit)" #Only Search One Level Deep (ie. Children) $query.SearchScope = "OneLevel" $results = $query.findAll() Write-Host $sParentDN " has " $results.Count " children" return $results } #Create an Organization Profile under parentOrg for provided OU function Create-Organization { Param ($ou, $parentOrg, $levelTitle) Write-Host "Creating:" $ou.description "under" $parentOrg.DisplayName "of type" $levelTitle $subType = $psm.GetProfileSubtype($levelTitle); $orgProfile = $opm.CreateOrganizationProfile($subType, $parentOrg) $orgProfile.DisplayName = $ou.description $orgProfile.Commit() return $orgProfile } #Determine Subtype Based on Level function Get-Level-ProfileSubtype { Param ($level) $subtypeTitle = $level switch ($level) { 0 { $subtypeTitle = "Root"; break } 1 { $subtypeTitle = "Group"; break } 2 { $subtypeTitle = "Division"; break } 3 { $subtypeTitle = "Branch"; break } 4 { $subtypeTitle = "Section"; break } default { $subtypeTitle = "Other" } } return $subtypeTitle } #Create Organization Profiles for All OU's underneath the provided OU and Organization Profile function Create-Child-Orgnizations { Param ([string]$currentOuDn, $parentOrg, $level) #Create the Organization Write-Host "Searching for Children for: " $currentOuDn $children = Find-Child-OUs $currentOuDn if ($children -ne $null) { Write-Host -ForegroundColor red $children.Count "OU's found under:" $currentOuDn Foreach($childOu in $children) { $ou = $childOu.GetDirectoryEntry() $ouDn = $ou.distinguishedname $levelTitle = Get-Level-ProfileSubtype($level) #Create the Child Organization $newOrg = Create-Organization $ou $parentOrg $levelTitle Write-Host -ForegroundColor green "OU Created: " $newOrg.DisplayName " = " $newOrg.ProfileSubtype.Name $nextLevel = $level + 1 Create-Child-Orgnizations $ouDn $newOrg $nextLevel } } } #Create All Organization Profiles Starting from Provided OU DN function Create-All-Organizations { Param ([string]$rootOuDn) Create-Child-Orgnizations $rootOuDn $rootOrg 1 }
Once you have loaded all the globals and declared all the functions above the following two lines (can be done in one) will begin the profile creation.
#Run Creation From Root Orgnization Unit, Make sure the following matches the LDAP query to the Root OU in your AD structure. $rootOu = "OU=Department,DC=depttest,DC=gov,DC=au" Create-All-Organizations $rootOu
To help with testing & re-running code i also created a couple of functions to (a) List all Organizational Profiles under a parent and (b) Delete all Organization Profiles under a parent.
#Retrieve existing Org Profiles function List-OrgProfiles { Param($parentOrg) if ($parentOrg.HasChildren) { foreach ($childOrg in $parentOrg.GetChildren()) { Write-Host $parentOrg.DisplayName "-" $childOrg.DisplayName List-OrgProfiles $childOrg } } } #Delete existing Org Profiles function Delete-OrgProfiles { Param($parentOrg) # If Parent Has Children Delete them first if ($parentOrg.HasChildren) { foreach ($childOrg in $parentOrg.GetChildren()) { #Write-Host $childOrg.DisplayName " - " $parentOrg.DisplayName Delete-OrgProfiles $childOrg } #Once children are deleted remove the current org if ($parentOrg.RecordId -ne $opm.RootOrganization.RecordId) { $opm.RemoveOrganizationProfile($parentOrg.RecordId) Write-Host "Removing(" $parentOrg.DisplayName ")" } else { Write-Host "KEEP (" $parentOrg.DisplayName ")" } } else { #If not children then delete the current org if ($parentOrg.RecordId -ne $opm.RootOrganization.RecordId) { $opm.RemoveOrganizationProfile($parentOrg.RecordId) Write-Host "RemovingChildless(" $parentOrg.DisplayName ")" } else { Write-Host "Childless KEEP(" $parentOrg.DisplayName ")" } } }