SharePoint 2013: Another way to change order of user profile properties via powershell

  • Comments 5
  • Likes

I recently ran into an issue where we couldn't change the position of a certain custom user profile property past a certain point.

Looking around the web, I found several resources such as this (Kudos to the author), that provided a way to reorder the profile properties. However, when I looked closer at the default DisplayOrder for existing properties, I noticed several were duplicated.

 


 

I have a feeling the duplicate display order values have something with the inability to move properties around through Central admin.

 

As such, the following solution allows:

- exporting all the properties and sections out to an XML file

- you the Admin, can then clean up the XML, define the order of properties (ie use this mechanism to move properties up and down)

- importing the cleaned up XML

 

The script is as follows. Just copy and paste into powershell ISE or save as a .ps1 file.

The script will prompt you to select whether you want to Export or Import....pay attention to the prompts. It should be pretty self explanatory.

 

 

#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 = https://URLtoSiteCollection

 

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)
}

Comments
  • Works fine with SharePoint 2013! Finally a solution for the reordering bug! You are great! Thanks!

  • hey, thanks for this. Great stuff !

  • Fantastic, many thanks!

  • I cannot get this to work. The error is UserProfileApplication.SqlSession has empty Application ID.
    I am new to powershell.
    pleaes help

  • I cannot get this to work this either. The error is UserProfileApplication.SqlSession has empty Application ID. It looks like it is unable to get the context although I am giving the correct sharepoint url.

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment