Graph PowerShell remove member from group

Continuing my Graph/ PowerShell journey…

Now I want to remove users from an Azure AD group. And turns out there’s no cmdlet in the Microsoft.Graph module for that. Bummer, eh!

No worries, one of the cooler cmdlets in that module is Invoke-MgGraphRequest which as you probably guessed makes calls to the Graph API. Why not just use Invoke-RestMethod you might ask? Well, you could… but this one takes care of the authentication etc. You are already connected via Connect-MgGraph so why bother now getting access tokens etc. via Invoke-RestMethod and then passing that in the header to another Invoke-RestMethod and so on…? It’s a small convenience, sure…

Anyways, removing members is discussed in this API document. You have to send a DELETE request to /groups/{id}/members/{id}/$ref. No big deal, first I made a loop along these lines:

I have the group Id in $GroupObj.Id from an earlier part of the code, and I get the user Id from Get-MgUser. I am intentionally skipping the $ref part as I can’t put that in PowerShell because it will get interepreted as a variable. I was expecting some error due to this but I got an access denied and that threw me off:

At this point I should have just tried tacking on a $ref and seeing if that works, but I stupidly didn’t. I thought maybe I had missed some permissions to the application so went down that track.

To ensure there’s no bug in the cmdlet I decided to try another way. I could have used Invoke-RestMethod instead I went with PostMan. I’ve been slowly building up a collection of queries in PostMan as it’s just easier there.

For instance, I have the following collections for various things I am trying out (SharePoint Online, Group Sync). In these collections I have the queries I want to try out. You can see for instance I have 4 queries in the Group Sync collection.

The nice thing with PostMan is that I can define variables, and put those into separate environments. Thus for instance, notice my query above to get an access token doesn’t have the tenant Id or app Id anywhere… all these are stored as variables. I can have an environment for my test tenant (for instance) where the tenantId variable points to that; so when I want to send a query to that tenant I merely switch environments. Or I could have separate environments for each of my app Ids – for instance my SharePoint work and Groups work have separate app registrations; so I have separate environments with the app Ids and secrets for these.

When I run the above query and get an access token, I can right click that and store it as a variable. Then in subsequent queries I can send that variable as the authorization token. So cool! :)

Anyways, if I were to run the DELETE request using PostMan, with the same app registration, it fails with the same error.

But at least with PostMan I can tack on $reg (as it is not a variable in PostMan) and when I do that the query succeeds.

Nice! So the $ref was the issue.

Thus I modified the loop above and now it works: