Forum Discussion
Bulk Update SharePoint Online User Profile Properties with Extension Attributes in Azure AD
I have been using the following script to bulk update custom SharePoint Online User Profile Properties with Azure AD attributes that aren't mapped to SharePoint by default (Azure AD gets information from our on-premises AD via Azure AD Connect). It iterates through each Azure AD user, captures their attributes, then uses Connect-PnPOnline to bulk update SharePoint with a JSON file that has extracted specified Azure attributes.
This works great for standard Azure AD attributes such as Mobile or Department, but I cannot get this to work with Extension Properties (on-premises AD attributes that are synced to Azure AD as Directory Extensions in Azure AD Connect, in this case the IP Phone and Notes fields in AD).
#Function to Extract User profile Extension Property
Function Extract-ADUserProperties
{
Param ([Parameter(Mandatory=$true)][string[]]$ADProperties, [Parameter(Mandatory=$true)][PSCredential]$Cred)
Try {
#Connect to AzureAD
Connect-AzureAD -Credential $Cred | Out-Null
#Get All Users from AzureAD
$AllUsers = Get-AzureADUser -All:$True
Write-host "Total Number of User Profiles Found:"$AllUsers.Count
$UserProfileDataColl = @()
#Iterate through All User profiles
$Counter = 1
ForEach($User in $AllUsers)
{
$UserProfileData = New-Object PSObject
$UserProfileData | Add-Member NoteProperty IDName($User.UserPrincipalName)
#Get Value of each property of the user
ForEach($ADProperty in $ADProperties)
{
#Get User Profile Property value
$ADPropertyValue = $User | Select -ExpandProperty ExtensionProperty $ADProperty
If(!$ADPropertyValue) {$ADPropertyValue = [string]::Empty}
$UserProfileData | Add-Member NoteProperty $ADProperty($ADPropertyValue)
}
$UserProfileDataColl += $UserProfileData
Write-Progress -Activity "Getting User Profile Data..." -Status "Getting User Profile $Counter of $($AllUsers.Count)" -PercentComplete (($Counter / $AllUsers.Count) * 100)
$Counter++
}
#Convert data to required Json format
$JsonData = $UserProfileDataColl | ConvertTo-Json
$JSON = @"
{ "value":
$JsonData
}
"@
#Export JSON to a File
$JSON | Out-File -FilePath $Env:TEMP/UserProfileData.JSON -Force
Write-host "Extracted user profile Properties Successfully!" -f Green
}
Catch {
write-host -f Red "Error Getting User Profile Properties!" $_.Exception.Message
}
}
#Call the function to Extract User profile data to JSON
Extract-ADUserProperties -ADProperties @("extension_cc64416229824d08b7a6db3c5ea9b847_ipPhone", "extension_cc64416229824d08b7a6db3c5ea9b847_info") -Cred (Get-Credential)
#Parameters
$SiteUrl = "https://tenant.sharepoint.com"
$SiteRelativeFolderPath = "/Shared Documents"
#Connect to site
Connect-PnPOnline $SiteUrl -Credentials (Get-Credential)
#Call the Bulk Import Job - Mapping in format AzureAD User Attribute = SharePoint User Profile Property
New-PnPUPABulkImportJob -Folder $SiteRelativeFolderPath -Path $Env:TEMP/UserProfileData.JSON -IdProperty "IdName" -UserProfilePropertyMapping @{"extension_cc64416229824d08b7a6db3c5ea9b847_ipPhone"="ipPhone";"extension_cc64416229824d08b7a6db3c5ea9b847_info"="info"}
With standard Azure AD attributes like "Country" and "Mobile", I get a nice clean JSON file like this:
But when I try to use Extension Attributes, which are all contained within the "ExtensionProperty" Azure AD attribute, I get the following:
When what I'm really wanting is to be pulling just the two extension attributes, which would ideally result in a JSON file like this:
Any ideas on how to modify the script to achieve this behavior? I'm thinking that the following probably needs to be used, but I'm not sure how best to incorporate this into the script.
4 Replies
- mrmarquesCopper Contributor
Not sure if the reply is too late, but we had a similar solution where we needed to update some properties that are not synced by default.
We were using Graph API to get all the users from Azure AD and then sync with SharePoint User Profile entries by submitting a JSON file to UPS import job.
In brief we followed the steps:
- Get data from Graph API (with deltas, getting only the updated identities from last sync)- Create a JSON with all users with new values (User Profile properties vs new values from Azure AD)
- Store JSON file in a document library
- Submit the JSON to UPS by using what is explained here - https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/bulk-user-profile-update-api-for-sharepoint-onlineThe user profile properties that will be updated by the process needs to configured in UPS as non editable by the users (for some specific properties we created new properties in UPS)
- willmxCopper ContributorJust curious. Can you share how you get data from Graph APU with deltas only?
- zegCopper Contributor
willmx
You could use the following script and keep your last DeltaLink somewhere to check changes on the next run.You might need to add some loop if your users are updated frequently
$nextLink = 'https://graph.microsoft.com/v1.0/users/delta?$select=<property1 that you need to checck>,<property2 that you need to checck>,etc.' #Run this the first time once /start while (![string]::IsNullOrEmpty($nextLink)) { $res = Invoke-GraphRequest -Uri $nextLink $nextLink = $res.('@odata.nextLink') } $deltaLink = $res.('@odata.deltaLink') Keep your $deltaLink somewhere and #Run this the first time once /end repeat the follwoing ##################################### $res = Invoke-GraphRequest -Uri $deltaLink $deltaLink = $res.('@odata.deltaLink') Check $res.Values for changes Keep your $deltaLink somewhere #####################################
- Varun_GhildiyalIron ContributorHave you landed upon any solution .
There is too much data to process here, could you please share your requirement summary in short .
I know this reply is late , but just want to check if you are still stuck with this