The Microsoft Graph PowerShell SDK
By Emil Björk · Microsoft ecosystem consultant, Gothenburg
Microsoft Graph PowerShell is the modern way to script Microsoft 365 administration. Here's the basics.
4 min read
Share as imagePNGFor years, Microsoft 365 administrators had separate PowerShell modules for each service: AzureAD, MSOnline, ExchangeOnlineManagement, MicrosoftTeams, Microsoft.Online.SharePoint.PowerShell, PnP.PowerShell. Some still exist, but the strategic direction is the unified Microsoft Graph PowerShell SDK — a single set of cmdlets that talk to the Graph API.
Why Graph PowerShell
- Single module covers most of what the older per-service modules did.
- Cross-platform — runs on Windows PowerShell, PowerShell 7 on Mac and Linux.
- Modern authentication — supports interactive sign-in, certificate-based auth, managed identity, and client credentials without extra plumbing.
- Aligns with the Graph API — what you can do in the cmdlets matches what you can do via REST.
- Active investment — older modules (
AzureAD,MSOnline) are deprecated or in maintenance.
Getting started
Install-Module Microsoft.Graph -Scope CurrentUser
Connect-MgGraph -Scopes "User.Read.All","Group.Read.All"
Get-MgUser -Top 10
Get-MgGroup -Filter "displayName eq 'Marketing'"
Disconnect-MgGraph
Sign-in uses your normal Microsoft 365 admin account with MFA. The first time you sign in for a given scope, the SDK prompts for consent.
Cmdlet shape
Cmdlets follow a <Verb>-Mg<Noun> pattern:
Get-MgUser,New-MgUser,Update-MgUser,Remove-MgUser.Get-MgGroup,Add-MgGroupMember,Remove-MgGroupMember.Get-MgUserMessage,Send-MgUserMail.Get-MgDeviceManagementManagedDevice(Intune).
Sub-modules let you install only what you need: Microsoft.Graph.Users, Microsoft.Graph.Groups, Microsoft.Graph.Mail, Microsoft.Graph.Identity.SignIns — useful for keeping the install footprint small.
Service-specific modules that still matter
A few modules remain non-Graph for now:
- ExchangeOnlineManagement — still the right module for Exchange-specific work (mail flow rules, mailbox settings, retention).
- MicrosoftTeams — Teams-specific configuration that hasn't fully landed in Graph yet.
- PnP.PowerShell — community/Microsoft-supported, great for SharePoint deep work.
Graph PowerShell handles the broad cases; reach for the others for service-specific deep configuration.
Production patterns
- Use certificate-based authentication for unattended scripts. App registration in Entra ID + certificate + appropriate Graph permissions.
- Use managed identities when the script runs on Azure compute (VM, Function, Logic App).
- Audit script identities — service principals with Graph permissions show up in your enterprise apps list. Review them like any other app.
- Avoid running scripts as a Global Admin user — that's a Conditional Access mess waiting to happen.
The transition from old modules to Graph PowerShell is well underway. New automation should start there; existing scripts should be migrated over time as their owners touch them.
Permissions and consent, in practice
Every Graph PowerShell call runs under whatever delegated or application permissions were consented to for the session — Connect-MgGraph -Scopes requests delegated permissions matching the signed-in user's own rights (an interactive Get-MgUser call still respects the caller's actual read access), while unattended scripts using an app registration with application permissions and a certificate act with the registration's own granted scopes regardless of who (if anyone) is signed in. Requesting broader scopes than a script actually needs is a common and avoidable risk — User.ReadWrite.All when a script only ever reads users, for instance — since Graph PowerShell doesn't narrow what's granted at consent time to what a specific script call uses; the admin consenting the app registration is the only checkpoint, so scoping the request precisely at that point matters more than it might for older, more narrowly-scoped modules.
Frequently asked questions
Can Graph PowerShell replace the Exchange Online, Teams, and SharePoint modules entirely? Not yet, and not on a fixed date — Microsoft continues migrating capability into Graph over time, but several deep, service-specific operations (granular mail-flow rule configuration, Teams policy assignment, SharePoint site-collection administration) still require their dedicated modules. The practical approach is Graph PowerShell as the default for identity, groups, and cross-service scripting, falling back to the service-specific module only for the operations Graph genuinely doesn't cover yet.
Why does installing the full Microsoft.Graph module feel slow compared to the old AzureAD module? The full module ships as many sub-modules covering the entire Graph API surface, and importing all of them at once genuinely does take longer than a single-purpose legacy module; installing and importing only the specific sub-modules a script needs (Microsoft.Graph.Users, Microsoft.Graph.Groups, and so on, rather than the umbrella Microsoft.Graph package) is the standard fix and noticeably improves both install and session start time.
Is the older AzureAD module still safe to use for new scripts? No — AzureAD and MSOnline are deprecated, meaning they no longer receive feature updates and are on a retirement path; any new automation should start on Microsoft Graph PowerShell, and existing scripts on the old modules should be migrated opportunistically rather than left to break unannounced when the deprecated modules are eventually withdrawn.
Was this useful?
Spot something wrong or want a topic covered? Send it through the contact form.