EASYENTRA Blog

News & Updates

Configure Microsoft Graph PowerShell for EasyEntra Delegation

EasyEntra Microsoft Graph PowerShell consent script

If you want to delegate administration of Microsoft 365 to non-Global-Admins, you need to delegate Admin or User Consent to Microsoft Graph PowerShell for the following scopes:

  • User.ReadWrite.All
  • Group.ReadWrite.All
  • Device.ReadWrite.All
  • Domain.Read.All
  • UserAuthenticationMethod.ReadWrite.All
  • Directory.AccessAsUser.All
  • offline_access

If you have not configured a user Consent for your own global admin account, you can set up Admin Consent by running the following command:

Connect-MgGraph -Scopes "User.ReadWrite.All Group.ReadWrite.All Device.ReadWrite.All UserAuthenticationMethod.ReadWrite.All Domain.Read.All Reports.Read.All AuditLog.Read.All Directory.AccessAsUser.All DeviceLocalCredential.Read.All BitLockerKey.Read.All Mail.ReadWrite.Shared offline_access"

This will open an Oauth2 authentication dialog where you must click “Consent on behalf of your organization”. This is also referred to as Admin Consent and will allow your non-global admins to use Microsoft Graph PowerShell (they still need proper Entra ID roles to manage resources):

EasyEntra v1.1.0 - MS Graph Consent

Configure Admin and User Consent With PowerShell

If your global admin account has already been granted Consent, you’ll not get the option to grant the Admin Consent (read this article to understand this authentication flaw).

In that case, you can run the below script to configure the necessary Microsoft Graph PowerShell Admin or User Consent.

The script preserves any existing Admin Consent already configured on Microsoft Graph PowerShell.

However, if you select option 3 (“Remove all Admin Consent from Microsoft Graph PowerShell”), then all Admin Consent is removed (User Consent is not modified).

You can also use the script to grant User Consent to individual users for improved security.

Remember that admin consent does not grant any resource permissions to users. You still need to delegate the proper Entra ID roles to your admins:

  • User Administrator role
  • Exchange Recipient Administrator role
  • Authentication Administrator (optional, required for MFA management)
  • Reports Reader (optional, required for report generation)
# This script creates admin consent to let Microsoft PowerShell Graph access Microsoft Graph.
# The consent includes Read/Write to Users, Groups, Devices, Authentication Methods, and Domain, read access to Reports and AuditLogs, allows DirectoryAccess as user, reading LAPS and BitLocker keys, read/write access to mailbox where user has permissions, and provides long lived refresh tokens.
# Feel free to modify the script but include the following line:
# EasyEntra - The Microsoft 365 Management Tool for Hybrid and Cloud-Only Environments: https://EasyEntra.com
# Feel free to publish the script (with any modifications) but link credits to the following page:
# https://easyentra.com/configure-microsoft-graph-powershell-for-easyentra-delegation/

$ErrorActionPreference = "Stop"
$Scopes = @(
    "User.ReadWrite.All"
    "Group.ReadWrite.All"
    "Device.ReadWrite.All"
    "UserAuthenticationMethod.ReadWrite.All"
    "Domain.Read.All"
    "Sites.Read.All"
    "Reports.Read.All"
    "AuditLog.Read.All"
    "Directory.AccessAsUser.All"
    "DeviceLocalCredential.Read.All"
    "BitLockerKey.Read.All"
    "Mail.ReadWrite.Shared"
    "Calendars.Read.Shared"
    "Contacts.Read.Shared"
    "RoleEligibilitySchedule.Read.Directory"
    "RoleAssignmentSchedule.ReadWrite.Directory"
    "offline_access"
)
$scope = $scopes -Join " "
$MSGraphPS_AppId = "14d82eec-204b-4c2f-b7e8-296a70dab67e"
$MSGraph_AppId = "00000003-0000-0000-c000-000000000000"
$MicrosoftPowerShellGraph_Id = $null
$Microsoftgraph_Id = $null


Function Show-Menu {
    Clear-Host
    Write-Host "EasyEntra uses the Microsoft Graph PowerShell API - the future of Microsoft 365 management."
    Write-Host "Before you can use the API, you must grant consent to let the API impersonate your identity when accessing Graph Resources."
    Write-Host 
    Write-Host "This script allows a Global Admin to configure an Admin or User Consent, enabling non-Global-Admins to call the API."
    Write-Host "The Admin/User Consent does not grant users any rights. It only enables the API to use users' existing rights."
    Write-Host
    Write-Host "If you already configured Microsoft Graph PowerShell Admin Consent, you can skip this step (press 'X')."
    Write-Host "If all EasyEntra users are Global Admins, you can skip this step (press 'X')."
    Write-Host
    Write-Host "Only Global Admin role holders will be able to use EasyEntra until the Admin Consent has been configured."
    Write-Host
    Write-Host "Consult the EasyEntra documentation for more information:"
    Write-Host "https://EasyEntra.com/configure-microsoft-graph-powershell-for-easyentra-delegation/"
    Write-Host
    Write-Host "==================================================================="
    Write-Host "=== Configure Admin/User Consent for Microsoft Graph PowerShell ==="
    Write-Host "==================================================================="
    Write-Host
    If (Check-MgContext) {
        Write-Host Connected to tenant: ((Get-MgDomain | Where-Object { $_.IsInitial -eq $true }).Id)
        Write-Host
    }
    Write-Host "C: Press 'C' to connect to Microsoft Graph PowerShell."
    If (Check-MgContext){
        Write-Host "                                        "
        Write-Host "1: Press '1' to configure Admin Consent."
        Write-Host "2: Press '2' to see the current Admin Consent configuration."
        Write-Host "3: Press '3' to remove all Admin Consent from Microsoft Graph PowerShell."
        Write-Host
        Write-Host "4: Press '4' to configure User Consent."
        Write-Host "5: Press '5' to see the current User Consent configuration."
        Write-Host "6: Press '6' to remove single User Consent from Microsoft Graph PowerShell."
        Write-Host
        Write-Host "7: Press '7' to view all consent configured for Microsoft Graph PowerShell."
    }
    Write-Host
    Write-Host "X: Press 'X' to exit."
    Write-Host
}

Function Write-Consent ($Principal) {
    Try {
        Write-Host
        $ScopeMod = $Scope
        $User = "Admin"
        $PrincipalID = $null
        If ($Principal -ne $null){
            $User = "User (" + $Principal + ")"
            $PrincipalID = (Get-MgUser -UserId $Principal -ErrorAction Stop).Id
        }
        $ExistingAdminConsent = Get-MgOauth2PermissionGrant -All | Where-Object { $_.clientId -eq $Script:MicrosoftPowerShellGraph_Id -and $_.PrincipalId -eq $PrincipalID } -ErrorAction Stop
        If ($ExistingAdminConsent -eq $null) {
            Write-Host "No existing $User Consent was found for Microsoft Graph PowerShell."
            Write-Host
            Write-Host "Configuring $User Consent for Microsoft Graph PowerShell."
            Write-Host
            If ($PrincipalID -eq $null){
                New-MgOAuth2PermissionGrant -ClientId $Script:MicrosoftPowerShellGraph_Id -ConsentType "AllPrincipals" -ResourceId $Script:MicrosoftGraph_Id -Scope $Scope -ErrorAction Stop
            }
            Else {
                New-MgOAuth2PermissionGrant -ClientId $Script:MicrosoftPowerShellGraph_Id -ConsentType "Principal" -PrincipalId $PrincipalID -ResourceId $Script:MicrosoftGraph_Id -Scope $Scope -ErrorAction Stop
            }
        }
        Else {
            Write-Host "Existing $User Consent was found for Microsoft Graph PowerShell:"
            Write-Host
            Write-Host ($ExistingAdminConsent.Scope.Replace(" ", "`n`r")) -ForegroundColor Yellow
            Write-Host
            Write-Host "Merging missing scopes to support EasyEntra administration."
            If ($ExistingAdminConsent.Scope.IndexOf("Domain.ReadWrite.All") -ge 0) {
                $ScopeMod = $ScopeMod.Replace("Domain.Read.All", "Domain.ReadWrite.All")
            }
            $NewScope = $ScopeMod.Split(" ") + ($ScopeMod.Split(" ") | Where-Object {$ExistingAdminConsent.Scope.Split(" ") -notcontains $_})
            If ($PrincipalID -eq $null){
                Update-MgOAuth2PermissionGrant -OAuth2PermissionGrantId $ExistingAdminConsent.Id -ClientId $Script:MicrosoftPowerShellGraph_Id -ConsentType "AllPrincipals" -ResourceId $Script:MicrosoftGraph_Id -Scope ($NewScope -Join " ") -ErrorAction Stop
            }
            Else {
                Update-MgOAuth2PermissionGrant -OAuth2PermissionGrantId $ExistingAdminConsent.Id -ClientId $Script:MicrosoftPowerShellGraph_Id -ConsentType "Principal" -PrincipalId $PrincipalID -ResourceId $Script:MicrosoftGraph_Id -Scope ($NewScope -Join " ") -ErrorAction Stop
            }
        }
        Write-Host
        Write-Host Configuration succeeded. -ForegroundColor Green
        Write-Host
        Write-Host "Please allow up to five minutes before the new configuration is visible."
    }
    Catch {
        Write-Host Configuration failed: $Error[0].Exception.Message -ForegroundColor Red
        If ($Error[0].Exception.Source -eq "Microsoft.Graph.Authentication") {
            Connect-ToGraph
        }
    }
    Write-Host
    Read-Host "Press Enter to continue"
}

Function Read-Consent ($Principal) {
    Try {
        Write-Host
        $User = "Admin"
        $PrincipalID = $null
        If ($Principal -ne $null){
            $User = "User (" + $Principal + ")"
            $PrincipalID = (Get-MgUser -UserId $Principal -ErrorAction Stop).Id
        }
        $ExistingAdminConsent = Get-MgOauth2PermissionGrant -All | Where-Object { $_.clientId -eq $Script:MicrosoftPowerShellGraph_Id -and $_.PrincipalId -eq $PrincipalID } -ErrorAction Stop
        If ($ExistingAdminConsent -eq $null) {
            Write-Host "No existing $User Consent was found for Microsoft Graph PowerShell."
        }
        Else {
            Write-Host Existing $User Consent for Microsoft Graph PowerShell:
            Write-Host
            Write-Host ($ExistingAdminConsent.Scope.Replace(" ", "`n`r")) -ForegroundColor Yellow
        }
        Write-Host
        Write-Host The following $User Consent is missing to support EasyEntra administration:
        Write-Host
        If ($ExistingAdminConsent -eq $null){
            $ExistingScope = ""
        }
        Else {
            $ExistingScope = $ExistingAdminConsent.Scope
        }
        If ($ExistingScope.IndexOf("Domain.ReadWrite.All") -ge 0) {
            $ExistingScope = $ExistingScope.Replace("Domain.ReadWrite.All", "Domain.Read.All")
        }
        $MissingScope = ($Scope.Split(" ") | Where-Object {$ExistingScope.Split(" ") -notcontains $_})
        If ($MissingScope -eq $null) {
            Write-Host All set up! -ForegroundColor Green
        }
        Else {
            Write-Host ($MissingScope -Join "`n") -ForegroundColor Yellow
        }
        Write-Host
        Write-Host "(Recent changes may take up to five minutes before they become visible.)"
    }
    Catch {
        Write-Host Failed to read configuration: $Error[0].Exception.Message -ForegroundColor Red
    }
    Write-Host
    Read-Host "Press Enter to continue"
}

Function Remove-Consent ($Principal) {
    Write-Host
    $User = "Admin"
    $PrincipalID = $null
    If ($Principal -ne $null){
        $User = "User (" + $Principal + ")"
        $PrincipalID = (Get-MgUser -UserId $Principal -ErrorAction Stop).Id
    }
    $ExistingAdminConsent = Get-MgOauth2PermissionGrant -All | Where-Object { $_.clientId -eq $Script:MicrosoftPowerShellGraph_Id -and $_.PrincipalId -eq $PrincipalID}
    If ($ExistingAdminConsent -eq $null) {
        Write-Host "No existing $User Consent was found for Microsoft Graph PowerShell."
        Write-Host
    }
    Else {
        Write-Host "Existing $User Consent was found for Microsoft Graph PowerShell:"
        Write-Host
        Write-Host ($ExistingAdminConsent.Scope.Replace(" ", "`n`r")) -ForegroundColor Yellow
        $ExistingAdminConsent | ForEach-Object { Remove-MgOauth2PermissionGrant -OAuth2PermissionGrantId $_.Id }
        Write-Host
        Write-Host "Removed all $User Consent from Microsoft Graph PowerShell."
    }
    Write-Host
    Read-Host "Press Enter to continue"
}

Function View-AllConsent {
    $PermGrants = Get-MgOauth2PermissionGrant -All | Where-Object { $_.clientId -eq $Script:MicrosoftPowerShellGraph_Id }
    $GrantList = @()
    ForEach ($PermGrant In $PermGrants) {
        $Grant = New-Object PSObject -Property @{
            User = If ($PermGrant.PrincipalId -ne $null) { (Get-MgUser -UserId $PermGrant.PrincipalId).UserPrincipalName } Else { "*** Admin_Consent ***" }
            Scope = $PermGrant.Scope.Trim()
        }
        $GrantList += $Grant
    }
    $GrantList | ft User,Scope -Wrap
    Write-Host
    Read-Host "Press Enter to continue"
}

Function Connect-ToGraph {
    Write-Host
    Write-Host "Connecting to Microsoft PowerShell Graph."
    Write-Host
    Write-Host "(If asked, you don't need to consent to the permissions requested on behalf of your organization during the login.)"
    Write-Host
    If ((Get-MgContext) -ne $null){
        Disconnect-MgGraph
    }
    Try{
        Connect-MgGraph -Scopes "DelegatedPermissionGrant.ReadWrite.All Directory.AccessAsUser.All Directory.ReadWrite.All"
        Write-Host
        Write-Host "Connected to Microsoft Graph PowerShell:"
        Get-MgContext
    }
    Catch {
        Write-Host Failed to connect to Microsoft Graph PowerShell: $Error[0].Exception.Message -ForegroundColor Red
    }
    Write-Host
    Read-Host "Press Enter to continue"
}

Function Check-MgContext {
    $Context = Get-MgContext
    If ($Context -eq $null){
        Return $false
    }
    Write-Host "Connecting...`r" -NoNewline 
    If ($Context.Scopes.IndexOf("DelegatedPermissionGrant.ReadWrite.All") -lt 0 -or $Context.Scopes.IndexOf("Directory.AccessAsUser.All") -lt 0 -or $Context.Scopes.IndexOf("Directory.ReadWrite.All") -lt 0){
        Return $false
    }
    If ($Script:MicrosoftPowerShellGraph_Id -eq $null -or $Script:Microsoftgraph_Id -eq $null) {
        $Script:MicrosoftPowerShellGraph_Id = (Get-MgServicePrincipal -All | Where-Object { $_.AppId -eq $Script:MSGraphPS_AppId}).Id
        $Script:Microsoftgraph_Id = (Get-MgServicePrincipal -All | Where-Object { $_.AppId -eq $Script:MSGraph_AppId}).Id
    }
    Return $true
}

Function GetUserID($PrincipalID){
    Try{
        $
    }
    Catch {
        Write-Host Failed to connect to Microsoft Graph PowerShell: $Error[0].Exception.Message -ForegroundColor Red
    }
}

$Exit = $false
While ($Exit -eq $false) {
    Show-Menu
    $selection = Read-Host "Enter your selection"
    switch ($selection) {
        'C' {
            Connect-ToGraph
        }
        '1' {
            Write-Consent
        }
        '2' {
            Read-Consent
        }
        '3' {
            Remove-Consent
        }
        '4' {
            Write-Consent (Read-Host "Enter user ID to grant consent to")
        }
        '5' {
            Read-Consent (Read-Host "Enter user ID to read consent for")
        }
        '6' {
            Remove-Consent (Read-Host "Enter user ID to remove consent from")
        }
        '7' {
            View-AllConsent
        }
        'X' {
            $Exit = $true
        }
    }
}

After running the script and connecting to your tenant you will have the following options:

EasyEntra uses the Microsoft Graph PowerShell SDK - the future of Microsoft 365 management.
Before you can use the SDK, you must grant consent to the SDK to call the Microsoft Graph on your behalf.

This script allows a Global Admin to configure an Admin or User Consent, enabling non-Global-Admins to call the SDK.
The Admin/User Consent does not grant users any rights. It only enables the SDK to use users' existing rights.

If you already configured Microsoft Graph PowerShell Admin Consent, you can skip this step (press 'X').
If all EasyEntra users are Global Admins, you can skip this step (press 'X').

Only Global Admin role holders will be able to use EasyEntra until the Admin Consent has been configured.

Consult the EasyEntra documentation for more information:
https://EasyEntra.com/configure-microsoft-graph-powershell-for-easyentra-delegation/

===================================================================
=== Configure Admin/User Consent for Microsoft Graph PowerShell ===
===================================================================

Connected to tenant: e365m.onmicrosoft.com

C: Press 'C' to connect to Microsoft Graph PowerShell.

1: Press '1' to configure Admin Consent.
2: Press '2' to see the current Admin Consent configuration.
3: Press '3' to remove all Admin Consent from Microsoft Graph PowerShell.

4: Press '4' to configure User Consent.
5: Press '5' to see the current User Consent configuration.
6: Press '6' to remove single User Consent from Microsoft Graph PowerShell.

7: Press '7' to view all consent configured for Microsoft Graph PowerShell.

X: Press 'X' to exit.

Enter your selection:

Select ‘1’ to set up Admin Consent to allow (all) non-Global-Admins to run EasyEntra.

Select ‘4’ to set up User Consent on a per-user basis to run EasyEntra.

Free 30-minute demo

try 30 days for free

GET EASYENTRA NEWS

Opt out at any time

“One of the best products I've used.”
Gary Shurland
Chief Information Officer, Mirick, United States
“This tool has been invaluable in streamlining our IT processes.”
Tyson Mckay
Chief Information Officer, Southwest Network, United States
“EasyEntra includes offboarding steps we’d never even thought of, like removing inbox rules.”
Jerry Jacobson
IT Operations Manager, MetalTek International, United States
“This product has been a miracle for our Help Desk. EasyEntra has completely transformed how we handle Microsoft 365 administration.”
Doug Sanders
Manager of Technical Customer Support, Junior Achievement USA, United States
“Your product is such a time saver. I love it!”
Scott Fehr
IT Infrastructure, MEC Aerial Work Platforms, United States
“It's a good product and saves us lots of time for these ongoing quick admin tasks.” 
Chris McFerran
Managing Director, CTech IT Solutions Ltd, United Kingdom
“The speed of creating a user is magic.” 
John Duncan
IT Administrator, MetalTek International, United States
“EasyEntra has significantly streamlined our workflow, simplifying everything. It feels almost like a revolution.”
Johan Sadelius
IT-chef, Arjeplog Kommun, Sweden
I greatly appreciate your assistance and willingness to enhance the already outstanding product.”
Michael I. Wilson
Executive Director of Information Technology, Archdiocese Of Washington, United States
“It's great not having to switch back and forth between the O365 admin center and the Teams admin center to assign groups. I am sold!”
Thomas Madden
Director Information Technology, AutoPayPlus, United States
“I would highly recommend organizations use the solution as it greatly simplifies various tasks.”
S. Roger Singh
Chief Technology Officer, Prasad & Company LLP, Canada
“EasyEntra is time-saving. Love the copy/paste for user/computer groups and the copy to new user.”
Damian Nita
Associate Network Administrator, Shenandoah Valley Westminster-Canterbury, United States
“EasyEntra has transformed our daily IT operations by simplifying user management, reducing errors, and enhancing overall efficiency.”
Henrik Nefling
IT- and Digitalization Manager, Animal Protection Denmark, Denmark