Microsoft Graph PowerShell
Microsoft.Graph is the module for Microsoft 365 and Entra ID. It replaces the retired AzureAD and MSOnline modules, and cmdlets from those no longer work.
Documentation: Microsoft Learn
Overview
Scopes are the thing to understand. Connect-MgGraph requests permissions, and you only get what you asked for. Connect without -Scopes and Get-MgUser fails with an authorization error even though your account has the rights, because the token does not carry the scope. Find-MgGraphCommand tells you which permissions a given cmdlet needs, which saves guessing.
Get-MgContext shows the scopes you currently hold. When a Graph command fails on permissions, that is the first thing to check, and reconnecting with the right scopes is usually the fix.
Property selection works differently from the AD module. Graph returns a default subset and -Property asks for more, but note that -Property on a Get-Mg cmdlet shapes the request to the API, so a property you did not request comes back null rather than absent. That looks like missing data.
Paging is real. Use -All or you get the first page, which is 100 objects, and no indication there are more.
For automation, app-only authentication with a certificate is the supported path. Grant application permissions with admin consent rather than reusing a person's account.
Inspect this example’s structure
Read the command and its supplied arguments. This example requires real PowerShell or its module; this diagram does not execute it.
[pscustomobject]@{
Connect = "Connect-MgGraph -Scopes 'User.Read.All','Group.Read.All'"
Check = 'Get-MgContext | Select-Object ClientId, Scopes, TenantId'
Query = 'Get-MgUser -All -Property DisplayName,UserPrincipalName,AccountEnabled'
Find = 'Find-MgGraphCommand -Command Get-MgUser | Select-Object -First 1 Permissions'
} | Format-List- Stage 1[pscustomobject]@{
Positional values or no named parameters - Stage 2Format-List
Positional values or no named parameters
What happens
This prints the four commands. The Connect line shows scopes being requested explicitly, which is the step people leave out. The Find line is the one that saves the most time: it tells you which scopes a cmdlet needs, so you can ask for them before hitting an authorization error.
Worth remembering
- Request scopes at connect time; your account rights are not enough on their own.
- Find-MgGraphCommand reports the permissions a cmdlet needs.
- AzureAD and MSOnline are retired.
- Use -All or you silently get only the first 100 objects.
Primary documentation
Try it
Illustrative output · values vary by environment
Example reader
Inspect this page's example
Run supported commands against the practice data, or inspect the example without executing it.
Ready to inspect.
Prints the Graph connect sequence including scope discovery.
Show reference output
Illustrative output · values vary by environment
Connect : Connect-MgGraph -Scopes 'User.Read.All','Group.Read.All' Check : Get-MgContext | Select-Object ClientId, Scopes, TenantId Query : Get-MgUser -All -Property DisplayName,UserPrincipalName,AccountEnabled Find : Find-MgGraphCommand -Command Get-MgUser | Select-Object -First 1 Permissions
Practise this
Connect and read tenant users
Connect to the fictional tenant first. Connect with User.Read.All and return fictional tenant users.
The sandbox is visible now. Sign in with Google only when you run or check a task; commands and temporary files are discarded when you leave.
Run a command to inspect its result.
Inspect starting data
Supported syntax
Virtual files
Keep going
Next: PowerShell Entra users and groupsCheck your understanding
A Graph query returns only part of a collection. What should you check?
Check paging and whether the cmdlet supports -All. Also confirm requested properties, granted permissions and the connected tenant.