Using Dev Proxy with the Microsoft Graph PowerShell SDK
Use Dev Proxy to Detect Common Problems in SDK Scripts
Dev Proxy is a Microsoft API simulator to help developers test cloud applications. That doesn’t sound very interesting to Microsoft 365 tenant administrators, but after reading a series of LinkedIn posts by Waldek Mastykarz (who has the splendid title of “AI Coding Agents Advocate at Microsoft), I decided to have a look at what Dev Proxy does.
In his posts (here’s an example), Waldek explains how Dev Proxy helps with issues like excessive permissions, poor use of select to minimize data fetched by Graph requests, and improper pagination. Although the Microsoft Graph PowerShell SDK takes care of a lot of Graph housekeeping, permissions and performance are problems faced by people who write PowerShell scripts based on SDK cmdlets.
Getting Dev Proxy Installed on a PC
The Dev Proxy documentation explains how to install the proxy using WinGet. I recommend that you also install the Dev Proxy Toolkit extension for Visual Studio Code because it makes it easier to edit the JSON configuration files used by the proxy. Of course, you can edit the JSON files with Notepad, but Visual Studio Code is the smarter option.
Plugins, Configuration Files, and the Graph
Dev Proxy uses a plugin architecture. The plugins are defined in configuration files, and each plugin instructs the proxy about some form of behavior to monitor. From the perspective of the Microsoft Graph PowerShell SDK, we’re interested in plugins like GraphMinimalPermissionsGuidance, to observe the permissions available to an application and report whether the application is overly-permissioned, and GraphSelectGuidance, which checks the properties for each item fetched by Graph requests to highlight when performance can be improved by retrieving a smaller set of properties.
Dev Proxy comes with a set of standard configuration files. Microsoft recommends that you create your own configuration file instead of editing the standard files. If Dev Proxy finds a file called devproxyrc.json in the directory where you’re running the proxy from, it will use that, but you can create and use whatever configuration file you like. Microsoft recommends that you create files used with Dev Proxy in a separate folder.
For our purposes, the m365.json file at %localAppData%ProgramsDev ProxyConfig is a good starting point for a configuration file to test Microsoft 365 scripts. I copied portions of the m365 file over to my custom devproxyrc.json to get a configuration I was happy with. Figure 1 shows the file being edited with Visual Studio Code.

Monitoring Scripts with Dev Proxy
After tweaking the configuration file, we’re ready to monitor Graph requests. In a PowerShell session, type:
devproxy --record
Alternatively, put a record:true instruction in your Dev Proxy configuration file to have the proxy start up in record mode each time.
The proxy reads the configuration file to know what it should monitor and begins listening. As Graph requests are made by Microsoft Graph PowerShell SDK cmdlets or other applications, the proxy examines what happens and reports what it finds. I found it amusing that any time Outlook (classic) opens a message, it issues a Graph request to fetch the photo for the sender (Figure 2).

Pagination is not usually an issue for Microsoft Graph PowerShell SDK scripts. Most cmdlets that fetch information support an All parameter to instruct the Graph to return all available data. The cmdlet then takes care of processing nextlink URLs until it has retrieved all records. However, there are exceptions to the rule and Figure 3 shows an example. In this case, the script is fetching Exchange Online message trace data (see this article). The original call to the messageTraces endpoint is visible as is the call to fetch the next page of message trace results.

You can see that the Graph request created by the cmdlet is shown by Dev Proxy rather than the cmdlet. This is similar behavior to how the Debug parameter works when running Microsoft Graph PowerShell SDK cmdlets.
Restricting Properties with Select
An example of detecting when request performance could be improved by including Select to specify the properties of items to be fetched is shown in Figure 4. The top request is generated by Get-MgUser. The second is Get-MgUser with a -Select qualifier. Restricting the number of properties retrieved by requests won’t make much difference in small tenants. It will once you deal with thousands of objects.

The proxy generates the “skip” messages shown in these figures when a plugin doesn’t process a request for some reason (such as the beta plugin receiving a V1.0 request). To suppress the skip messages, make sure that the showSkipMessages instruction is set to false in your configuration file.
The Permissions Conundrum
Good security mandates that Microsoft Graph -based applicationss should use least-permission access. In other words, applications should be granted consent for the lowest possible level of permission required to do a job. It’s common to find that developers seek higher levels of permission “just in case,” through lack of knowledge, or because it’s hard to figure out the exact permissions. For instance, many do not know that the User.ReadBasic.All permission is available if an application only needs access to user properties like the display name and user principal name. In these circumstances, the higher User.Read.All permission is not required.
Dev Proxy observes the Graph requests made by an application and works out the permissions required to make those requests. At the end of a recording session, Dev Proxy reports the permissions held by an application that have not been used. If the application has fully exercised its functionality, the application doesn’t need the highlighted permissions and they can be removed.
Permission monitoring happens for app-only and interactive Graph SDK sessions. One of the characteristics of the Microsoft Graph Command Line Tools enterprise application, used to run interactive Graph sessions, is its propensity to accrue permissions over time. This isn’t a new issue. I first wrote about it in September 2021. The net effect is that interactive sessions usually have access to a bunch of delegated permissions. Figure 5 shows the report generated by Dev Proxy when it compared the permissions used in a session with those held by the application.

Of course, this is an outrageous example to prove the point. Applications should be checked to validate the permissions that they hold. Tenants should conduct regular reviews of permission assignments to ensure that standards hold, but developers should also check their permissions before launching their applications on the unwary.
The Connect Issue
One odd thing that I discovered is that I couldn’t run Connect-MgGraph in a PowerShell session when Dev Proxy was actively monitoring. All attempts failed with the message:
Connect-MgGraph: InteractiveBrowserCredential authentication failed:
However, if I stopped the proxy, I could run Connect-MgGraph, issue some commands to make sure that everything worked, and then restart the proxy in record mode. Odd.
Some Value for PowerShell Developers
Dev Proxy is a more useful to developers who build traditional applications than those who develop PowerShell scripts based on the Microsoft Graph PowerShell SDK. Even so, people do experience difficulties figuring out permissions and other issues with scripts based on the Microsoft Graph and any help is welcome. Dev Proxy is something that should be considered, if only for help to settle on the lowest possible permissions for any task.
Need help to write and manage PowerShell scripts for Microsoft 365, including Azure Automation runbooks? Get a copy of the Automating Microsoft 365 with PowerShell eBook, available standalone or as part of the Office 365 for IT Pros eBook bundle.









