• images
  • 1:50 am
  • images
  • 3 Comments.

Create, update and order user profile properties using Powershell in Sharepoint 2013

User profile properties can be created and managed using the graphical interface inside SharePoint central admin.(Central Admin -> Manage Service Applications -> User Profile Service Application -> Manage User Properties). But in a real production scenario where lot of user profile properties need to be created and ordered, the GUI way becomes extremely tedious and timetaking. But, don’t worry, we can automate everything using powershell :-).

Below is the powershell script which creates and updates (if prop already exists) the different user profile properties and orders them also by reading from a XML file.

#Script to find all employees/contractors who roll up to a manager and add their usernames to the manager's colleague list in SharePoint 
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server")  
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles")  
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles.UserProfileManager")  
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")  

$filePath = "Path to XML file containing user profile props";
$siteName = "Site url";

clear-host
#add sharepoint cmdlets
if ( (Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null )
{    
      Add-PsSnapin Microsoft.SharePoint.PowerShell
}

[System.Xml.XmlDocument] $XmlDoc = new-object System.Xml.XmlDocument
$file = resolve-path($filePath)

if (!$file)
{
    Write-Host "Could not find the configuration file specified. Aborting." -ForegroundColor red       
    Break
}

write-host "Parsing file: " $file
$XmlDoc = [xml](Get-Content $file)

                #Preparing connection manager#

        $site = new-object Microsoft.SharePoint.SPSite($siteName);  
        $context = [Microsoft.SharePoint.SPServiceContext]::GetContext($site);  

        if (!$context)
        {
        write-host "context is empty, quitting!"
        break
        }

            #$context = new-object Microsoft.SharePoint.SPServiceContext.GetContext($site); 
            $UPAConfMgr = new-object Microsoft.Office.Server.UserProfiles.UserProfileConfigManager($context)

        if (!$UPAConfMgr)
        {
        write-host "confmgr is empty, quitting!"
        break
        }

        $UPAConnMgr = $UPAConfMgr.ConnectionManager
                $userprofiletype = [Microsoft.Office.Server.UserProfiles.ProfileType]::User
                    $CurrentConnection = $UPAConnMgr | where {$_.AccountDomain -eq $ConnectionDomain}
                $PropertyMapping = $CurrentConnection.PropertyMapping

                                $userProfilePropertyManager = $UPAConfMgr.ProfilePropertyManager
                                $userProfileTypeProperties = $userProfilePropertyManager.GetProfileTypeProperties($userprofiletype)

                                #Creating core properties
                                $CoreProperties = $UPAConfMgr.ProfilePropertyManager.GetCoreProperties()                              

                    #####################
                    #Creating properties#
                    #####################

Write-Host "Creating user profile properties." -ForegroundColor green
                                $PropertyNodeList = $XmlDoc.Connections.Connection.PropertyCreations

                                #Checking if the servicecontext (the site specified in the  attribute
                                #in the parse file actually exist. If not, we cannot continue.
                                if (!$context) 
                                {
                                                Write-Host "There are entries in the  node in the parse file, but the  node contains a URL to a site that does not exist. Critical error, cannot continue." -ForegroundColor red
                                                Break
                                }
                                $userProfileSubTypeManager = [Microsoft.Office.Server.UserProfiles.ProfileSubtypeManager]::Get($context)
                                $userProfile = $userProfileSubTypeManager.GetProfileSubtype([Microsoft.Office.Server.UserProfiles.ProfileSubtypeManager]::GetDefaultProfileName($userprofiletype))
                                $userProfileProperties = $userProfile.Properties

        #$userProfileProperties.RemovePropertyByName("State");  
        #write-host -f red "deleted state"
        #break

                                foreach ($PropertyNode in $PropertyNodeList.ProfilePropertyCreation) 
                    {
            #write-host "Creating " $PropertyNode.InnerText
                                    if ($PropertyNode)
                                                {
               #$ProfilePropertyCreation.Privacy = "public"
                #$ProfilePropertyCreation.PrivacyPolicy = "option"

                                                                #Fetching information for the new property.   userOverridePrivacy="0" isReplicable="1"
                                                                $ProfilePropertyCreation = $PropertyNode#.SelectSingleNode("ProfilePropertyCreation")
                                                                $SharePointProp = $ProfilePropertyCreation.InnerText
                                                                $SharePointPropDisplayName = $ProfilePropertyCreation.DisplayName
                                                                $SharePointPropPrivacy = $ProfilePropertyCreation.Privacy.ToLower()
                                                                $SharePointPropPrivacyPolicy = $ProfilePropertyCreation.PrivacyPolicy.ToLower()
                                                                $SharePointPropType = $ProfilePropertyCreation.PropType.ToLower()
                                                                $SharePointPropLength = $ProfilePropertyCreation.PropLength
                                                                $SharePointPropIsVisibleOnEditor = $ProfilePropertyCreation.IsVisibleOnEditor
                                                                $SharePointPropIsVisibleOnViewer = $ProfilePropertyCreation.IsVisibleOnViewer
                                                                $SharePointPropDisplayOrder = $ProfilePropertyCreation.DisplayOrder
                                                                $SharePointPropIsEventLog = $ProfilePropertyCreation.IsEventLog
                                                                $SharePointPropIsUserEditable = $ProfilePropertyCreation.IsUserEditable
                                                                $SharePointUserOverrideprivacy = $ProfilePropertyCreation.UserOverridePrivacy  
                                                                $SharePointSectionName = $ProfilePropertyCreation.Section     

                                                                $SharePointPropDisplayOrder = [int]$SharePointPropDisplayOrder                                                                                                                         

                                                                #Basic syntax checking of $SharePointPropPrivacy attribute
                                                                $PrivacyMembers = "public", "contacts", "Organization", "Manager", "Private"
                                                                if (!($PrivacyMembers -contains $SharePointPropPrivacy))
                                                                {
                                                                                Write-Host "The new SharePoint property `"$SharePointProp`" contains an invalid privacy attribute ($SharePointPropPrivacy). The allowed entries are: public, contacts, Organization, Manager, Private. Skipping attribute." -ForegroundColor red
                                                                                Continue
                                                                }

                                                                #Basic syntax checking of $SharePointPropPrivacyPolicy attribute
                                                                $PrivacyPolicyMembers = "mandatory", "optin","optout", "disabled"
                                                                if (!($PrivacyPolicyMembers -contains $SharePointPropPrivacyPolicy))
                                                                {
                                                                                Write-Host "The new SharePoint property `"$SharePointProp`" contains an invalid privacy policy attribute ($SharePointPropPrivacyPolicy). The allowed entries are: mandatory, optin,optout, disabled. Skipping attribute $SharePointProp." -ForegroundColor red
                                                                                Continue
                                                                }

                                                                #Basic syntax checking of $SharePointPropType attribute
                                                                if ($SharePointPropType -ne "string")
                                                                {
                                                                                Write-Host "Currently the script only able to create `"String`" type of attributes. The attribute provided is: $SharePointPropType. Skipping attribute $SharePointProp." -ForegroundColor red
                                                                                Continue
                                                                }

                                                                #Basic syntax checking of $SharePointPropLength attribute
                                                                $loaderror = [Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
                                                                if ($loaderror -ne "Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
                                                                {
                                                                                $IsNumber = [Microsoft.VisualBasic.Information]::isnumeric($SharePointPropLength)

                                                                                if (!$IsNumber)
                                                                                {
                                                                                                Write-Host "The property length specified for this attribute is invalid. Skipping attribute $SharePointProp." -ForegroundColor red
                                                                                                Continue
                                                                                }
                                                                }

                                                                #Basic syntax checking of $SharePointPropLength attribute
                                                                $loaderror = [Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
                                                                if ($loaderror -ne "Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
                                                                {
                                                                                $IsNumber = [Microsoft.VisualBasic.Information]::isnumeric($SharePointPropDisplayOrder)

                                                                                if (!$IsNumber)
                                                                                {
                                                                                                Write-Host "The property length specified for this attribute is invalid. Skipping attribute $SharePointPropDisplayOrder." -ForegroundColor red
                                                                                                Continue
                                                                                }
                                                                }

                                                                if($SharePointPropIsVisibleOnEditor -eq "1")
                                                                {
                                                                    $SharePointPropIsVisibleOnEditor = $true
                                                                }
                                                                else
                                                                {
                                                                    $SharePointPropIsVisibleOnEditor = $false
                                                                }
                                                                if($SharePointPropIsVisibleOnViewer -eq "1")
                                                                {
                                                                    $SharePointPropIsVisibleOnViewer = $true
                                                                }
                                                                else
                                                                {
                                                                    $SharePointPropIsVisibleOnViewer = $false
                                                                }
                                                                if($SharePointPropIsEventLog -eq "1")
                                                                {
                                                                    $SharePointPropIsEventLog = $true
                                                                }
                                                                else
                                                                {
                                                                    $SharePointPropIsEventLog = $false
                                                                }
                                                                if($SharePointPropIsUserEditable -eq "1")
                                                                {
                                                                    $SharePointPropIsUserEditable = $true
                                                                }
                                                                else
                                                                {
                                                                    $SharePointPropIsUserEditable = $false
                                                                }
                                                                 if($SharePointUserOverrideprivacy -eq "1")
                                                                {
                                                                    $SharePointUserOverrideprivacy = $true
                                                                }
                                                                else
                                                                {
                                                                    $SharePointUserOverrideprivacy = $false
                                                                }                                                              

                                                                $sec = $userProfileProperties.GetSectionByName($SharePointSectionName);

                                                                $NewUPProperty = $userProfileProperties.GetPropertyByName($SharePointProp)   #sproperty

                                                                if($NewUPProperty -eq $null)
                                                                {
                               Write-Host "Creating " $sharepointpropdisplayname                                 

                                                                #Creating a NewProperty with basic attributes
                                                                $NewProperty = $CoreProperties.Create($false)
                                                                $Newproperty.Name = $SharePointProp
                                                                $NewProperty.DisplayName = $SharePointPropDisplayName
                                                                $NewProperty.Type = $SharePointPropType
                                                                $NewProperty.Length = $SharePointPropLength

                            #Write-Host $sharepointpropdisplayname 

                                                                #Adding the new property to the core properties list
                                                                $CoreProperties.Add($NewProperty)

                                                                #Reinitializing the newly created property to change secondary attributes.
                                                                $NewTypeProperty = $userProfileTypeProperties.Create($NewProperty)                                                                

                                                                #Display attributes
                                                                $NewTypeProperty.IsVisibleOnEditor = $SharePointPropIsVisibleOnEditor
                                                                $NewTypeProperty.IsVisibleOnViewer = $SharePointPropIsVisibleOnViewer 
                                                                $NewTypeProperty.IsEventLog = $SharePointPropIsEventLog

                                                                #Updating the new property's secondary attributes
                                                                $userProfileTypeProperties.Add($NewTypeProperty)

                                                                #Reinicializing the newly created property to privacy attributes.
                                                                $NewSubProperty = $userProfileProperties.Create($NewTypeProperty)
                                                                $NewSubProperty.DefaultPrivacy = [Microsoft.Office.Server.UserProfiles.Privacy]::$SharePointPropPrivacy
                                                                $NewSubProperty.PrivacyPolicy = [Microsoft.Office.Server.UserProfiles.PrivacyPolicy]::$SharePointPropPrivacyPolicy

                                                                $NewSubProperty.IsUserEditable = $SharePointPropIsUserEditable

                                                                $NewSubProperty.UserOverridePrivacy = $SharePointUserOverrideprivacy

                                                                #Finalizing the new property.
                                                                $userProfileProperties.Add($NewSubProperty)

                                                                }
                                                                else
                                                                {

                                                        Write-Host "Updating " $sharepointpropdisplayname     

                                                                $NewUPTypeProperty = $userProfileTypeProperties.GetPropertyByName($SharePointProp)

                                                                $NewUPTypeProperty.CoreProperty.DisplayName = $SharePointPropDisplayName    

                                                                $NewUPTypeProperty.IsVisibleOnViewer = $SharePointPropIsVisibleOnViewer 
                                                                $NewUPTypeProperty.IsVisibleOnEditor = $SharePointPropIsVisibleOnEditor
                                                                $NewUPTypeProperty.IsEventLog = $SharePointPropIsEventLog

                                                                $NewUPProperty.DefaultPrivacy = [Microsoft.Office.Server.UserProfiles.Privacy]::$SharePointPropPrivacy
                                                                $NewUPProperty.PrivacyPolicy = [Microsoft.Office.Server.UserProfiles.PrivacyPolicy]::$SharePointPropPrivacyPolicy

                                                                $NewUPProperty.IsUserEditable = $SharePointPropIsUserEditable                                                                
                                                                $NewUPProperty.UserOverridePrivacy = $SharePointUserOverrideprivacy

                                                                $NewUPTypeProperty.CoreProperty.Commit()
                                                                $NewUPProperty.Commit()
                                                                $NewUPTypeProperty.Commit()

                                                                }

                                                                $err = $userProfileProperties.GetEnumerator()

                                                                #Setting the display order
                                                                if($ProfilePropertyCreation.DisplayOrder -ne "0")
                                                                {
                                                                    $userProfileProperties.SetDisplayOrderByPropertyName($SharePointProp,$sec.DisplayOrder + $SharePointPropDisplayOrder)
																	Write-Host "    Set user profile property `"$SharePointProp`"." " with display order $SharePointPropDisplayOrder +" $sec.DisplayOrder                                                     
                                                                }

                                                                Write-Host "    User profile property `"$SharePointProp`"." " added or updated"
                                                }
                                                else
                                                {
                                                                Write-Host "There are no profiles to be created in the parse file."
                                                }
                                }

                                $userProfileProperties.CommitDisplayOrder()

The input file format looks like this –

<?xml version="1.0" encoding="utf-8"?>
<Connections>
  <Connection name="Test">
    <PropertyCreations>
      <ProfilePropertyCreation DisplayName="Education" Privacy="public" PrivacyPolicy="optin" UserOverridePrivacy="1" PropType="string" PropLength="25" IsUserEditable="1" IsVisibleOnEditor="1" IsVisibleOnViewer="1" IsEventLog="1" DisplayOrder="0" Section="SPS-Section-Details">SPS-School</ProfilePropertyCreation>
    </PropertyCreations>
  </Connection>
</Connections>

The attributes in the input file are pretty direct and have a direct correlation to the attributes found in central admin. The extra attributes to note here are “DisplayOrder” and “Section”. These are used for ordering the attribute. “Section” refers to the section name which will contain our user profile property and “Order” refers to the position of our attribute inside the specified section.

To re-order a section, use a script like this-

 $sec = $userProfileProperties.GetSectionByName("SPS-Section-ContactInfo");  
 Write-Host $sec.DisplayOrder;
 $userProfileProperties. SetDisplayOrderBySectionName("MySection",$sec.DisplayOrder+12)

This script fetches the order of the “Contact Info” section and adds a custom section named “MySection” (created earlier) after that.

Also, please note that the above script currently works only for string type properties but it can be very easily modified to accomodate all kinds of properties. Also, it doesnot map the properties to AD props.

3 Comments

John

September 6, 2013 6:14 pm Reply

will this work with SharePoint 2010 as well?

admin

September 6, 2013 8:37 pm Reply

Hi John,

This will work nicely with SharePoint 2010 also. Just remove the extra SP2013 property assignments (m unable to compare with SP2010 env. now. so can’t provide u the exact names of those props) and you are good to go.

Leave a Reply