PortiBlog

SharePoint 2013 - User profile service - change order user profile properties - Duplicate display id

8 mei 2014

We have recently deployed SharePoint 2013 on server 2012. I ran into an issue with the user profile service where we couldn't change the position of a certain custom user profile property past a certain point.

First I looked closer at the default Display Order for existing properties in SQL in the user profile DB, I noticed several were duplicated. And that is also a bug in Sharepoint 2010. Below you see how you can see what is wrong.

2 type of tables to check Select top 1000 rows
1 2

You can see below that there are duplicate display id’s. You can match/find the property ID in the PropertyList table. Do Not change anything in database itself!! A script will talk to the client object model of SharePoint to get rid of this problem nasty BUG.

ProfileSubtypePropertyAttributes PropertyList
3  4

Things to do:

1. The account you run the script must have the permissions to the user profile servers itself:

Set the account you run the script to the administrators and gif it all the permissions

  • Full Control
  • Manage Profiles
  • Manage Audiences
  • Manage Permissions
  • Retrieve People Data for Search Crawlers
  • Manage Social Data

 

5

2. Set the account you run the script to the connection permissions

  • Full Control
7

 3. Run the following script. Save it as changeorder.ps1 and run SharePoint managed Shell. You only have to change ‘$siteUrl = http://<mysitehostheader>In your own mysite host url.

You can choose export and import. First choose export. The file will be exported to: C:\Users\<youreuser>

6

#This is the xml template into which properties are exported$template = "

<Properties>

<Section Name="""" Order="""" >

<Property Name="""" Order="""" />

</Section>

</Properties>"

 

#xml template is saved out

$template | out-file $home\output.xml

$xml = New-Object XML

$xml.Load("$home\output.xml")

 

#IMPORTANT...fill this section out before executing script

$siteUrl = "http://<mysitehostheader>"

 

 

function exportProfileProperties()

{

#connect to upa

$site = Get-SPSite $siteUrl

$context = Get-SPServiceContext $site

$psm = [Microsoft.Office.Server.UserProfiles.ProfileSubtypeManager]::Get($context)

$col = $psm.GetSubtypesForProfileType("User")

 

#load xml template

$sectionTemplate = @($xml.Properties.Section)[0]

$propertyTemplate = @($xml.Properties.Section.Property)[0]

 

$newSection = ""

 

#parse sections and properties and generate xml structure

foreach($propFromUPA in $col.PropertiesWithSection)

{

if($propFromUPA.IsSection -eq $true)

{

$newSection = $sectionTemplate.Clone()

$newSection.Name = $propFromUPA.Name

$newSection.Order = $propFromUPA.DisplayOrder.ToString()

$xml.Properties.AppendChild($newSection)

}

else

{

$newProp = $propertyTemplate.Clone()

$newProp.Name = $propFromUPA.Name

$newProp.Order = $propFromUPA.DisplayOrder.ToString()

$newSection.AppendChild($newProp)

}

#cleanup xml

$newSection.Property | where-object{$_.Name -eq ''} | ForEach-Object {$newSection.RemoveChild($_)}

}

 

#cleanup xml

$xml.Properties.Section | where-object {$_.Name -eq ''} | ForEach-Object {$xml.Properties.RemoveChild($_)}

 

#save xml

$xml.Save("$home\output2.xml")

 

write-host "File has been exported to " + "$home\output2.xml"

write-host "Edit the file by updating the display order and the location where you want to property to be"

write-host "Then run this script again to in Import mode"

 

}

 

function importProfileProperties($fileLocation)

{

#load xml

$inputXML = [XML] (Get-Content $fileLocation)

 

#connect to upa

$site = Get-SPSite $siteUrl

$context = Get-SPServiceContext $site

$upcManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileConfigManager($context)

$defaultUserProfileSubTypeName = [Microsoft.Office.Server.UserProfiles.ProfileSubtypeManager]::GetDefaultProfileName("User")

$profileSubtypePropManager = $upcManager.ProfilePropertyManager.GetProfileSubtypeProperties($defaultUserProfileSubTypeName)

 

#read entries in xml file

foreach($section in $inputXML.Properties.childnodes)

{

#process sections

Write-Host $section.Name

$profileSubtypePropManager.SetDisplayOrderBySectionName($section.Name,$section.Order)

#process properties within sections

foreach($property in $section.childnodes)

{

Write-Host $property.Name

$profileSubtypePropManager.SetDisplayOrderByPropertyName($property.Name,$property.Order)

}

}

 

#verify user wants to commit

$commit = Read-Host "Press Y to commit changes or CTRL+C to exit "

if ($commit.ToLower() -eq 'y')

{

$profileSubtypePropManager.CommitDisplayOrder()

}

 

}

 

 

$userInput = Read-Host "Type E to export the current properties OR I to import a config file "

 

if ($userInput.ToLower() -eq "e")

{

exportProfileProperties

}

elseif($userInput.ToLower() -eq "i")

{

$fileLocation = Read-Host "Type in the path to the input file "

importProfileProperties($fileLocation)

}

 4. Now the export is ready you can change the order and display id. If you want to set a property you have to set the same id as above or you have to change all id. See my example. Do not change de name itself!!

<Section Name="SPS-Section-BasicInfo" Order="0"><Property Name="UserProfile_GUID" Order="1" />

<Property Name="SID" Order="2" />

<Property Name="ADGuid" Order="3" />

<Property Name="AccountName" Order="4" />

<Property Name="SPS-PhoneticDisplayName" Order="4" />

<Property Name="FirstName" Order="5" />

<Property Name="SPS-PhoneticFirstName" Order="6" />

<Property Name="LastName" Order="7" />

<Property Name="SPS-PhoneticLastName" Order="8" />

<Property Name="PreferredName" Order="9" />

<Property Name="SPS-PhoneticDisplayName" Order="10" />

 5. Now the xml is ready. Just run the script again with ‘import - i’. Refresh / reload the user profile properties and the order is changed and quickly NOT BY HAND.

Other things to know.

The script will also help you the change the order of the properties fast and not clicking by hand. I hope Microsoft will fix this bug in the future.

In summary,

Follow this blog and it will work. For questions just contact me.

Submit a comment