In this post I want to summarize some basics you need to know to use the Microsoft Graph PowerShell to manage your Microsoft Entra ID tenant (formerly Azure Active Directory or Azure AD).

Microsoft Graph PowerShell is the replacement for the Azure AD PowerShell and MSOnline modules and is recommended for interacting with Microsoft Entra ID.





Introduction

The Microsoft Graph PowerShell SDK acts as an API wrapper for the Microsoft Graph APIs, exposing the entire API set for use in PowerShell. It contains a set of cmdlets that helps you manage identities at scale from automating tasks to managing users in bulk using Azure Active Directory (Azure AD). It will help administer every Azure AD feature that has an API in Microsoft Graph.

The commands in Microsoft Graph PowerShell are autogenerated from the Microsoft Graph API schema making it easier to get faster updates and functionality. The cmdlet reference content is also autogenerated from the API reference.

Microsoft Graph PowerShell is the replacement for the Azure AD PowerShell and MSOnline modules and is recommended for interacting with Azure AD.

To understand how to migrate from Azure AD PowerShell to Microsoft Graph PowerShell, follow the migration guide.

Supports PowerShell 7: Microsoft Graph PowerShell works with PowerShell 7 and later. It’s also compatible with Windows PowerShell 5.1.


Source: https://learn.microsoft.com/en-us/powershell/microsoftgraph/overview





Install the Microsoft Graph PowerShell SDK

Install-Module Microsoft.Graph -Scope AllUsers

# to verify the installation you can use the following cmdlet
Get-InstalledModule Microsoft.Graph


To verify installed sub-modules and their versions, run:

Get-InstalledModule


To update the SDK run:

Update-Module Microsoft.Graph


To uninstall the SDK run:

Uninstall-Module Microsoft.Graph -AllVersions


Source: https://learn.microsoft.com/en-us/powershell/microsoftgraph/installation





Microsoft Graph permissions

Before the Microsoft identity platform can authorize your application (here the Microsoft Graph PowerShell SDK) to access data in the Microsoft cloud, the application must be granted the privileges that it needs.

In case no user in the tenant ever used the Microsoft Graph PowerShell SDK to sign-in and consent to the Microsoft Graph, there will be no application provisioned in Enterprise applications of your tenant as shown below.


When now a user sign-in to the Microsoft Graph by using the Microsoft Graph PowerShell SDK, the user will get prompted to consent to allow the Microsoft Graph Command Line Tools (app) accessing organization data.

Consent is the process of a user granting authorization to an application to access protected resources on their behalf. An admin or user can be asked for consent to allow access to their organization/individual data.

Here below because my user is a global administrator I also have the option to Consent on behalf of my organization which is an admin consent.

By default, granting tenant-wide admin consent to an application allows all users to access the application unless otherwise restricted.

Granting admin consent on behalf of an organization is a sensitive operation, potentially allowing the application’s publisher access to significant portions of your organization’s data, or the permission to do highly privileged operations. Examples of such operations might be role management, full access to all mailboxes or all sites, and full user impersonation. Carefully review the permissions that the application is requesting before you grant consent.


After consent to the requested permissions by the application (Microsoft Graph Command Line Tools), the command line tool is connected and signed in to the Microsoft Graph.


After the consent, the application will be provisioned in your Azure tenant.



You can review the permissions granted to your application by clicking on Permissions in the left menu as shown below.


In case just non-global administrators were consenting to the application, you will see these permissions in the User consent tab as shown below.

A global administrator can here directly grant admin consent.


Under Microsoft Entra ID -> Enterprise applications -> Consent and permissions you can configure the user consent settings for your tenant.




Microsoft Graph supports two access scenariosdelegated access and app-only access. In delegated access, the app calls Microsoft Graph on behalf of a signed-in user. In app-only access, the app calls Microsoft Graph with its own identity, without a signed in user.

To support these access scenarios, Microsoft Graph exposes delegated permissions and application permissions.

Source: https://learn.microsoft.com/en-us/graph/permissions-overview




Delegated permissions

Delegated permissions, also called scopes, are used in the delegated access scenario. They’re permissions that allow the application to act on behalf of a signed-in user.

When you sign-in to the Microsoft Graph using the Microsoft Graph PowerShell SDK you need to specify these scopes (delegated permissions) as shown below in the Sign in section.

In the following article you will see a permissions reference showing and explainig all permissions you can specify as scopes when you sign-in to the Microsoft Graph.

Microsoft Graph permissions reference
https://learn.microsoft.com/en-us/graph/permissions-reference


For example, an application has been granted the Files.Read.All delegated permission on behalf of Tom, a user. The application will only be able to read all files in the organization that Tom can already access.

Source: https://learn.microsoft.com/en-us/graph/permissions-overview?tabs=http#delegated-permissions




Application permissions

Application permissions, also called app roles, are used in the app-only access scenario, without a signed-in user present. The application will be able to access any data that the permission is associated with. For example, an application granted the Files.Read.All application permission will be able to read any file in the organization.

Source: https://learn.microsoft.com/en-us/graph/permissions-overview?tabs=http#application-permissions




Sign in

Use the Connect-MgGraph command to sign in with the required scopes. You’ll need to sign in with an admin account to consent to the required scopes.

Connect-MgGraph

# connect to a specific tenant
Connect-MgGraph -TenantId “<your tenant id>”

# connect and consent to specific permissions for the Microsoft Graph Command Line Tools app in Azure
Connect-MgGraph -Scopes “User.Read”,”User.ReadWrite.All”,”Group.ReadWrite.All”
Connect-MgGraph -TenantId “<your tenant id>” -Scopes “User.Read”,”User.ReadWrite.All”,”Group.ReadWrite.All”

All scopes (delegated permissions) you will find here https://learn.microsoft.com/en-us/graph/permissions-reference

Source: https://learn.microsoft.com/en-us/powershell/microsoftgraph/get-started?view=graph-powershell-1.0#authentication



You can add additional permissions by repeating the Connect-MgGraph command with the new permission scopes.

Using Find-MgGraphCommand to find required permissions
The Find-MgGraphCommand cmdlet can be used to discover the required permissions for another cmdlet
https://learn.microsoft.com/en-us/powershell/microsoftgraph/get-started?view=graph-powershell-1.0#using-find-mggraphcommand-to-find-required-permissions


More about authentication you will find in the following article.

Authentication module cmdlets in Microsoft Graph PowerShell
https://learn.microsoft.com/en-us/powershell/microsoftgraph/authentication-commands





Adding required permissions

Below I was running for example into an error because of insufficient privileges when executing the Get-MgDevice cmdlet, which will get the properties and relationships of a device object. The reason for is that I am so far only signed in to the Microsoft Graph API by using the scope (delegated permissions) for user and group objects.

Connect-MgGraph -Scopes “User.Read”,”User.ReadWrite.All”,”Group.ReadWrite.All”


In order to call all registered devices in my tenant, I have to sign-in with a different scope for devices.

You can add additional permissions by repeating the Connect-MgGraph command with the new permission scopes.

So the -Scopes flag is just needed to add permissions to the Microsoft Graph Command Line Tools application in Azure and is not needed always when connecting to the Microsoft Graph.


You can determine the required permissions for a specific cmdlet by running the following command:

Find-MgGraphCommand -Command Get-MgDevice | Select -First 1 -ExpandProperty Permissions

# adjust the -Command flag to your cmdlet you want to use


To retrieve all the scopes (delegated permissions) that you’ve already consented to, use the Get-MgContext command and expand the Scopes property using the -ExpandProperty parameter.

Get-MgContext | Select -ExpandProperty Scopes


So in order to be able to request device information by using the Get-MgDevice cmdlet, I will first have to add the following permissions when connecting to Microsoft Graph.

Connect-MgGraph -TenantId “<tenant id>” -Scopes “Device.Read.All”,”Group.ReadWrite.All”



Now I can run the Get-MgDevice cmdlet successfully.

Get-MgDevice -Top 5 | ft DisplayName,OperatingSystem,OperatingSystemVersion,ProfileType,RegistrationDateTime,TrustType,AccountEnabled

For more information on using this cmdlet, see Using Find-MgGraphCommand.




Sign out

Use the Disconnect-MgGraph command to sign out

Disconnect-MgGraph





Using Get-MgContext

Get-MgContext is used to retrieve the details about your current session.


To retrieve all the scopes that you’ve consented to, expand the Scopes property using the -ExpandProperty parameter.

Get-MgContext | Select -ExpandProperty Scopes






Call Microsoft Graph

Now that you’re signed in, you can start making calls to Microsoft Graph.

Some requests for Azure Active Directory resources require the use of advanced query capabilities. If you get a response indicating a bad request, unsupported query, or a response that includes unexpected results, including the $count query parameter and ConsistencyLevel header may allow the request to succeed. For details and examples, see Advanced query capabilities on Azure AD directory objects.




Get the signed-in user

Get-MgUser

This command outputs a listing of users in your Microsoft 365 organization.

You can use an OData filter to help locate the specific user you want. Run the following command, to list a specific user in your organization.

Get-MgUser -Filter “displayName eq ‘John Doe'”


List the user’s joined teams

Get-MgUserJoinedTeam -UserId 66f43bd9-6971-444c-a071-34e7059c9a35


To simplify the requests you can use a variable for the user object.

$user = Get-MgUser -Filter "displayName eq 'John Doe'"
Get-MgUserJoinedTeam -UserId $user.Id


Get-MgUser | fl will return all properties but not all values for

The Get-MgUser or Get-MgDevice cmdlets will not retrieve all properties by default. All of the object properties are returned but most of them are empty although available in Microsoft Entra ID.

In order to list all values you have to specify all properties you want to retrieve the value for.

So instead for example using the following command.

Get-MgUser -Filter “givenName eq ‘John'” | fl


You need to use

Get-MgUser -Filter “givenName eq ‘John'” -Property DisplayName, GivenName, Surname, UserPrincipalName, EmployeeHireDate | Format-List *



Get Devices

To get the properties and relationships of a device object you can run:

Get-MgDevice


Below I will request the first 5 devices from my tenant for example.

Get-MgDevice -Top 5 | ft DisplayName,OperatingSystem,OperatingSystemVersion,ProfileType,RegistrationDateTime,TrustType,AccountEnabled



Update the properties of a user object

You can update user properties by using the Update-MgUser cmdlet.

When running the command I was first getting the insufficient privileges to complete the operation error message as shown below. The reason for is as already mentioned that you first need to to add permissions to the Microsoft Graph Command Line Tools app in Azure.

Update-MgUser -UserId “939bfd52-c553-409b-b409-02e6f86aa7a4” -City “Stuttgart” -PostalCode “70599” -Department “IT” -PreferredLanguage “en-US”


So first I was checking which permissions the Update-MgUser cmdlet requires and then I was sign in again by using these permission scopes.

Connect-MgGraph -TenantId “5a144de6-9a54-4e8a-9680-b28aa0dbf52f” -Scopes “DeviceManagementApps.ReadWrite.All”,”DeviceManagementConfiguration.ReadWrite.All”,”DeviceManagementManagedDevices.ReadWrite.All”,”DeviceManagementServiceConfig.ReadWrite.All”,”Directory.ReadWrite.All”,”User.EnableDisableAccount.All”,”User.ManageIdentities.All”,”User.ReadWrite”,”User.ReadWrite.All”


Consent to the requested permissions.


From now on updating the properties for the user works.


Source: https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.users/update-mguser



Disable User Account

$User = Get-MgUser -Filter “displayName eq ‘Fred Nurk'”
Update-MgUser -UserId $User.Id -AccountEnabled:$false





Update the properties of a registered device

In order to update properties of a registered device, we can use the Update-MgDeviceByDeviceId command.

Update-MgDeviceByDeviceId -DeviceId “aaa2c13a-27de-4c10-abad-6339e572b839” -DisplayName “nb-matrix6-changed”


Source: https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.directorymanagement/update-mgdevicebydeviceid



Using Query Parameters

Microsoft Graph supports optional query parameters that you can use to specify and control the amount of data returned in a response. The support for the exact query parameters varies from one API operation to another, and depending on the API, can differ between the v1.0 and beta endpoints.

More you will find in the following article from Microsoft.

Use query parameters to customize responses
https://learn.microsoft.com/en-us/graph/query-parameters?tabs=powershell


Below I will show some examples how you can use them.

Get-MgDevice -Filter “startswith(displayName, ‘nb’)” | ft DisplayName,OperatingSystem,ProfileType,RegistrationDateTime,TrustType,AccountEnabled



Get-MgUser -Sort “displayName”



Get-MgUser -Filter “accountEnabled eq false” -Property AccountEnabled,DisplayName,Id,UserPrincipalName | ft AccountEnabled,DisplayName,Id,UserPrincipalName




Filter output

Specify which properties the request resp. output should include.

Get-MgDevice | ft DisplayName,OperatingSystem,OperatingSystemVersion,ProfileType,RegistrationDateTime,TrustType,AccountEnabled


Filter the output to show only the device where the display name is nb-matrix4

Get-MgDevice -Filter “DisplayName eq ‘nb-matrix4′” | ft DisplayName,OperatingSystem,OperatingSystemVersion,ProfileType,RegistrationDateTime,TrustType,AccountEnabled


Filter the output to show all devices where the display name is like the wildcard nb*

Get-MgDevice | Where-Object {$_.displayname -Like “nb*”} | ft DisplayName,OperatingSystem,OperatingSystemVersion,ProfileType,RegistrationDateTime,TrustType,AccountEnabled





Navigating the Microsoft Graph PowerShell SDK

The Microsoft Graph API is huge, and it’s growing all the time. Therefore, the number of commands in the Microsoft Graph PowerShell SDK is also large. Finding the right command for what you want to achieve can be challenging, especially if you’re not already familiar with Microsoft Graph. Let’s look at some ways to help find a particular command.


Command naming conventions

The commands in the SDK are generated directly from the REST API, so the names are influenced by the API. You don’t have to understand the details of the API to use the Microsoft Graph PowerShell SDK, but it helps to understand the naming convention.

PowerShell commands are named using a verb-noun pair, such as Get-Command or Update-List. Let’s start with the verb.

For basic REST operations, the verb is determined by the HTTP method used for the API.

HTTP methodCommand verbExample
GETGetGet-MgUser API reference
POSTNewNew-MgUserMessage API reference
PUTNewNew-MgTeam API reference
PATCHUpdateUpdate-MgUserEvent API reference
DELETERemoveRemove-MgDriveItem API reference


More about you will find in the following article from Microsoft.

Navigating the Microsoft Graph PowerShell SDK
https://learn.microsoft.com/en-us/powershell/microsoftgraph/navigating





Links

Microsoft Graph PowerShell documentation
https://learn.microsoft.com/en-us/powershell/microsoftgraph

Get started with the Microsoft Graph PowerShell SDK
https://learn.microsoft.com/en-us/powershell/microsoftgraph/get-started

Connect to Microsoft 365 with PowerShell
https://learn.microsoft.com/en-us/microsoft-365/enterprise/connect-to-microsoft-365-powershell

Navigating the Microsoft Graph PowerShell SDK
https://learn.microsoft.com/en-us/powershell/microsoftgraph/navigating