Use the Debug Parameter for Microsoft Graph PowerShell SDK Cmdlets to Expose Graph API Requests

Debug Microsoft Graph PowerShell SDK Cmdlets to Gain Insights into What They Do

A comment for my article about recent enhancements for the Microsoft Graph Explorer noted that while it was great to see the Graph Explorer generate PowerShell code snippets for requests it executes, it would be even nicer if the Graph Explorer supported “round tripping.” In this instance, that means users could send PowerShell commands to the Graph Explorer, which would then interpret the commands and generate the appropriate Graph API requests. It sounds like a great idea.

I contacted some of the folks working on the Microsoft Graph to see if this is possible. Although they couldn’t commit on such an implementation appearing in the future, I was told about a nice feature in the Microsoft Graph PowerShell SDK cmdlets. It doesn’t address the round-tripping request, but it’s a good thing to know none the less, especially if you’re grappling to understand how the SDK cmdlets work for tasks like user, group, or license management.

In a nutshell, if you add the –Debug parameter to any Microsoft Graph PowerShell SDK cmdlet, you’ll see exactly what the cmdlet does, including the Graph API request it runs to execute the command. This is a great way to gain insight into how these cmdlets work and also understand how to leverage Graph API requests.

Because many of its cmdlets are built on Graph APIs, the Debug parameter also works in the same manner for cmdlets from the Microsoft Teams PowerShell module. However, the Teams cmdlets do not output details about permissions and the older policy cmdlets that originated from the Skype for Business Online connector do not display Graph API URIs when they run.

Running with the Debug Parameter

Let’s take a basic example and run the Get-MgUser cmdlet to fetch details of all user accounts in a tenant:

Get-MgUser -All -Debug -Filter "userType eq 'Member'"

When the cmdlet starts, it shows the context it will run under, including whether it’s an interactive session and the scopes (permissions) available to the command. You can get the same information by running the Get-MgContext cmdlet, but this is useful up-front knowledge.

In Figure 1 you can see that the service principal used by the Microsoft Graph PowerShell SDK has many permissions. This is the result of permission creep, the tendency of the service principal to accrue permissions over time due to testing different cmdlets. The existence of so many permissions makes it a bad idea to use the Microsoft Graph PowerShell SDK cmdlets interactively unless you know what you’re doing. In production, it’s best to use certificate-based authentication and a registered Azure AD app to limit the permissions available.

Debug Microsoft Graph PowerShell SDK cmdlets - the execution context
Figure 1: Debug Microsoft Graph PowerShell SDK cmdlets – the execution context

The Graph API request is now displayed. We can see that it looks for the top 100 matching items that satisfy the filter. In other words, return the first 100 Azure AD member accounts (Figure 2).

Debug Microsoft Graph PowerShell SDK cmdlets - the HTTP GET request
Figure 2: Debug Microsoft Graph PowerShell SDK cmdlets – the HTTP GET request

As you can see, running with Debug set, the cmdlet halts frequently to allow you to read what’s happened and understand if the command has any problems. If you want to see the cmdlet run as normal but with the diagnostic information, set the SDebugPreference variable from its default (SilentlyContinue) to Continue.

$DebugPreference="Continue"

To revert to normal operation, set $DebugPreference back to SilentlyContinue.

Pagination

Pagination is a concept that doesn’t really exist in PowerShell. Some cmdlets have a ResultSize parameter to control the number of items retrieved by a command, and some have an All parameter to tell the command to fetch everything. The Get-MgUser and Get-MgGroup cmdlets are examples of cmdlets that support an -All parameter.

Graph API requests limit the retrieval of data (usually to 100 or 200 items) to avoid issues caused by requests that might mistakenly look for tens of thousands of items. If more items exist, the application must make additional requests to fetch more pages of data until it has fetched all available items. Applications do this by following a nextlink (or skiptoken) link.

In Figure 3, we see a nextlink for the cmdlet to run to retrieve the next page of data. In this instance, I ran the Get-MgUser cmdlet with no filter, so more than 100 accounts are available, and this is what caused the Graph to respond with the first 100 accounts and the nextlink. In debug mode, you can pause after each page to see the results retrieved from the Graph.

Debug Microsoft Graph PowerShell SDK cmdlets - a nextlink to more data
Figure 3: Debug Microsoft Graph PowerShell SDK cmdlets – a nextlink to more data

Another Thing for the Administrator Toolbox

Facilities like the Debug parameter and the Graph X-ray tool help people to understand how the Graph APIs work. Knowing how the Graph functions is invaluable. Having an insight into how cmdlets work helps people develop better code and hopefully avoid bugs. At least, that’s the theory. Try out the Debug parameter with some Microsoft Graph PowerShell SDK cmdlets and see what you think.


Learn how to exploit the data available to Microsoft 365 tenant administrators like how to debug Microsoft Graph PowerShell SDK cmdlets through the Office 365 for IT Pros eBook. We love figuring out how things work.

2 Replies to “Use the Debug Parameter for Microsoft Graph PowerShell SDK Cmdlets to Expose Graph API Requests”

  1. Great info Tony! I guess one thing worth mentioning (a downside when attempting to run the script unattended) is that the -Debug switch continuously prompts for each operation (command). Another way of getting the Debug output is to run the cmdlet without the -Debug switch, but setting the $DebugPreference variable to ‘Continue’ (default is ‘SilentlyContinue’). E.g.:
    $DebugPreference=’Continue’
    Get-MgUser -All -Filter “userType eq ‘Member'”

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.