--- name: entra-group-member-reads description: az ad group member list and Graph /members silently omit service principal members — use the servicePrincipal cast or transitiveMemberOf when a group is expected to hold an SPN. metadata: node_type: memory type: reference --- `az ad group member list --group ` and `GET /groups/{id}/members` both return an **empty collection**, with no error, for a group whose only members are service principals — at least when called with Lyra's user account. The read looks authoritative and is not. **Reliable reads instead:** ```sh # members, cast to the type that is being hidden az rest --method get --url "https://graph.microsoft.com/v1.0/groups//members/microsoft.graph.servicePrincipal?\$select=id,displayName" # count, which does not filter az rest --method get --url "https://graph.microsoft.com/v1.0/groups//members/\$count" --headers ConsistencyLevel=eventual # from the principal's side az rest --method get --url "https://graph.microsoft.com/v1.0/servicePrincipals//transitiveMemberOf?\$select=id,displayName" az rest --method post --url "https://graph.microsoft.com/v1.0/servicePrincipals//checkMemberGroups" \ --body '{"groupIds":[""]}' --headers "Content-Type=application/json" ``` **How to apply:** any group that deployment or automation identities belong to — `*-cluster-admins`, `*-keyvault`, anything created by `rg-prereqs` — must be checked with one of the above before concluding it is empty. Cross-check against Terraform: a plan reporting "No changes" against a `members` attribute is strong evidence the membership is present, and outranks the `az` read. On 2026-08-28 the plain read produced a Bug (WSP-33432, cancelled) claiming five `*-cluster-admins` groups across three tenants had been emptied; all five held their deployment principals the whole time. Related: [[wsp-32957-pim-migration]].