Table of Contents
Use SDK Cmdlets to Add Properties to the Microsoft 365 User Profile Card
The Microsoft 365 profile card displays information about users. The information show in a profile card comes from the user’s Entra ID account. By default, Microsoft 365 limits the properties shown by the profile card to the set that they consider to be most important. Organizations can customize the Contact tab of the profile card to reveal some of the properties that are not shown by default. However, not every property of an Entra ID user account is available for the profile card. Some, like the employee hire date, are not supported.
In 2020, I wrote about how to customize the profile card. At that time, the profile card API was in beta. The production Graph endpoint now supports the profile card API, and it’s also supported by cmdlets in the Microsoft Graph PowerShell SDK. I used version 2.9 of the SDK for this article.
The Microsoft documentation for customizing the profile card is a little outdated. At the time of writing, it uses V1.0 of the SDK and is based on the beta API. Because the API is now in production, it follows that the latest SDK cmdlets use that API. In any case, the instructions contained in the documentation are a reasonable guide.
Customized User Profile Card Available to All
The most important point about customizing the profile card is that any change is exposed to all users. You cannot customize the profile card for a subset of the user population such as a targeted administrative unit. This fact creates difficulties in multinational organizations where local privacy regulations might prevent the display of certain information held in user account properties.
As already mentioned, only certain user account properties are available for customization. Basically, you can add six standard properties:
- UserPrincipalName.
- Fax.
- StreetAddress.
- PostalCode.
- StateOrProvince.
- Alias.
Of course, including these properties in the profile card is useless unless information is populated in the directory for all user accounts. That often doesn’t happen.
The the fifteen custom attributes inherited from Exchange Server (different to the custom security attributes that can be defined for Entra ID) are also supported. Many organizations use these attributes to store information about users such as personnel numbers, cost centers, employee type, employee job codes, seniority level, and even the date of last promotion. Dynamic distribution lists and dynamic Microsoft 365 groups.
Add an Attribute to the Profile Card
To add one of the six standard or fifteen custom attributes to the profile card, construct a payload in a PowerShell hash table. The table contains the property name and its display name (annotation). Then run the New-MgAdminPeopleProfileCardProperty cmdlet passing the hash table as the body parameter (the same as passing a request body to a Graph request). This command adds CustomAttribute15 and tells Microsoft 365 that the user profile card should refer to the property as the “Employee Type.”
Connect-MgGraph -Scopes "PeopleSettings.ReadWrite.All","PeopleSettings.Read.All" -NoWelcome $AddPropertyDetails = @{ directoryPropertyName = "CustomAttribute15" annotations = @( @{ displayName = "Employee Type" } ) } $AddPropertyDetails Name Value ---- ----- directoryPropertyName CustomAttribute15 annotations {Employee Type} New-MgAdminPeopleProfileCardProperty -BodyParameter $AddPropertyDetails Id DirectoryPropertyName -- --------------------- CustomAttribute15
It takes at least 24 hours before the profile card picks up customized properties. When they do, they appear on the Contact tab of the profile card. Figure 1 shows three custom properties for cost center, preferred drink (a historic part of the Active Directory schema), and employee type. If a custom properties doesn’t contain any information for a user, it won’t appear on the profile card.
To check the set of attributes added to the profile card with PowerShell, run the Get-MgAdminPeopleProfileCardProperty cmdlet. This output tells us that the profile card is configured to display three optional properties and three custom properties:
Get-MgAdminPeopleProfileCardProperty Id DirectoryPropertyName -- --------------------- userPrincipalName customAttribute12 StreetAddress Postalcode CustomAttribute9 CustomAttribute15
If you make a mistake, you can remove a property from the profile card by running the Remove-MgAdminPeopleProfileCardProperty cmdlet. For example, this command removes the Drink attribute (stored in CustomAttribute9) from the profile card:
Remove-MgAdminPeopleProfileCardProperty -ProfileCardPropertyId CustomAttribute9
Note that the profile card property id parameter is case sensitive. You must pass the property name as returned by the Get–MgAdminPeopleProfileCardProperty cmdlet.
Adding a Translated Label for a Custom Profile Card Property
The documentation makes a big thing about defining a language-specific value for a custom property. This is done using the Update-MgAdminPeopleProfileCardProperty cmdlet. This example shows how to add a French language label for CustomAtrribute15:
$LocalizationHash = @{} $LocalizationHash.Add("languagetag","fr-FR") $LocalizationHash.Add("displayName","Type d’employé") $UpdatePropertyDetails = @{ annotations = @( @{ displayName = "Cost Center" localizations = @( $LocalizationHash ) } ) } Update-MgAdminPeopleProfileCardProperty -ProfileCardPropertyId 'customAttribute15' -BodyParameter $UpdatePropertyDetails
This command works, but it only works for a single language. If you want to have labels for multiple languages, you’ll be sadly disappointed because Update-MgAdminPeopleProfileCardProperty (and its Graph API counterpart) overwrite the language configuration each time.
You could argue that this is disappointing for multinational organizations that want to have fully-translated interfaces for all languages in use. Being restricted to a single language alternative is a strange approach to localization, especially for a company that does so much to deliver local language translations for user interfaces. The counterargument is that the properties chosen for display in the profile cards are likely to be well understood by anyone in an organization.
Work Still to Do
Not much has changed in customizing the profile card since 2020. The API is now production rather than beta and the Graph SDK supports the action, but that’s it. Coverage for multiple local language labels would be nice but that’s still elusive.
Support the work of the Office 365 for IT Pros team by subscribing to the Office 365 for IT Pros eBook. Your support pays for the time we need to track, analyze, and document the changing world of Microsoft 365 and Office 365.
Thanks for this post. This would be helpful to us to surface some attributes on the profile card.
I’m trying it and get an error when I try the final step. Any thoughts on what is causing this?
New-MgAdminPeopleProfileCardProperty : The ‘New-MgAdminPeopleProfileCardProperty’ command was found in the module ‘Microsoft.Graph.Identity.DirectoryManagement’, but the module could not be loaded. For more information, run
‘Import-Module Microsoft.Graph.Identity.DirectoryManagement’.
At C:\Users\tandy\Farmers Alliance\M365 Admin & Governance – PowerShellScripts\Update-User-Profile-Cards.ps1:24 char:1
+ New-MgAdminPeopleProfileCardProperty -BodyParameter $AddPropertyDetai …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (New-MgAdminPeopleProfileCardProperty:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CouldNotAutoloadMatchingModule
What version of the SDK are you using? The latest is V2.9 and that’s the one I use.
I believe I am at version 2.9.0. That’s what I see for the version when I use get-module for microsoft.graph.identity.directorymanagement. I did load az.accounts and connect and now I get a different error.
+ New-MgAdminPeopleProfileCardProperty -BodyParameter $AddPropertyDetai …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-MgAdminPeop…Property_Create], AggregateException
+ FullyQualifiedErrorId : System.AggregateException,Microsoft.Graph.PowerShell.Cmdlets.NewMgAdminPeopleProfileCardProperty_Create
Permissions? “PeopleSettings.ReadWrite.All”,”PeopleSettings.Read.All”
I’m a global admin and using Powershell with my admin credentials. At some point while working on this I got a “Permissions requested” pop up that said “This app would like to: read and write tenant-wide people settings, Read tenant-wide people settings, View users’basic profile, maintain access to data you have given it access to. I selected “Consent on behalf of your organization.” So I should have permissions.
Run (Get-MgContext).Scopes just to make sure. Being a global admin doesn’t mean that the process has permissions to update the people card settings.
Yes, the scope says: Scopes : {ChannelSettings.Read.All, Directory.Read.All, openid, PeopleSettings.Read.All…}
But in looking at versions of modules, I had both the 2.9.0 and an older version of the Microsoft.Graph.Authentication. I had to force uninstall that version and restart powershell, and now I’ve run the command without an error. So “fingers-crossed,” I might have updated the profile cards.
Thanks so much Tony for your quick responses and attention to detail. I appreciate it!
It´s sad not more attributes are supported, like employeeid.
Great article as always Tony!
I’m running into an issue with running the commands.
I’m running PS Graph SDK v2.11.1. I’ve tried in WPS (5.1) and PSC (7.4).
I’m a GA with a PIM’d role and have admin and user consent.
Scope was set to “Connect-MgGraph -Scopes “PeopleSettings.ReadWrite.All”,”PeopleSettings.Read.All” -NoWelcome”
Double checked with “(Get-MgContext).Scopes”and scopes are listed and presented, but I’m hitting a
Remove-MgAdminPeopleProfileCardProperty
Status: 403 (Forbidden)
UnknownError,Microsoft.Graph.PowerShell.Cmdlets.RemoveMgAdminPeopleProfileCardProperty_Delete
The documentation says that PeopleSettings.ReadWrite.All is all that’s needed as does the Graph documentation. Have you tried using a Graph request rather than the cmdlet (just in case).
Found the answer đź‘Ť. It was GA permission consent in one of our tenants that wasn’t in the correct state. Thanks for taking the time to reply.