SharePoint Online: Sync User Profile Property from Azure AD using PowerShell
Requirement: Sync User Profile Property from Azure Active Directory to SharePoint Online using PowerShell.
How to sync a User Profile Property in SharePoint Online?
In a typical SharePoint Online environment, The user profile synchronization process imports user profiles from On-Premises AD to Azure (through AD Sync Tool), and then from the Azure Active Directory (AAD), certain properties are mapped and synchronized with the SharePoint Online User Profiles. Not all the properties from Azure AD are synced to SharePoint Online. I’ve got a requirement to sync the “Mobile Phone” Property to the SharePoint Online user profile. Although the Azure AD Sync tool imports the “Mobile” property from On-Premises AD, SharePoint doesn’t have a mapping for this property!
And the bad news is: currently, there are no ways to map and synchronize additional properties from the SharePoint Online Administration page (As we do in SharePoint On-Premises). However, we can loop through the users from Azure AD and update the User Profile Property in SharePoint Online using the CSOM PowerShell script.
PowerShell to import a User Profile Property in SharePoint Online:
Using the Azure AD PowerShell and the SharePoint Client-Side Object Model (CSOM), we can get the user profile property value from Azure AD and update the corresponding properties in the SharePoint Online User Profiles and then schedule this script to run on a regular basis. Let’s sync mobile phone from azure active directory to SharePoint Online using PowerShell.
#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.UserProfiles.dll"
Function Sync-UserProfileProperty()
{
Param
(
[Parameter(Mandatory=$true)] [string] $AdminSiteUrl,
[Parameter(Mandatory=$true)] [string] $UserPrincipalName,
[Parameter(Mandatory=$true)] [string] $ADPropertyName,
[Parameter(Mandatory=$true)] [string] $SPOPropertyName
)
#Get Credentials to connect
$Cred = Get-Credential
Try {
#Connect to AzureAD
Connect-AzureAD -Credential $Cred | Out-Null
#Get the User Property from AzureAD
$AzureADUser = Get-AzureADUser -ObjectId $UserPrincipalName
$ADUserPropertyValue = $AzureADUser | Select -ExpandProperty $ADPropertyName
#To get extended property value, use: $AzureADUser.ExtensionProperty.Item($ADPropertyName)
#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($AdminSiteUrl)
$Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
#Get User Profile Manager
$PeopleManager = New-Object Microsoft.SharePoint.Client.UserProfiles.PeopleManager($Ctx)
#Sync User Profile Property from AD
$UserAccount = "i:0#.f|membership|$UserPrincipalName"
$PeopleManager.SetSingleValueProfileProperty($UserAccount, $SPOPropertyName, $ADUserPropertyValue)
$Ctx.ExecuteQuery()
Write-host "User Profile Property has been Synched for: $UserPrincipalName" -f Green
}
Catch {
write-host -f Red "Error Synching User Profile Property!" $_.Exception.Message
}
}
#Config parameters
$AdminSiteUrl = "https://crecent-admin.sharepoint.com"
$UserPrincipalName = "[email protected]"
$ADPropertyName = "MobilePhone"
$SPOPropertyName = "CellPhone"
#Call the function to sync a Property from Azure AD to SharePoint Online
Sync-UserProfileProperty -AdminSiteUrl $AdminSiteURL -UserPrincipalName $UserPrincipalName -ADPropertyName $ADPropertyName -SPOPropertyName $SPOPropertyName
This PowerShell script imports a given property from Azure AD to SharePoint Online for a particular user. Make sure you have Azure AD Module installed in your machine prior to running this script:
Install-Module AzureAD
PowerShell to Sync User Profile Property Value for All Users
This time, let’s sync a user profile property for all users from Azure AD to SharePoint Online using PnP PowerShell. In addition, let’s check the following:
- If the AD user profile property has some value (not null!)
- If the user profile property in SharePoint Online doesn’t have any existing value in it!
#Config Variables
$AdminSiteURL = "https://crescent-admin.sharepoint.com"
$ADPropertyName = "Department"
$SPOPropertyName = "Department"
#Get Credentials to connect to Azure AD and SharePoint Online Admin Center
$Cred = Get-Credential
Try {
#Connect to AzureAD
Connect-AzureAD -Credential $Cred | Out-Null
#Get All Users of the Domain from AzureAD
$AllUsers = Get-AzureADUser -All:$True -Filter "UserType eq 'Member'"
Write-host "Total Number of User Profiles Found:"$AllUsers.Count
#Connect to PnP Online
Connect-PnPOnline -Url $AdminSiteURL -Credentials $Cred
#Iterate through All Users
$Counter = 1
ForEach($User in $AllUsers)
{
Write-host "`nUpdating User Profile Property for: $($User.UserPrincipalName)" -f Yellow
#Get the User Property value from Azure AD
$ADUserPropertyValue = $User | Select -ExpandProperty $ADPropertyName
#Check if the AD Property is not Null
If (!([string]::IsNullOrEmpty($ADUserPropertyValue)))
{
#Get existing User Profile Property from SharePoint
$UserAccount = "i:0#.f|membership|$($User.UserPrincipalName)"
$UserProfile = Get-PnPUserProfileProperty -Account $UserAccount
$UserProfileProperty = $UserProfile.UserProfileProperties[$SPOPropertyName]
#Check if the Existing SharePoint User Profile Property is Null
If (([string]::IsNullOrEmpty($UserProfileProperty)))
{
Set-PnPUserProfileProperty -Account $UserAccount -PropertyName $SPOPropertyName -Value $ADUserPropertyValue
Write-host "`tUpdated User Profile Property for: $($User.UserPrincipalName)" -f Green
}
Else
{
Write-host "`t Existing Value of the Property in SharePoint is Not Null! Skipping..." -f Yellow
}
}
else
{
Write-host "`t AD Value of the Property is Null! Skipping..." -f Yellow
}
$Counter++
Write-Progress -Activity "Updating User Profile Data..." -Status "Updating User Profile $Counter of $($AllUsers.Count)" -PercentComplete (($Counter / $AllUsers.Count) * 100)
}
}
Catch {
write-host -f Red "Error Updating User Profile Property!" $_.Exception.Message
}
Default user profile property mappings in SharePoint Online
Here are the user profile properties mapped and synched to SharePoint Online from Azure AD.
SharePoint Online User profile property | Azure Active Directory attribute |
---|---|
AccountName | msonline-UserPrincipalName |
ADGuid | ObjectGuid |
Department | Department |
FirstName | GivenName |
GroupType | GroupType |
IsPublic | msOnline-IsPublic |
IsUnifiedGroup | msonline-groupType |
LastName | sn |
Manager | Manager |
msOnline-ObjectId | msOnline-ObjectId |
msOnline-ObjectId | msOnline-ObjectId |
Office | PhysicalDeliveryOfficeName |
PreferredName | DisplayName |
PublicSiteRedirect | WWWHomePage |
SPO-IsSPO | SPO-IsSharePointOnlineObject |
SPS-ClaimID | msonline-UserPrincipalName |
SPS-Department | Department |
SPS-DistinguishedName | DistinguishedName |
SPS-HideFromAddressLists | msExchHideFromAddressList |
SPS-JobTitle | Title |
SPS-MUILanguages | PreferredLanguage |
SPS-RecipientTypeDetails | msExchRecipientTypeDetails |
SPS-SavedSID | ObjectSid |
SPS-SIPAddress | proxyAddresses |
SPS-UserPrincipalName | msonline-UserPrincipalName |
SPS-UserType | msOnline-UserType |
Title | Title |
UserName | msonline-UserPrincipalName |
WorkEmail | proxyAddresses |
WorkPhone | telephoneNumber |
Please note, This property update is only for SharePoint Online. It can’t be synced to Office 365 or Azure AD. User profile property created in the SharePoint Online admin center will not create or sync that property in Office 365! We also have an API to bulk update user profile properties Bulk update custom user profile properties for SharePoint Online
I’m having an issue with line 29 of the second script; when storing the value of the expanded property in the variable it always comeback that it doesn’t exist, whatever the property I try to select ;
$ADUserPropertyValue = $User | Select -ExpandProperty $ADPropertyName
Anyone having the same problem?
I am getting error while doing it for all users – Set-PnPUserProfileProperty : This operation requires you to be managing your own data or have administrator privileges. I am sharepoint administrator already
I’m also having the same
There is a bug for Set-PnPUserProfileProperty, see the following : https://github.com/pnp/powershell/issues/277
No ETA yet as to when it will be fixed. You can loging using the -AppId and -AppSecret instead to bypass this
Appid and appsecret are no longer an option for connect-pnponline.
generally -interactive seems to fix most problems so I updated my script testing for just one user and i’m still getting the permission error despite interactive login using Global Admin account to login.
I need to change a number of mappings any idea how to get around the permissions issue?
After digging through the Github a bit I was able to make this script work by changing the connect-pnplogin to the following;
Connect-PnPOnline -S -Url $AdminSiteURL -Credentials $cred
I believe the -S flag being the most critical. Weird because most times if i’m not using -interactive now the pnp modules fail but at least this works!
Running this as a global admin and sharepoint admin and receive the following;
Set-PnPUserProfileProperty : Access denied. You do not have permission to perform this action or access this resource.
Any ideas why this would be the case?
Salaudeen, I tried the first script and ran into a few problems. First, it looks like it needs t be “mobile” and not “MobilePhone”. I made that change and got a bit further but then I get an error “Error Synching User Profile Property! Exception calling “.ctor” with “2” argument(s): “The ‘username’ argument cannot be null.
Parameter name: username”. I am NOT a wiz with Powershell or any of the rest of this. Can you point me in right direction?
Thanks Salaudeen, Good article. I’m hoping this has moved me forward very quickly on a bit of project work, with the introduction of a few improvements to allow for script #2 to update multiple properties per user account.
Can I use this script to sync “Country or Region” from Azure AD to SharePoint user profile property? Just change these values?
$ADPropertyName = “Country”
$SPOPropertyName = “Country”
second question. I assumed I have to create a custom managed property in SharePoint called “Country”?
Yes, You can create a custom user profile property and then use the above script to sync it from Azure AD. How to create user profile property in SharePoint Online?
Script works great for all users until it ran into an error on a user that doesn’t have user profile. The script stop after it. How do I modify the script to ignore the error and continue to the next user?
error”Error Updating User Profile Property! Cannot index into a null array.”
Are you using the First script? The Second only already checks for null!
Hi,
Can a custom property in On-Premise AD be synced to Azure AD and then synced to a Custom User profile property in SPO, using this approach? Or does it only work for standard properties of AD?
Yes! It works for any Azure AD Properties, Including Custom user profile properties from AD!
Great post Salaudeen!
So to utilise extended fields from AD/AAD, would this mean it’s just a case of defining the variables for the customer fields? and then a foreach for each of the custom values?
$ADPropertyName = “MyCustomValue”
$SPOPropertyName = “MyCustomValue”
Yes, That’s right! Also make sure your extended property is mapped from AD to AAD in AD Sync tool.
Hi, Does it work for a custom property in On-Premise AD which is synced to Azure AD ?
In another words, If we create a custom user profile property in User profile application within SPO, with the above script can we sync any corresponding custom attribute from Local Ad to Azure AD to the Custom User Profile property?