Administrators managing products such as Sharepoint, Teams, and Azure AD tend to use multiple PowerShell modules as each service has its own PowerShell module. Although this helped a lot, the real need is for a one-stop shop that helps in managing all the services instead of having multiple modules. The solution is to use the Microsoft Graph SDK PowerShell module.

Microsoft Graph API PowerShell module offers control over all the services using one PowerShell module, so If you are like me, who struggles with multiple PowerShell modules to manage the cloud services, then this post is the post you don’t want to miss.

Prerequisites

This is a hands-on demonstration. If you’d like to follow along, be sure you have the following:

Why switch to Microsoft PowerShell Graph Module SDK?

Microsoft PowerShell Graph Module SDK allows interacting with all Microsoft APIs, including SharePoint, Exchange online…etc. So no need for a separate PowerShell module for each service. Microsoft will discontinue the Azure AD Graph endpoints, which means that the AzureAD and MSOL modules will no longer work and a PowerShell script rewritten is required.

Microsoft PowerShell Graph Module SDK is cross-platform and supports Windows, macOS, and Linux

Downloading and installing Microsoft PowerShell Graph Module SDK

The first step in getting started with Using Microsoft Graph API in your Powershell session is to install Microsoft.Graph Module. This module is much more widely called the Microsoft Graph Powershell SDK, and all of the cmdlets in it begin with “Mg.” Another thing I like about one such module is how it works perfectly with Powershell 7.

The Graph API PowerShell Module must be downloaded first. Begin by launching PowerShell 7 and entering the following command:

Install-Module -Name Microsoft.Graph

PowerShell downloads and installs Microsoft.Graph Module on the system. This could take a few minutes to finish.

Installing Microsoft.Graph
Installing Microsoft.Graph

Type the following cmdlet to confirm a successful installation.

C:\> Get-Module -ListAvailable Microsoft.Graph

The return lists the installation version and name

Microsoft.Graph installation details
Microsoft.Graph installation details

Always keep your PowerShell modules updated by running Update-Module

Understanding Different between Microsoft Graph API vs. AzureAD PowerShell module

Authentication and authorization support are some of the differences between MSOnline, AzureAD, and Microsoft Graph. Credential object and token access authentication are supported by the legacy modules. The Microsoft Graph API, on the other hand, supports browser authentication, token access, and certificate authentication, as well as passing the required permissions known as scopes.

Touring Around and First look at Microsoft Graph Connect-MgGraph Scopes

The PowerShell module has currently been downloaded and set up. The next step is to establish a connection to the Graph API endpoint. Use the cmdlet Connect-MgGraph to connect to the Microsoft Graph API. When connecting to Microsoft Graph, things get a little strange because you have to specify the connection scope.

There’s no need to be concerned about the scopes. This is covered in the tutorial, but for now, let’s take a look around and see how things look.

Run the following line to connect to the Microsoft Graph API via PowerShell.

Connect-MgGraph -Scopes "User.Read.All","Group.ReadWrite.All","GroupMember.ReadWrite.All"

Following the execution of the Connect-MgGraph cmdlet, a new browser session is launched, requesting authentication. This is how browser authentication appears.

Browser-based based authentication.
Browser-based based authentication.

Following authentication, you must accept the permissions listed

Consent on the required permissions
Consent on the required permissions

When you click Accept, you authorize this application/script to access the specified permission.

Then the browser displays a message “Authentication complete. You can return to the application. Feel free to close this browser tab.

Close the browser, open back PowerShell, and now you are connected. PowerShell shows a welcome message.

Welcome to Microsoft Graph
Welcome to Microsoft Graph

You are connected, but what are these permissions, the scope, and how do you find the required scope?

Understanding Microsoft Graph Permissions and Scope

Applications that use Graph API, such as Azure Active Directory, Teams etc., have their permission chunked into a small permission set. For example, Azure Active Directory permission is chunked to a list of a small set of permission such as User.Read.All, Group.ReadWrite.All…etc.

Any third-party application that connects to Azure Active Directory using Graph API needs to specify the permission it needs for it to work correctly. These small permission are called Scope.

One or more permission scopes protect each API in the Microsoft Graph. The logged-in user must agree to one or more of the required scopes for the APIs you intend to use.

Even if the global admin account is used for authentication, the global admin must specify the access and consent permission scope. In contrast to older modules such as AzureAD and MSOnline, the admin has full access once connected.

Understanding Microsoft Graph API Scope

Microsoft Graph uses a simple pattern: Resource.Operation.Constraint, for example, User.Read grant the permission to read the user profile for the signed-in user.

User, Group, Object, and so on are all examples of resources.
Operation: Can be one of Read, Write, Update, and so on.

The constraint element determines the extent of access the app/script will have to the directory. There are four constraints, but the focus of this post is on two:

  • All: Grant permission to perform the Operation on all Resource types in the directory. For example, User.Read.All grant permission to read all the user’s profiles in the directory.
  • If no constraint is specified, the scope is limited to what the signed-in user can do, for example, the User.Read scope reads only the signed-in user information.

If multiple scopes are required, such as reading user’s information and groups information, the scope is separated by a comma “,”. Such as User.Read, Group.Read

To connect to Graph API to perform read operations for all users and groups in the directory, use the following.

Connect-MgGraph -Scope @('User.Read.All', 'Group.Read.All')

Read More about Microsoft Graph Permission on Microsoft.com

How PowerShell Authenticates with Microsoft Graph API.

Interacting with Microsoft Graph necessitates Authentication and Authorization.

Introduction to Microsoft Graph API Authentication

  • Authentication: The authentication can be one of the following:
    • Delegate Authentication: The user must type the username and password and have a valid account with the tenant. usually, this type of authentication opens up a browser window for the user to authenticate.
      • Pros: If the user has already authenticated to the office 365 web interface, there is no need to authenticate.
        • You won’t need to handle the MFA part and do much work to authenticate the user, all handled by the web browser and the PowerShell Module.
      • Cons: user experience is not friendly as the user needs to navigate outside the PowerShell and use the browser to authenticate.
        • Won’t help in automation.
    • Application Authentication: Seemless authentication won’t ask the user for a username or password from the user. How?. First, the Azure admin should have registered an App in Azure Active Directory –> App Registrations.
      This process creates a Service Principal Names SPN used during the authentication. Consider this similar to a username.
      After registering the application. You will have a Client ID and client credentials. The Client ID, Tenant ID, and the client credentials information will be used in the PowerShell script to connect and authenticate your script to the cloud.
      The Client Credentials can be one of the following:
      • Certificate
      • Client Secrets
      • Federated Credentials.

Introduction to Microsoft Graph API Authorization

After successful authentication, there are two steps, Authorization, and Consent.

  • Authorization / Permission: Two types of permission can be requested.:
    • Delegated: The permission is granted when a Delegate Authentication is used during the login process. If permitted, it grants access to the signed-in user’s data or the scope specified. However, an intersection of the effective permissions between the scope and user-assigned privilege is applied.
      For example, User1 is a non-administrative who has the User.ReadWrite.All. The User.ReadWrite.All allow User1 to read and update all the user profiles in the organization. But if User1 tries to update any user profile, it will fail as User1 lacks the necessary privileges to carry out such an operation. User1 can still update his/her account information only.
      However, if an administrator with the necessary Azure roles connects and attempts to update the user information while connected with the appropriate scope, this administrator will be able to update any user profile in the organization.
    • Application: The tenant admin should assign the application the required permission and consent. The permission provisioning is done through Azure Active Directory App Registration. Permission is assigned by adding them to the list of API Permissions.
      Application Authorization is used for background applications or services that don’t require user login. Unlike delegated permissions, effective permissions are the permissions granted by assigning the scope required to the application.
      For example, an application with User.ReadWrite.All have the power to update all the user profiles in the organization, there is no need to add this application to any AAD role.
  • Consents: The consent is Microsoft’s way of telling that this script/App uses these permissions and you agree to it. There are two types of consent:
    • Static User Consent: When using Delegated permission, the connected user will be prompted to consent and accept the permissions, much like when you install an app on your mobile device. You are notified that this application will use these permissions, and you must accept them.
    • Admin Consent: Used with Application Permission as the script needs to access data in all the tenants, so the administrator needs to add the permissions to the registered application, consent, and accept these permissions through the Azure Active Directory portal, App Registration

Looking for a deep dive, Check out Permissions and Consent in the Microsoft identity platform

How Limited Non-Administrative User Request For Scope Permission

If the Azure administrator enables the following setting, limited users can request access to a specific scope.

  • Azure Active Directory
  • Enterprise Application
  • User Setting
  • Under the Admin Consent requests –> Users can request admin consent to apps they are unable to consent to.

Assume a limited user attempts to connect and request the User.Readwrite.All. The User.ReadWrite.All are considered high permission, and limited users don’t have access to such endpoints. However, the user still gets a message while authentication requests to type a justification for this request.

Justify your request

The Azure admin needs to approve this request from the Enterprise Application –> Admin Consent Requests.

But if the Azure admin did not enable the Admin Consent requests –> Users can request admin consent to apps they are unable to consent to. The connecting user gets the following message.

Needs permission to access resources in your organization that only an admin can grant. Please ask an admin to grant permission to this app before you can use it.

Need admin approval

You can read more about how to connect using Application Registration by reading Connect to Microsoft Graph PowerShell Using an App Registration.

Finding Microsoft Graph Scope and Permissions.

The key to successful execution is determining the appropriate scope. Otherwise, the script will not run. There are several ways to obtain this information:

Microsoft Graph SDK PowerShell Module has cmdlets Find-MgGraphCommand and Find-MgGraphPermissions which helps in finding the available permissions for an operation.

Using Find-MgGraphPermissions

The Find-MgGraphPermissions cmdlet helps find the related permission for a given domain, such as a User domain or an application.

The examples below list all available permissions for the User domain. It contains the Name as well as the Description.

The best permission to use the User.Read.All. If you need to update the user information, then you can use the User.ReadWrite.All

PS C:\> Find-MgGraphPermission user  -PermissionType Delegated | Select-Object Name, Description

Name                                      Description
----                                      -----------
.
.
User.Export.All                           Allows the app to export data (e.g. customer content or system-generated logs), associated with any user in your company, when the app is used by a privileged user (e.g. a Company Administrator).
User.Invite.All                           Allows the app to invite guest users to the organization, on behalf of the signed-in user.
User.ManageIdentities.All                 Allows the app to read, update and delete identities that are associated with a user's account that the signed-in user has access to. This controls the identities users can sign-in with.
User.Read                                 Allows you to sign in to the app with your organizational account and let the app read your profile. It also allows the app to read basic company information.
User.Read.All                             Allows the app to read the full set of profile properties, reports, and managers of other users in your organization, on behalf of the signed-in user.
User.ReadBasic.All                        Allows the app to read a basic set of profile properties of other users in your organization on your behalf. Includes display name, first and last name, email address and photo.
User.ReadWrite                            Allows the app to read your profile, and discover your group membership, reports and manager. It also allows the app to update your profile information on your behalf.
User.ReadWrite.All                        Allows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on behalf of the signed-in user.
.

Output trimmed to shorten the result.

This helps in finding the permission scope required to do a particular operation. But now we need to know what cmdlet to act.

Using Find-MgGraphCommand

The Find-MgGraphCommand cmdlet helps find the command to perform an operation and list the available usable permission to run the commands.

Find-MgGraphCommand uses -URI parameter which helps find all the related cmdlets for a specific API endpoint. As an example. we need to find the cmdlets in the Users API.

The Microsoft Graph REST API v1.0 reference is an easy way also to find all the information about the scopes, permission and command

C:> Find-MgGraphCommand -Uri "/users/{id}" -ApiVersion v1.0 | Format-list Command,Permissions

Command     : Get-MgUser
Permissions : {DeviceManagementApps.Read.All, DeviceManagementApps.ReadWrite.All, DeviceManagementManagedDevices.Read.All, DeviceManagementManagedDevices.ReadWrite.All…}

Command     : Remove-MgUser
Permissions : {DeviceManagementApps.ReadWrite.All, DeviceManagementManagedDevices.ReadWrite.All, DeviceManagementServiceConfig.ReadWrite.All, User.ReadWrite.All}

Command     : Update-MgUser
Permissions : {DeviceManagementApps.ReadWrite.All, DeviceManagementManagedDevices.ReadWrite.All, DeviceManagementServiceConfig.ReadWrite.All, Directory.AccessAsUser.All…}

The URI parameter value looks like the following “/Resource/{id}” as in “/users/{id}” just make sure to add the {id} at the end, and you get all the cmdlets related to the resource required.

There is no value for the {id}, you don’t need to replace the {id} with any value, just type it as it is, {id}

The following example lists all the available permission to run Get-MgUser. The Get-MgUser gets all users in the tenant.

Open PowerShell and type the following line.

Find-MgGraphCommand -Command Get-MgUser | Select-Object command,Permissions

Did you notice the Permission column? Use the following cmdlet to get the permissions.

PowerShell lists the Get-MgUsercmdlet available in both the current version and the beta version.

PS C:\> Find-MgGraphCommand -Command Get-MgUser | Select-Object command,Permissions

Command    Permissions
-------    -----------
Get-MgUser {DeviceManagementApps.Read.All, DeviceManagementApps.ReadWrite.All, DeviceManagementManagedDevices.Read.All…
Get-MgUser {DeviceManagementApps.Read.All, DeviceManagementApps.ReadWrite.All, DeviceManagementManagedDevices.Read.All…
Get-MgUser {DeviceManagementApps.Read.All, DeviceManagementApps.ReadWrite.All, DeviceManagementManagedDevices.Read.All…
Get-MgUser {DeviceManagementApps.Read.All, DeviceManagementApps.ReadWrite.All, DeviceManagementManagedDevices.Read.All…

Let’s narrow it down, exclude the beta, and expand the permissions to list all the available permissions that can be used to run Get-MgUser successfully.

PS C:\> Find-MgGraphCommand -Command Get-MgUser | Select-Object -First 1 -ExpandProperty Permissions

Name                                         IsAdmin Description                                   FullDescription
----                                         ------- -----------                                   ---------------
DeviceManagementApps.Read.All                True    Read Microsoft Intune apps                    Allows the app to read the properties, group assignments and status of apps, app configurations and app protection policies managed by Microsoft Intune.
DeviceManagementApps.ReadWrite.All           True    Read and write Microsoft Intune apps          Allows the app to read and write the properties, group assignments and status of apps, app configurations and app protection policies managed by Microsoft Intune.
DeviceManagementManagedDevices.Read.All      True    Read devices Microsoft Intune devices         Allows the app to read the properties of devices managed by Microsoft Intune.
DeviceManagementManagedDevices.ReadWrite.All True    Read and write Microsoft Intune devices       Allows the app to read and write the properties of devices managed by Microsoft Intune. Does not allow high impact operations such as remote wipe and password reset on the device’s owner.
DeviceManagementServiceConfig.Read.All       True    Read Microsoft Intune configuration           Allows the app to read Microsoft Intune service properties including device enrollment and third party service connection configuration.
DeviceManagementServiceConfig.ReadWrite.All  True    Read and write Microsoft Intune configuration Allows the app to read and write Microsoft Intune service properties including device enrollment and third party service connection configuration.
Directory.AccessAsUser.All                   True    Access the directory as you                   Allows the app to have the same access to information in your work or school directory as you do.
Directory.Read.All                           True    Read directory data                           Allows the app to read data in your organization's directory.
Directory.ReadWrite.All                      True    Read and write directory data                 Allows the app to read and write data in your organization's directory, such as other users, groups.  It does not allow the app to delete users or groups, or reset user passwords.
User.Read.All                                True    Read all users' full profiles                 Allows the app to read the full set of profile properties, reports, and managers of other users in your organization, on your behalf.
User.ReadBasic.All                           False   Read all users' basic profiles                Allows the app to read a basic set of profile properties of other users in your organization on your behalf. Includes display name, first and last name, email address and photo.
User.ReadWrite.All                           True    Read and write all users' full profiles       Allows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on your behalf.

Microsoft Graph Rest API

Another easy option is to go straight to Microsoft Documentation. This document includes a lot of information with examples of each permission and how to use it. All permissions are categorized based on resources.

Microsoft Graph Docs
Microsoft Graph Docs

If this is your first time reading about using Microsoft Graph SDK PowerShell Module, then it’s okay to feel a bit lost. Practice is the key. Lets’s put it together and clear the confusion by trying examples.

Using Azure Active Directory to find Microsoft Graph Permission Easily

You can use Azure Active Directory to find all the permissions and scope related to any resource in your organization, plus you can easily filter the scope based on what you want to do, like get all the scope with Read scope.

Open Azure Active Directory, open Enterprise Applications, click on Consent and permissions, and then on Permission Classifications. Click on Add Permission button.

Permission Classifications

Select Microsoft Graph and a list of all the available resources with their related permission displayed.

Showing only Read scope

Don’t add any permission, I am just showing how to find the scope for the related resources.

Putting it all together – Example

In the following scenario, we need to get a user named AzureUser and read the user property such as Department and manager.

Start by opening PowerShell 7 and import the Microsoft Graph PowerShell Module by using.

Import-module Microsoft.Graph

Now the next step is finding the required cmdlet. Based on the requirement, we need to find the cmdlet which reads users’ information.

By Find-MgGraphCommand we can pass the -URI Parameter and passes the value ‘/users/{id}’.

C:> Find-MgGraphCommand -Uri '/users/{id}' -ApiVersion v1.0 | fl Command,Permissions

Command     : Get-MgUser
Permissions : {DeviceManagementApps.Read.All, DeviceManagementApps.ReadWrite.All, DeviceManagementManagedDevices.Read.All, DeviceManagementManagedDevices.ReadWrite.All…}

Command     : Remove-MgUser
Permissions : {DeviceManagementApps.ReadWrite.All, DeviceManagementManagedDevices.ReadWrite.All, DeviceManagementServiceConfig.ReadWrite.All, User.ReadWrite.All}

Command     : Update-MgUser
Permissions : {DeviceManagementApps.ReadWrite.All, DeviceManagementManagedDevices.ReadWrite.All, DeviceManagementServiceConfig.ReadWrite.All, Directory.AccessAsUser.All…}

As for now, we need to read user information, so let’s use the Get-MgUser, lets’s now check the required permission.

(Find-MgGraphCommand -Command Get-MgUser -ApiVersion v1.0 )[0] | select -ExpandProperty Permissions | select Name, Description
Getting the required permission
Getting the required permission

With a quick read, we need to use the User.Read.All. Let’s connect

PS C:\> Connect-Graph -Scopes User.Read.All
Welcome To Microsoft Graph!

PS C:\> Get-MgUser -UserId Azureuser@testdomain.com

Id                                   DisplayName Mail UserPrincipalName      UserType
--                                   ----------- ---- -----------------      --------
0a6d9460-cd81-4903-bb8d-e4964ed78083 Azure            AzureUser@testdomain.com

To select the Department use the Property parameter and type Department.

If you run this code without the Property parameter, you get a null result.

PS C:\> Get-MgUser -UserId AzureUser@testdomain.com | Format-List Department,Manager

Department :
Manager    : Microsoft.Graph.PowerShell.Models.MicrosoftGraphDirectoryObject

Make sure to use the Property parameter and specify the property you need to read. This is by design as the SDK mirrors how Microsoft Graph API works. The API does not return all properties by default.

PS C:\> Get-MgUser -UserId AzureUser@testdomain.com -Property Department,Manager| Format-List Department,Manager

Department : Test Department
Manager    : Microsoft.Graph.PowerShell.Models.MicrosoftGraphDirectoryObject

Now we get the Department, but I am sure that Microsoft.Graph.PowerShell.Models.MicrosoftGraphDirectoryObject is not the manager of the AzureUser user account.

You can retrieve the Manager name, we need to use -ExpandProperty parameter as the Manager value is a PowerShell object, and to see the full detail of this object, run the following line.

PS C:\> (Get-MgUser -UserId AzureUser@testdomain.com -ExpandProperty Manager).Manager.AdditionalProperties.displayName

Faris Malaeb

Note that the displayname in the Manager.AdditionalProperties.displayName is case sensitive, otherwise, you get an empty results

To get both Department and Manager properties, we need to format it using the following line

PS C:\> Get-MgUser -UserId AzureUser@testdomain.com -Property department -ExpandProperty Manager | select Department, @{N="Manager"; E={$_.Manager.AdditionalProperties.displayName}}

Department      Manager
----------      -------
Test Department Faris Bassam Malaeb

To update the Department property for this user, use the following line and see the results.

C:\> Update-MgUser -UserId AzureUser@testdomain.com -Department "My New Department"

Update-MgUser_UpdateExpanded: Insufficient privileges to complete the operation.

Update-MgUser_UpdateExpanded: Insufficient privileges to complete the operation

The Update-MgUser_UpdateExpanded: Insufficient privileges to complete the operation error is a common error ,and you might face it while working with MS graph API. Granting the user the ability to connect to an endpoint might not be enough.

If a user granted the scope to User.ReadWrite.All but this user is not assigned the proper role that gives the user the ability to update the user’s information; then the operation will fail.

To troubleshoot this issue, first, ensure the user is connected and has the required scope User.ReadWrite.All.

Connect-MgGraph -Scopes User.ReadWrite.All

Remember to use the (Get-MgContext).Scopes to see the available scope for the connected user or app

No need to close PowerShell or disconnect the active session. Using Connect-MgGraph with the new scope adds the required scope to the user. But the user needs to accept the new permission scope.

If the error is present and you cannot update the user information, then you need to assign the user the required roles. In this case, the User administrator role.

Here are the full results.

# Confirm the required scope User.ReadWrite.All
PS C:\Users> (Get-MgContext).Scopes
Group.Read.All
openid
profile
User.Read
User.Read.All
User.ReadWrite.All
email

#Before assigning the User Administrator AD role
PS C:\Users> Update-MgUser -UserId AzureUser@testdomain.com -Department 'My New Department'
Update-MgUser_UpdateExpanded: Insufficient privileges to complete the operation

#After assugning the User Administrator AD Role
PS C:\Users> Update-MgUser -UserId AzureUser@testdomain.com -Department 'My New Department'

#To Confirm
PS C:\Users> get-MgUser -UserId AzureUser@testdomain.com -Property Department | Select-Object Department

Department
----------
My New Department

Adding a user’s role might take a few minutes, so be patient. In my case, it took almost 30 minutes.

So it’s a cross between the Graph API scope and what role the user has. The effective permission is the least privilege permission, so even if the user has the User Administrator role and did not set the connection scope, the operation fails. So make sure to use both instead of wasting your time troubleshooting why the cmdlet is not working.

Conclusion

Microsoft Graph SDK is the direction. It came with a new authentication and authorization way, which needs more attention. This might be confusing, but think about how this secures your scripts and the users as the user needs to accept and consent to each permission and limit unwanted access.

4.6/5 - (9 votes)