---
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 <id>` 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/<gid>/members/microsoft.graph.servicePrincipal?\$select=id,displayName"

# count, which does not filter
az rest --method get --url "https://graph.microsoft.com/v1.0/groups/<gid>/members/\$count" --headers ConsistencyLevel=eventual

# from the principal's side
az rest --method get --url "https://graph.microsoft.com/v1.0/servicePrincipals/<spid>/transitiveMemberOf?\$select=id,displayName"
az rest --method post --url "https://graph.microsoft.com/v1.0/servicePrincipals/<spid>/checkMemberGroups" \
  --body '{"groupIds":["<gid>"]}' --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]].
