Use the Microsoft Graph PowerShell SDK to Reduce Code and Make Scripts Easier to Follow
The announcement for Microsoft Places was in October 2022. However, Places failed to gain much traction until earlier this year when Microsoft launched a public preview. I never felt the need for a connected workspace that would facilitate serendipitous meet-ups, so I have not paid much attention to Places yet, figuring that I could wait until the technology reached general availability.
Then a report arrived of an error in the meeting room statistics script. The script uses Graph API requests to interrogate the calendars of room mailboxes to extract information about events before analyzing usage patterns. Any attempt to retrieve workspace data resulted in a 404 (not found) error. The URI used for the request was:
https://graph.microsoft.com/V1.0/places/microsoft.graph.workspace
The request asks the Places resource to return any workspace objects and had worked flawlessly since the script was published. Some investigation revealed that using the beta endpoint worked, as in:
https://graph.microsoft.com/beta/places/microsoft.graph.workspace
My conclusion is that Microsoft made some changes to the Places resource to support the public preview of Microsoft Places. I didn’t notice because I didn’t spend any time investigating Places. In any case, I updated the script in GitHub, and all is well. The script to generate a weekly report for room mailbox schedules is unaffected.
Reader Expectations for Code Examples
The experience caused me to reflect on the expectations people have of code examples covered in articles on this and other websites. Authors obviously want their code to work. It’s not nice when someone finds a bug. Many sites don’t bother fixing problems after they’re discovered. The attitude is that any code posted is “as is” and readers should be prepared to work through problems encountered in the code.
It’s reasonable to expect that people should be able to debug and fix code that they download from an article or a GitHub repository. After all, if you can’t have the necessary technical knowledge to understand how code downloaded from somewhere on the internet works (perhaps not the finer details, but definitely in outline, you shouldn’t run the code on anything but a test system.
PowerShell scripts found on sites like Practical365.com are not complete solutions. Rather, the code is to explain principles and demonstrate how to accomplish goals. Before the code can be put into production use, it needs to be bullet-proofed using the techniques explained by Michel de Rooij in his Practical PowerShell series.
In saying all of this, we sincerely appreciate the comments people post and do our best to respond as quickly as possible. Sometimes the response will be a simple acknowledgment of the bug, and sometimes we will update the code.
Common Problems with Graph-Based Articles
Looking at the comments we receive for scripts based on the Microsoft Graph, it’s obvious that many issues are related to three major topics: permissions, pagination, and access token expiration.
Permission issues tend to be because people mix up delegated and application permissions, use an app that doesn’t have the right permissions (including the Microsoft Graph PowerShell SDK app), or use an account that doesn’t hold a required administrative role. These are easy problems to sort out: assign the right permissions and rerun.
Pagination is the process used by the Graph to fetch pages of data until all available data is retrieved. Scripts commonly use a function to make sure that they process any nextlinks returned by requests. If not, requests that return more than the default page size (which can be as low as 10) won’t process all available data.
Access token problems come into two categories: getting an access token from Entra ID with the right scopes (permissions) and renewing an access token after its validity expires, usually after an hour. Access token renewal typically only becomes a problem when tens of thousands of objects must be processed, like the example where someone used the script to extract statistics for several thousand room mailboxes over a two-year period. This kind of processing takes time!
Article writers who cover Graph topics are accustomed to dealing with reported issues due to these reasons. You can see this interaction between readers and authors in many articles on this site.
The Microsoft Graph PowerShell SDK Solves Many Problems
Over the past year or so, I am increasingly convinced that using cmdlets from the Microsoft Graph PowerShell SDK is a better choice for writing sample Graph-based code. When you create an SDK session by running the Connect-MgGraph cmdlet, Entra ID issues an access token containing the scopes permitted by the authentication method. SDK sessions don’t need to worry about access token expiration and renewal because this happens automatically.
An interactive session uses a combination of delegated permissions granted to the SDK app and the rights granted to the signed-in account from the administrative roles it holds. An interactive session is great for testing against your own data. Accessing other peoples’ data means using application permissions gained by authenticating using an Entra ID app.
A further advantage is that SDK cmdlets handle pagination automatically. Most SDK cmdlets include an All parameter to instruct the Graph to provide all available data, and you can use the PageSize parameter to increase the number of objects returned in a page.
Overall, authentication to connect to an SDK session with the right permissions is easier for developers (fewer lines of code) and readers. Throw in easier pagination and the scripts written using the SDK are easier to write and follow, even if the SDK has its own set of quirks to understand. I now write everything using the SDK and avoid using “normal” Graph API requests unless absolutely necessary.
A New Version of the Room Mailboxes Statistics Script
Given the 90-odd comments for the original room mailboxes statistics script, it seemed like a good idea to put my preaching into practice and create a version based on the SDK. You can download the script from GitHub. This version uses:
- An Entra ID app to authenticate. The same app as used with the previous version can be used because the same permissions are required. The app authenticates using a certificate thumbprint.
- The Get-MgPlaceAsRoom cmdlet to find room mailboxes.
- The Graph request described above to find workspaces. I can’t find an SDK cmdlet to return workspace. Occasionally this happens, especially when a resource (like Places) is under active development.
- The Get-MgUserCalendarView cmdlet to fetch events from room mailbox calendars.
The rest of the code is the same as the previous version. That version didn’t generate any output files, so I added output of files for the room mailbox summary and the top organizers. The files are created as Excel worksheets (Figure 1) If the ImportExcel module is available on the workstation. Otherwise, the script creates CSV files.
Only Update Code When Necessary
No one likes going near code that works to seek improvements that might be marginal at best. I am not advocating that anyone should update scripts that successfully use Graph API requests to replace those requests with SDK cmdlets. That would be a waste of time. But when you write new code or need to revisit older scripts to fix bugs, consider using the Microsoft Graph PowerShell SDK to reduce the code that needs to be written and make it easier for people to read.