Graph search/ filters

Trying to filter our some Azure AD groups and instead of taking it easy and using the AzureAD module I decided to use the new Microsoft.Graph module instead. This is the future so I might as well take some pain now and write my newer scripts with this module rather than having to rewrite them all later (rewriting them later might be easier too as there’d be more blog posts etc. to show the way).

There isn’t much info in terms of using this module as it is relatively new. You can install it following the steps in this doc. The good thing about this module (and probably the more important reason for me to use it) is that it works on PowerShell Core so that means I can easily code and test on PowerShell macOS. No need to keep switching to Windows, yay!

The Getting Started guide has instructions on how to authenticate. This basically creates an app registration behind the scenes with delegated rights (same deal as if you were to use Graph Explorer). I will be using this from an automated account so I went with app-only authentication as mentioned in this doc (basically you create an app registration, give it the required permissions but at an “application” level – for which a Global Admin or Privileged Role Admin has to admin consent – and then you can create a self-signed cert and use that to authenticate).

All this is the easy bit! :) I wanted to use the Get-MgGroup cmdlet to get a single group and spent a long time trying to figure out the search syntax. This cmdlet has a -Filter parameter of which there’s no information (same for the -Search parameter). Turns out we have to look to the Graph API docs for this as it just uses the same syntax.

For filter there’s this doc. And for search there’s this. Am not sure what’s the difference between these two. I think search is more context aware? As in you can use it to search across things like subject, bcc, etc. in an email for instance… while filter is not? Not sure to be honest as I haven’t really tried using either of them that much. They also have different syntax too, just to keep things confusing for a beginner…

In addition it is best to also refer to the API docs of the particular API you are looking at in relation to filter or search coz not everything is supported by all APIs. Thus for instance, since I am dealing with Groups I have this page open: It has some examples but they didn’t help me.

I wanted a way of using Get-MgGroup to get a single group. Easy. The filter page has the following:

Hmm, that seems straightforward. Oh, and you can always test these in Graph Explorer so that’s a good place to try things before using the cmdlet (just to avoid any quirks related to the cmdlets being new).

You’d think based on the example there that if I can do filter=startsWith(displayName,'J') then I can do something like filter=eq(displayName,'GroupIAmInterestedIn'). Right? Looks about right… but nope, you can’t!

Why not? I dunno. 🤷‍♂️

Can I combine filters? Not sure, but upon a whim I tried adding an &. Thus I have the following:$filter=startsWith(displayName,'Budget')&endsWith(displayName,'Budget'). Whoo, that worked! Nice.

Then I noticed this one in the examples of the groups Graph API:$count=true&$filter=hasMembersWithLicenseErrors+eq+true&$select=id,displayName. So I tried$filter=displayName+eq+Budget, but nope it didn’t work.

Just for kicks I then added single quotes around the search term “Budget”, and that worked!$filter=displayName+eq+'Budget'. That got me wondering if I could remove the + as that just looks like encoding for spaces, and I found this link which was just above the filter section I had previously come across. Yes, you can & should encode spaces etc. In fact they even have some examples:

  •$filter=subject eq 'let''s meet for lunch?'

The first one’s interesting. It’s just what I had been trying to do earlier. Thus it offcially confirmed the eq filter has a different syntax to startsWith and endsWith. Why?

Anyhoo, long story short (too late!) this is how to use the cmdlet to get a single group called “Budget”:

I am glad Microsoft created the Microsoft.Graph module. Things were crazier in the dark days before this module when you had to use Invoke-RestMethod. Nothing wrong with Invoke-RestMethod but you have multiple steps… first authenticate with a secret (easy) or certificate (not so easy, you need to generate a JWT (here’s a PowerShell script to do that)) to get an access token; then use that access token each time to pass along in the headers to Invoke-RestMethod. There’s separate REST endpoints for each of these that you got to keep track of. At least with the Microsoft.Graph module I can just run Connect-MgGraph and it abstracts all this stuff away…