A Unified Approach to Microsoft 365 management
The Microsoft Graph API has been around for some time now and Microsoft is moving more management functions (such as License Management for Azure AD Accounts) to the platform. When Microsoft transitions a function to the Graph, organizations might have to update PowerShell scripts.
Getting started with the Graph API can be a daunting task, particularly if you don’t have experience with REST-based services. With some practice and time spent reading the Graph documentation, it’s possible to see how tools such as the Microsoft 365 Tenant Migration Assessment are put together and begin to understand the value of using the Graph.
If you want a more familiar way to leverage the Graph, the Microsoft Graph PowerShell SDK simplifies the process and packages it into a (relatively) simple PowerShell module. There are ups and downs to connecting to the Microsoft Graph using the PowerShell SDK, but it makes the process of learning and adopting the Graph API easier for tenant admins.
In the first part of a series about using the Microsoft Graph PowerShell SDK, I explain what the SDK is and what needs to be considered when getting started.
What is the Microsoft Graph API?
One way to look at the Microsoft Graph API (or any Graph API) is as a set of nodes in a logical tree-structure. The request is sent to the endpoint that represents the data you want to access.
For example, the users endpoint (https://graph.microsoft.com/v1.0) returns all users in the tenant, but to get data on a specific user, for example, firstname.lastname@example.org, we query the endpoint https://email@example.com.
This logic continues along the structure as shown in Figure 1. For example, the endpoint https://firstname.lastname@example.org/Messages returns the email messages for email@example.com, while the endpoint https://firstname.lastname@example.org/<Message ID> returns the details of an individual message.
The Microsoft Graph Explorer is a useful way to explore the different endpoints and the information they return. It also comes with a sample dataset to query so you can get familiar with the tool before connecting it to your production tenant. In Figure 2, we see the results from Graph Explorer for the manager endpoint of the user AdeleV.
Results of Graph queries are returned in JSON format which is flexible enough to account for different types of values and nested objects.
Another thing to consider when using Graph APIs is the permissions that are required for each endpoint and operation you run. To read more about permissions in the Microsoft Graph API, check out this article on How to Figure Out What Microsoft Graph Permissions You Need.
How does the PowerShell SDK help?
Working with the Graph API is a new concept for many tenant admins and there is a learning curve to master. The PowerShell SDK is a way for admins who are more comfortable with PowerShell to use the Graph without worrying about the specifics such as authentication tokens and formatting requests.
The SDK does this by providing PowerShell cmdlets that issue the Graph calls on your behalf. For example, in Figure 3, we see the Get-MgGroup cmdlet from the PowerShell SDK issues a GET request to the endpoint https://graph.microsoft.com/v1.0/groups. While it’s possible to send this request directly using Invoke-WebRequest, having a more familiar set of cmdlets and parameters simplifies working with the Graph significantly.
When creating new objects or updating existing objects through the Graph, a JSON payload is required to define the parameters of the new or updated object. This payload follows a predefined schema for each object type that can be awkward to get right. SDK cmdlets format the payload automatically based on the cmdlet parameters. For example, in Figure 4, the New-MgUser cmdlet passes the JSON data required by the Graph API to create a new user.
Using the -Debug parameter for Microsoft Graph PowerShell SDK Cmdlets is a good way to get visibility into what the SDK is doing in the background and view the requests that are being sent to the Graph API.
Installing the PowerShell SDK
The Microsoft Graph PowerShell SDK is available in the PowerShell Gallery. To install the SDK, the PSGallery repository must be registered, without it, the installation will fail as shown in Figure 5. To register the repository if it is missing, run the cmdlet Register-PSRepository -Default, and the install should then work.
Once the SDK is installed, 39 new modules are available (count correct at the time of writing).
Updating the SDK is relatively painless running the cmdlet Update-Module Microsoft.Graph as administrator and restarting PowerShell. The SDK is updated monthly and it’s important to use the latest version.
Using Azure Automation
Automation is a key factor for PowerShell. Automating tasks is often crucial to the day-to-day running of a Microsoft 365 tenant, as it allows admins to focus on adding value elsewhere. While the SDK runs perfectly fine as a scheduled task from a Windows server, Azure Automation adds an extra level of security and availability to automated tasks.
This article about Using the Microsoft Graph SDK for PowerShell with Azure Automation explains the requirements to get the Graph SDK running in Azure Automation.
Delegated vs Application Permissions
The Microsoft Graph supports two types of permissions, Delegated and Application. At a high level, delegated permissions run as if a user is present and generally require the user to authenticate and retrieve an access token interactively. Delegated permissions are often used for client applications that connect to the Graph on behalf of end users and are the default method for the PowerShell SDK and Graph Explorer. Apps using delegated permissions are limited to the permissions available to the signed-in user, so a non-admin user who uses the SDK is only able to carry out tasks that their account has permissions to perform.
Application permissions run as an app registration and support non-interactive authentication. Application permissions are generally used for automated tasks or apps that can’t use interactive authentication. Configuring application permissions for the Graph SDK requires using a registered application in Azure AD. As application permissions do not run as the current user, they are not subject to the permissions restrictions that delegated permissions are. Be careful when using application permissions, particularly when it comes to storing the client secret or certificate.
Another consideration when choosing between delegated and application permissions is functionality. There are tasks in Microsoft 365 that must be done by a user. For example, this article about Creating a New Microsoft 365 Group with the Microsoft PowerShell Graph SDK shows how to set up a Microsoft 365 Group and assign a sensitivity label, and this works well using delegated permissions. Trying to do the same with application permissions fails as it is not supported with an App-only token (Figure 6).
There are many nuances like this that impact the type of permissions needed. It’s important when planning your code to check the documentation to identify where you may find an issue.
Connecting to the Graph using the SDK
Multiple ways exist to connect to the Graph API using the SDK depending on how you want to use the cmdlets. The most common scenarios for connecting are:
- Connect interactively with delegated permissions
- Connect non-interactively with application permissions and a certificate
- Connect non-interactively with application permissions and a client secret
- Connect using Azure Automation and managed identity
Connecting with delegated permissions is most likely the first method people will try and the easiest to do. Running the cmdlet Connect-MgGraph and specifying the scopes you want prompts for login and consent to be granted to the Microsoft Graph PowerShell app, as shown in Figure 7.
Using Graph application permissions with a script requires a registered Azure AD app with consent to use the necessary permissions. I won’t go over creating an app registration here as it has been discussed many times (like in this article on Prepopulating Outlook Contacts with the Graph API), but with an app registration in place, the Connect-MgGraph cmdlet accepts both Client Certificate or Access Token parameters.
Using Client Certificate as shown in this article on Using Certificate-based Authentication with the Microsoft Graph PowerShell SDK is a great way to automate tasks with the PowerShell SDK securely (as long as you make sure to store the certificate in a secure location such as Azure Key Vault).
To use a Client Secret, you first need to obtain an access token. There are multiple methods of obtaining an access token for the Graph API, but an easy method is to use the Microsoft Authentication Library PowerShell Module (MSAL.PS), as mentioned in this article on Using Azure Automation to Process Exchange Online Data with PowerShell.
Figure 8 shows both methods in action.
Using the Microsoft Graph SDK for PowerShell with Azure Automation is a good way to automate long-running or complex scripts. The Microsoft Graph SDK can also use Managed Identities through Azure Automation, assigning permissions to the service principal of the managed identity and making them available directly to the Automation Account.
In this article, I explain how the Microsoft Graph PowerShell SDK simplifies the management of Microsoft 365 through the Microsoft Graph API. I also show how to get connected to the Graph using the SDK in a variety of scenarios. Getting connected and understanding the requirements when working with the Graph is the first big challenge many admins experience when trying to update their code.
In part two of this series, we will dive deeper into using the Microsoft Graph through the SDK and look at some examples of where it can save you time and effort through automation and bulk processing.