๐ Recipe ยท Entra ID & Identity
Bulk Assign Custom Security Attributes to Users in Entra ID
Tag users matching an email-domain filter with a Custom Security Attribute value for governance and Conditional Access scoping
Complexity
Intermediate
Impact
identity-governance + bulk-operation + conditional-access + attribute-based-access-control
Context
Why This Matters
Custom Security Attributes (CSAs) in Microsoft Entra ID are key-value pairs you define at the tenant level to classify directory objects (users, service principals, devices). They are commonly used to drive Conditional Access scoping, ABAC on Azure resources, license governance, and HR reporting.
A frequent operational task is the bulk assignment of a CSA value to a cohort of users โ for example, tagging every employee of a specific domain with Accounts > UserType = Employee so they fall under the correct Conditional Access policy or ABAC role assignment. Doing this one user at a time in the Entra portal is tedious and error-prone; this recipe shows the three reliable paths.
Run this recipe whenever you:
- Onboard a new acquired domain and need to tag its users with a classification value.
- Roll out a new CSA set and need to backfill existing users.
- Periodically reconcile the CSA against a source of truth (HRIS, domain, group membership).
Expected Outcomes
What you will have
- Every user matching the target filter (e.g. mail ending in
@contoso.com) carries the specified Custom Security Attribute value. - A reconciliation report showing users that already had the attribute vs. users who were newly assigned.
- An audit trail of
PATCH /beta/users/{id}calls against the directory that can be reviewed in the Entra audit log. - Confidence that Conditional Access policies, ABAC roles, or reports keyed on that attribute correctly scope the tagged cohort.
Risks & Considerations
Warnings & considerations
- Privileged role required. Assigning CSA values is gated by the Attribute Assignment Administrator role (or equivalent custom role) โ Global Admin alone is not sufficient. The operator must be explicitly granted this role before the PATCH calls will succeed.
- Beta endpoint. Custom Security Attribute read/write currently lives on
/beta. The payload shape may evolve when it moves tov1.0. - PATCH is a merge, not a replace. Sending a partial
customSecurityAttributespayload merges into the existing attribute set. To remove a value, sendnullexplicitly. - Predefined values. If the attribute is configured with
usePreDefinedValuesOnly = true, you must use anisActiveallowed value โ free-text will fail. - Advanced queries.
endsWith()requires theConsistencyLevel: eventualheader and$count=true. Without them, the filter returns HTTP 400. - Do NOT run the bulk assignment without first dry-running the filter and reviewing the user list. A typo in the domain filter can easily tag the wrong cohort.
- Compliance. CSAs may contain data subject to internal governance (e.g. employment classification). Confirm who can read the attribute set before populating it โ visibility is governed by attribute-set-level permissions.
Required Permissions
| Permission | Why It's Needed |
|---|---|
| CustomSecAttributeDefinition.Read.All | Read the CSA definitions and allowed values to validate the attribute name and target value before assignment. |
| CustomSecAttributeAssignment.ReadWrite.All | Read and write Custom Security Attribute values on user objects. |
| User.Read.All | Query users by mail filter to build the target cohort. |
| Attribute Assignment Administrator (directory role) | Azure role required in addition to Graph scopes โ the signed-in principal must hold this role to persist CSA writes. |
The fastest way to get this done: just ask Dex. Copy the prompt below and paste it into your Dex conversation.
For IT Admins
Paste into Dex Pro
Assign a CSA value to users via the Entra admin center
Use this path for small cohorts (<20 users) or as a one-off verification after a scripted run.
Step 1 โ Confirm the attribute definition
- Sign in to the at
https://entra.microsoft.comas an Attribute Definition Reader (or higher). - Navigate to .
- Open the attribute set (e.g.
Accounts) and verify the target attribute (e.g.UserType) exists and the desired value (e.g.Employee) is listed as an active allowed value.
Step 2 โ Build the user cohort
- Navigate to .
- Click Add filter, choose User principal name or Email, and enter the matching fragment (e.g.
@contoso.com). - Export the filtered list via Download users so you have a record of who was in scope.
Step 3 โ Assign the attribute per user
- Click a user in the filtered list to open their profile.
- Select the Custom security attributes tab.
- Click Add assignment.
- Choose the Attribute set (e.g.
Accounts), the Attribute name (e.g.UserType), and the Value (e.g.Employee). - Click Save.
- Repeat for each user in the cohort.
Step 4 โ Verify
- Return to and click Columns โ add Custom security attributes.
- Confirm all targeted users now display the expected attribute value.
For more than a handful of users, use the Graph API or PowerShell paths below โ the GUI does not offer bulk selection for CSA assignment.
Bulk assignment via Microsoft Graph
The Graph approach is idempotent and auditable. All CSA operations live on the /beta endpoint.
1. List attribute definitions (validate target)
GET https://graph.microsoft.com/beta/directory/customSecurityAttributeDefinitionsResponse (abbreviated):
{
"value": [
{
"id": "Accounts_UserType",
"attributeSet": "Accounts",
"name": "UserType",
"type": "String",
"status": "Available",
"usePreDefinedValuesOnly": true
}
]
}2. List allowed values for the attribute
GET https://graph.microsoft.com/beta/directory/customSecurityAttributeDefinitions/Accounts_UserType/allowedValuesConfirm the target value (e.g. Employee) is present with isActive: true.
3. Query target users (advanced query)
GET https://graph.microsoft.com/v1.0/users?$filter=endsWith(mail,'@contoso.com')&$select=id,displayName,mail,customSecurityAttributes&$count=true
ConsistencyLevel: eventual// The ConsistencyLevel: eventual header and $count=true are REQUIRED for endsWith()
4. PATCH each user to assign the attribute
PATCH https://graph.microsoft.com/beta/users/{user-id}
Content-Type: application/json
{
"customSecurityAttributes": {
"Accounts": {
"@odata.type": "#microsoft.graph.customSecurityAttributeValue",
"UserType": "Employee"
}
}
}Expected response: HTTP 204 No Content.
5. Verify
GET https://graph.microsoft.com/v1.0/users/{user-id}?$select=displayName,customSecurityAttributesNotes
- Graph does not support
$filteroncustomSecurityAttributes. Pull all candidates and filter client-side. - PATCH merges at the attribute-set level. Sending
UserType: nullclears just that attribute; sendingAccounts: nullclears the entire set. - Batch up to 20 PATCH calls per
$batchrequest to reduce round-trips.
PowerShell using Microsoft.Graph SDK
The provided PowerShell script automates the full workflow: authenticate, validate the attribute definition, enumerate the target cohort, skip users already tagged, and assign the CSA to the rest with a per-user success/failure report.
Prerequisites
- PowerShell 7+
Microsoft.Graphmodule installed (Install-Module Microsoft.Graph -Scope CurrentUser)- The signed-in admin must hold the Attribute Assignment Administrator directory role
Usage
# Dry run โ show what would change without writing
.\Assign-CustomSecurityAttribute.ps1 -MailSuffix '@contoso.com' -AttributeSet 'Accounts' -AttributeName 'UserType' -Value 'Employee' -WhatIf
# Live run
.\Assign-CustomSecurityAttribute.ps1 -MailSuffix '@contoso.com' -AttributeSet 'Accounts' -AttributeName 'UserType' -Value 'Employee'What the script does
- Connects to Graph with the minimum scopes required (
User.Read.All,CustomSecAttributeDefinition.Read.All,CustomSecAttributeAssignment.ReadWrite.All). - Reads the attribute definition and validates
usePreDefinedValuesOnlyโ if true, confirms the supplied-Valueis an active allowed value. - Queries all users matching
endsWith(mail, $MailSuffix)with the correctConsistencyLevelheader. - Splits the cohort into already-has and needs-assignment.
- Sends a PATCH per user, collects outcomes, and writes a CSV report.
- Honors
-WhatIfto preview changes.
Next steps