Now that we have device-based licensing for Office available to enterprise customers as well, adding device objects to Azure AD groups will become more common. The need to report on group membership for device objects will also arise. Neither the Azure AD blade nor PowerShell provide an easy option to do this, and while you can certainly enumerate all groups and their members via the Azure AD cmdlets (note that the old MSOnline module does not recognize devices as valid members for groups), this approach is not optimal.
Luckily, the Graph API gives us a better method, namely calling the memberOf endpoint, which is also supported for Device objects. We don’t yet however have a matching Azure AD PowerShell cmdlet (Get-AzureADUserMembership only covers user objects as the name suggestes), so if you want to do this via PowerShell you have to call the Graph endpoints directly. And since I’ve been posting a lot of proof-of-concept scripts around the use of Graph API lately, I figured I’d do yet another one for this scenario.
In a nutshell, all we have to do is fetch the list of device objects in the tenant by calling the devices endpoint, then loop over each device and query the memberOf, or the analogous transitiveMemberOf endpoint. And lastly, export the result to CSV file. Of course some additional details would be needed in order to obtain a token first, but I’ve covered the process in multiple articles already, so I’ll just skip the steps this time around.
You can find the sample script over at my GitHub repo. As usual, it lacks robust error checking, anti-throttling controls and so on, being a proof-of-concept code and all. It also fetches a minimal set of properties for each device, which you might want to expand on. I’d recommend always including at least one unique-valued property, such as the ObjectId. Same goes for the actual Groups returned by the transitiveMemberOf query, while of course it’s much easier to use display names in the output, you might end up with duplicate values and ambiguous results. Of course, you can always modify the code to export additional properties, for example by adding a new line for each device/group combo and dumping additional information about the group so that you don’t have to do additional queries later on (for example, is this a Security group, or an M365 group, is it mail-enabled, is it security-enabled, etc.).
It goes without saying that you should test this code before running it in production environments. While I’ve added the necessary bits to handle large number of devices, I only have a dozen or so in my tenants so I cannot possibly test for all scenarios. And again, minimum error handling is added to the code, so you might want to expand on that part as well. Let me know if you run into any issues.