Entra / Microsoft 365 · Users & guests
Migrate user profile card settings
Migrate custom properties on the Microsoft 365 user profile card to standard Entra ID attributes such as EmployeeId and CostCenter.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-MgGraph -NoWelcome
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
Connect-MgGraph -NoWelcome# Check that we have the right permissions - in Azure Automation, we assume that the automation account has the right permissionsIf ($Interactive) {[string[]]$CurrentScopes = (Get-MgContext).Scopes[string[]]$RequiredScopes = @('PeopleSettings.ReadWrite.All', 'User.ReadWrite.All')$CheckScopes =[object[]][Linq.Enumerable]::Intersect($RequiredScopes,$CurrentScopes)If ($CheckScopes.Count -ne 2) {Write-Host ("To run this script, you need to connect to Microsoft Graph with the following scopes: {0}" -f $RequiredScopes) -ForegroundColor RedDisconnect-GraphBreak}}# Get licensed member accounts for the tenant, excluding utility accounts[array]$Users = Get-MgUser -All -PageSize 500 -Filter "usertype eq 'member' and accountenabled eq true and employeeType ne 'Utility' and assignedLicenses/`$count ne 0" `-Sort displayName -ConsistencyLevel Eventual -CountVariable Count `-Property DisplayName, UserPrincipalName, id, employeeType, userType, employeeOrgData, accountEnabled, employeeId, OnPremisesExtensionAttributes, departmentWrite-Host ("Found {0} licensed member accounts to process" -f $Users.Count) -ForegroundColor Green$Report = [System.Collections.Generic.List[Object]]::new()[int]$i = 0ForEach ($User in $Users) {$i++Write-Host ("Processing user {0} of {1}: {2}" -f $i, $Count, $User.DisplayName) -ForegroundColor Yellow# Fetch the data from the on-premises extension attributes$CostCenter = $User.onpremisesExtensionAttributes.extensionAttribute15$EmployeeId = $User.onpremisesExtensionAttributes.extensionAttribute12$EmployeeType = $User.onpremisesExtensionAttributes.extensionAttribute11$Division = $User.department# Set some default values if values are missing in the custom attributesIf ($null -eq $CostCenter) { $CostCenter = "Not defined" }If ($null -eq $EmployeeId) { $EmployeeId = "000000" }If ($null -eq $EmployeeType) { $EmployeeType = "Permanent" }If ($null -eq $Division) { $Division = "HQ" }$Parameters = @{employeeOrgData = @{"costCenter" = $CostCenter"division" = $Division}EmployeeId = $EmployeeIdEmployeeType = $EmployeeType}Try {Update-MgUser -UserId $User.Id -BodyParameter $Parameters -ErrorAction Stop$DataLine = [PSCustomObject][ordered]@{User = $User.displayNameUserPrincipalName = $User.UserPrincipalNameEmployeeId = $EmployeeIdEmployeeType = $EmployeeTypeCostCenter = $CostCenterDivision = $Division}$Report.Add($DataLine)} Catch {Write-Host ("Failed to update user {0}: {1}" -f $User.DisplayName, $_.Exception.Message) -ForegroundColor Red}}# Now remove the old custom attributesWrite-Host "Removing old custom attributes from profile card" -ForegroundColor GreenRemove-MgAdminPeopleProfileCardProperty -ProfileCardPropertyId CustomAttribute11Remove-MgAdminPeopleProfileCardProperty -ProfileCardPropertyId CustomAttribute12Remove-MgAdminPeopleProfileCardProperty -ProfileCardPropertyId CustomAttribute15$Report | Export-Csv -Path ".\UserProfileCardMigrationReport.csv" -NoTypeInformation -Encoding UTF8$Report | Out-GridView -Title "User Profile Card Migration Report"
Attribution
Author
Office365itpros