In practice, that means setting:
securityEnabled = true(security principal required for role assignment scenarios)- and (typically)
isAssignableToRole = trueif you want to assign Microsoft Entra directory roles to the group (a “role-assignable group”).
This post explains why securityEnabled matters, then provides a complete PowerShell script using the Microsoft Graph PowerShell SDK (Graph API under the hood) to:
- Create the Entra ID group
- Assign an Entra role to that group
Why securityEnabled = true matters (and why you usually also need isAssignableToRole = true)
Microsoft Entra directory roles (for example, User Administrator, Groups Administrator, etc.) are assigned to security principals. If you create a group that is not security-enabled, you can’t use it as the target for directory role assignment in the intended way.
Microsoft’s own role assignment tutorial for Entra role management shows creating a role-assignable security group with securityEnabled: true and isAssignableToRole: true as the starting point.
Key takeaway:
If you want your automation to go from “create group” → “assign Entra role,” create the group as a security group (securityEnabled = true) and, for directory roles assigned to groups, make it role-assignable (isAssignableToRole = true).
Graph API building blocks you’re automating
- Create group:
POST <https://graph.microsoft.com/v1.0/groups> - Create role assignment:
POST /roleManagement/directory/roleAssignments(unifiedRoleAssignment)
Permissions depend on your approach (delegated vs app-only), but Microsoft’s tutorial calls out Group.ReadWrite.All to create the group and RoleManagement.ReadWrite.Directory for role-related operations.
(Also note: for creating role assignments, Microsoft documents that Privileged Role Administrator is the least privileged built-in role for the operation in delegated scenarios. )
Full PowerShell script: Create Entra ID group + assign Entra role
This script uses the Microsoft Graph PowerShell SDK. It creates a role-assignable security group and assigns a directory role at tenant scope (/). Adjust naming and the role as needed.
<#
Entra ID automation: Create a role-assignable security group and assign an Entra directory role
Requires: Microsoft Graph PowerShell SDK
#>
# ---------------------------
# 0) Prereqs / Install modules
# ---------------------------
# Install-Module Microsoft.Graph -Scope CurrentUser
# (Optional) Keep things lean by importing only what we need:
Import-Module Microsoft.Graph.Groups
Import-Module Microsoft.Graph.Identity.Governance
# ---------------------------
# 1) Connect to Microsoft Graph
# ---------------------------
# Delegated permissions (example):
# - Group.ReadWrite.All
# - RoleManagement.ReadWrite.Directory
# You might also need Directory.Read.All to lookup role definitions depending on your tenant config.
$scopes =@(
"Group.ReadWrite.All",
"RoleManagement.ReadWrite.Directory",
"Directory.Read.All"
)
Connect-MgGraph-Scopes$scopes
# ---------------------------
# 2) Define inputs
# ---------------------------
$groupDisplayName ="PIM-Helpdesk-UserAdmin"
$groupDescription ="Role-assignable security group managed by automation"
$mailNickname = ("pimhelpdesk" + (Get-Random-Maximum9999))
# Choose an Entra directory role by display name
# Examples: "User Administrator", "Groups Administrator", "Privileged Role Administrator"
$roleDisplayName ="User Administrator"
# ---------------------------
# 3) Create a ROLE-ASSIGNABLE SECURITY GROUP
# ---------------------------
# Important for role assignment scenarios:
# - securityEnabled = $true
# - isAssignableToRole = $true
# - mailEnabled = $false
# - groupTypes = @() (no M365 group type)
$params =@{
description =$groupDescription
displayName =$groupDisplayName
mailEnabled =$false
mailNickname =$mailNickname
securityEnabled =$true
isAssignableToRole =$true
}
$group =New-MgGroup-BodyParameter$params
Write-Host"Created group:"$group.DisplayName" ("$group.Id")"
# ---------------------------
# 4) Lookup the role definition ID
# ---------------------------
# Unified role definitions live under roleManagement/directory/roleDefinitions.
# We'll fetch by display name.
$roleDefinition =Get-MgRoleManagementDirectoryRoleDefinition-Filter"displayName eq '$roleDisplayName'"
if (-not$roleDefinition) {
throw"Role definition not found for displayName: $roleDisplayName"
}
Write-Host"Role:"$roleDefinition.DisplayName" ("$roleDefinition.Id")"
# ---------------------------
# 5) Assign the Entra role to the GROUP (tenant-wide scope)
# ---------------------------
# directoryScopeId "/" means tenant-wide directory scope.
$assignmentParams =@{
principalId =$group.Id
roleDefinitionId =$roleDefinition.Id
directoryScopeId ="/"
}
$assignment =New-MgRoleManagementDirectoryRoleAssignment-BodyParameter$assignmentParams
Write-Host"Assigned role to group. Assignment Id:"$assignment.Id
# ---------------------------
# 6) Optional: Output summary
# ---------------------------
[PSCustomObject]@{
GroupDisplayName =$group.DisplayName
GroupId =$group.Id
RoleDisplayName =$roleDefinition.DisplayName
RoleDefinitionId =$roleDefinition.Id
DirectoryScopeId ="/"
RoleAssignmentId =$assignment.Id
}
Why the script is structured this way:
- Group creation uses
POST /groupsand explicitly setssecurityEnabledandisAssignableToRolefor a role-assignable security group. - Role assignment is created as a
unifiedRoleAssignmentvia the role management APIs.
Where this fits operationally (and where it usually falls short)
This is excellent for repeatable provisioning (projects, temporary admin teams, service operations), but most organizations quickly need more than “just scripts,” such as:
- approvals & separation of duties
- time-bound activation (JIT) and automatic expiry
- audit trails and reporting
- hybrid coverage (Entra roles + on-prem AD roles)
That’s exactly the gap Privileged Identity Management is meant to close. Microsoft’s PIM guidance frames it as limiting standing admin access and managing privileged access lifecycle.
au2mator hybrid PIM (Entra ID + on-prem AD)
If you want to extend this approach into a governed workflow—hybrid, time-limited, and auditable—take a look at our solution here: au2mator Privileged Identity Management (PIM)