When the Invoke-MgGraphRequest Cmdlet Needs Help to Fetch Responses

Running Graph API Requests and Checking the Response

Whenever I need to run a Graph API request where a Microsoft Graph PowerShell SDK cmdlet isn’t available (or doesn’t work as expected), my normal go-to solution is the Invoke-MgGraphRequest cmdlet. The cmdlet works well and is extremely useful when testing a new API because it uses the authenticated connection established by the Connect-MgGraph cmdlet. In other words, you don’t need to obtain an access token to run requests because the cmdlet uses the token held by the session, including the scopes (permissions) detailed in the token.

The Graph Explorer App and Its Permissions

However, sometimes the Invoke-MgGraphRequest cmdlet comes up short and a different tool is needed for testing. That’s where the Graph Explorer can help. Like the Microsoft Graph PowerShell SDK, the Graph Explorer is implemented as an enterprise Entra ID app (appid de8bc8b5-d9f9-48b1-a8ad-b748da725064). And like the Microsoft Graph PowerShell Command Line tools app, the Graph Explorer app accumulates a set of delegated permissions over time as consent for permissions is granted to allow requests to run (that’s why the Graph Explorer UI includes a prominent Modify Permissions button).

The permissions allow signed-in users to run Graph API requests and access data available to them. Sometimes too many permissions can get in the way of testing, so it’s a good idea to review the permissions and remove any that seem not to be necessary.

Running an eDiscovery Purge Job

In this case, I was experimenting with the eDiscovery method to purge mailbox data based on a search. This is not the compliance search purge action. It’s an action to purge data found by eDiscovery premium searches. The Clear-MgSecurityCaseEdiscoveryCaseSearchData SDK cmdlet runs purge requests, using a command this:

Clear-MgSecurityCaseEdiscoveryCaseSearchData -EdiscoveryCaseId $Case.Id -EdiscoverySearchId $Search.Id -BodyParameter $PurgeParameters

The problem is that the cmdlet only reports failures (like a malformed payload). It doesn’t report the successful submission of the background purge job it creates, nor does it report the progress and eventual result of the purge job. Submission is like lobbing a stone into a deep black pit.

At first glance, using Invoke-MgGraphRequest doesn’t do any better. Once again, nothing happens, and no insight is available into the progress of the purge job.

$Uri = ("https://graph.microsoft.com/v1.0/security/cases/ediscoveryCases/{0}/searches/{1}/purgeData" -f $Case.Id, $Search.Id)
Invoke-MgGraphRequest -Uri $Uri -Body $PurgeParameters -Method POST

The documentation for the API says that a successful submission returns a 202 Accepted response code, and a response header containing the location of the Purge data operation created to commit the purge. The question is how to see that information.

Graph Explorer Reveals Responses

The Graph Explorer is designed to be a training and debugging tool. As you can see in Figure 1, it displays the 202 Accepted response, and it shows the response header. To see what’s happening with the purge job, copy the location URL and run a GET request against it (in Graph Explorer or using Invoke-MgGraphRequest) and you’ll see details such as the current progress of the purge job.

Graph Explorer reveals response headers for a Graph API request.

Invoke-MgGraphRequest
Figure 1: Graph Explorer reveals response headers for a Graph API request

Invoke-MgGraphRequest Comes Through in the End

You can’t run Graph Explorer in a script. Although the app is great for testing, it can’t work in a production environment. All of which brought me back to the Invoke-MgGraphRequest documentation, where I discovered the ResponseHeadersVariable parameter, which outputs response headers to a variable if generated by an API request. We can’t see the 202 response for a job submission, but we can fetch details of the purge job by extracting the URI from the variable and using it to query the job status. Apparently, the purge succeeded!

Invoke-MgGraphRequest -Uri $Uri -Body $PurgeParameters -Method POST -ResponseHeadersVariable Response

[string]$ResponseLocationURI = $Response.Location
$ResponseURI = [system.uri]$ResponseLocationURI

$ResponseData = Invoke-MgGraphRequest -Uri $ResponseURI -Method Get

Name                           Value
----                           -----
createdDateTime                05/06/2025 13:44:58
id                             f580a3b0c72b4c849912520e04bc39e7
percentProgress                100
@odata.context                 https://graph.microsoft.com/v1.0/$metadata#security/cases/ediscoveryCases('7fc26cf0-bc8d-421c-8ad1-bea9782f564c')/operations/$entity
action                         purgeData
status                         succeeded
@odata.type                    #microsoft.graph.security.ediscoveryPurgeDataOperation
completedDateTime              05/06/2025 13:47:23
createdBy                      {[user, System.Collections.Hashtable], [application, ]}

The learnings here are that the Graph Explorer is a very useful debugging tool and that you should check every cmdlet parameter, even for cmdlets that have become second nature.

2 Replies to “When the Invoke-MgGraphRequest Cmdlet Needs Help to Fetch Responses”

  1. Please can you confirm my understanding?

    In the last code block does the first line need to be assigned to the $Response variable?

    If not, I cannot see where line 2 gets the location:
    “[string]$ResponseLocationURI = $Response.Location”

Leave a Reply

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