Microsoft Graph PowerShell: Graph as cmdlets, and the choice between bundle and scenario modules
Powershell SDK for Microsoft Graph
At a glance
- What is it?
- The Microsoft Graph PowerShell SDK is a set of PowerShell modules that wrap the Microsoft Graph API as cmdlets, published for both the v1.0 and beta endpoints and split by scenario so you can install only what you need. It suits administrators and engineers who script against a tenant, and the repository ships numbered sample scripts that walk through installation, connection and the common objects.
- Who is it for?
- Microsoft Graph PowerShell suits a Windows administrator or engineer who already lives in PowerShell and wants to script against a Microsoft 365 tenant, because the scenario modules keep the install small and the sample scripts give a working path from Install-Module to reading tenant information.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Graph endpoints surfaced as PowerShell cmdlets
The Microsoft Graph PowerShell SDK exists to make one thing easy: consuming Microsoft Graph resources directly from PowerShell scripts. The README describes it as a set of modules that let you interact with the Graph API using PowerShell commands, where the modules consist of commands that act as wrappers for the API, allowing you to access all the features and functionality of the API through PowerShell.
That last clause is the interesting one, because it sets an expectation. This is not a curated subset with nicer names. The command surface is meant to cover the API, and the value of the SDK is the ergonomics of PowerShell objects and pipelines over the breadth of the underlying service.
The implementation is C#, and the repository is generated rather than hand-written. The tree has an autorest.powershell file, an openApiDocs/ directory, a src/ directory, a build.proj file, a Repo.props file, a Dockerfile, a .azure-pipelines/ directory and a config/ directory. The presence of AutoRest configuration and generated OpenAPI documentation says the cmdlets are produced from the Graph service description, which is why a new Graph endpoint tends to show up in the SDK without anyone writing C# by hand.
The audience is the administrator and developer working against a Microsoft 365 tenant. The topic list on the repository names cmdlets, powershell-modules, powershell-sdk, graph, microsoft and devxeng, and the documentation links point at the Graph API overview and at the SDK's own overview on Microsoft Learn.
The other thing the SDK provides, and this is what makes it usable in scripts rather than only in a console, is authentication, in the separate Microsoft.Graph.Authentication module. Authentication is treated as its own module rather than being baked into every scenario module, so the dependency graph stays small and the sign-in behaviour can be handled once.
Bundle modules or scenario modules, and why the choice matters
The module list in the README is long, and the reason for that is one deliberate packaging decision.
The repository publishes complete bundle modules, the authentication module, and scenario-specific modules for the Microsoft Graph v1.0 and beta endpoints. The bundles are Microsoft.Graph and Microsoft.Graph.Beta, and the README's guidance is explicit: for faster installation and import, prefer the scenario-specific modules you need instead of the complete Microsoft.Graph and Microsoft.Graph.Beta bundle modules. The bundle modules install all their respective scenario-specific modules as dependencies.
That is an unusual default in a vendor SDK, and it is worth understanding why it exists. A Graph cmdlet set is large. Installing the bundle pulls in every scenario, which means a large download, a long import, and a large set of commands to collide with in a session. A script that only needs to read users can install the users module and get a much faster start.
The scenario modules visible in the README's table cover the whole tenant surface, and the naming is systematic: Microsoft.Graph.Applications for application objects, Microsoft.Graph.Bookings, Microsoft.Graph.Calendar, Microsoft.Graph.ChangeNotifications, Microsoft.Graph.CloudCommunications, Microsoft.Graph.Compliance, Microsoft.Graph.CrossDeviceExperiences, Microsoft.Graph.DeviceManagement with its own Administration, Enrollment and Functions submodules, and Microsoft.Graph.Devices.CloudPrint and Microsoft.Graph.Devices.CorporateManagement. The table continues beyond the visible portion, but the pattern is clear, and it is one module per area of the API rather than one module per entity type.
Two separate version tracks run in parallel. The stable modules track the v1.0 endpoints and the Beta modules track the preview endpoints, and each scenario exists in both. That gives you a way to try a preview capability without taking the whole preview surface, and to pin production scripts to the stable set.
The practical recommendation is to install the authentication module plus the two or three scenario modules your script actually touches, and to resist the bundle until you know you need it.
A numbered sample script path from install to tenant data
The repository ships a samples/ directory with numbered scripts, and the numbering is the walkthrough. The files run samples/0-InstallModule.ps1, samples/1-FindCommands.ps1, samples/2-ConnectToGraph.ps1 and samples/3-TenantInformation.ps1, then samples/4-UsersAndGroups.ps1, samples/5-Teams.ps1, samples/6-Sites.ps1, samples/7-Drives.ps1, samples/8-ConditionalAccess.ps1, samples/9-Applications.ps1 and samples/A-Mail.ps1.
Read in order, that sequence is a complete first session. Install the module, find the commands you need, connect to Graph, read tenant information, then work through the objects an administrator touches most: users and groups, Teams, SharePoint sites, drives, conditional access policies, application registrations, and finally mail.
The value of that ordering is that it puts the connection step in the third position rather than the last. A new user finds out about signing in before they start querying, and the first script after connecting reads tenant information, which is the cheapest way to confirm that the sign-in actually worked and that your token has the scope you think it has.
There is also a samples/Scripts/ directory alongside the numbered files, and the repository's docs/ directory holds the fuller documentation set, with the getting started documentation linked from the Dockerfile's label. The README also links an API version section and a notes section in its table of contents, along with troubleshooting and known issues sections, which tells you the project treats the sharp edges as part of the documentation rather than leaving them to be discovered.
For a team writing automation, these scripts are also a style reference. They show the intended shape of a Graph script in this SDK, including how the connection and the context are handled, which is usually where a hand-rolled script goes wrong.
The container image pins PowerShell and installs both module tracks
The Dockerfile at the repository root is more interesting than a typical build file, because it shows how the SDK is meant to run in a container and it documents its own security reasoning.
The base image is pinned rather than floating. The ARG at the top sets a default of lts-ubuntu-22.04 and the FROM line uses mcr.microsoft.com/powershell with that argument, and the comment above explains why: the PowerShell team rebuilds the date-stamped rolling tags with patched OS layers, so a scheduled rebuild picks up Ubuntu and PowerShell CVE fixes and produces a fresh digest, clearing the security scanner findings about a vulnerable registry reference. The build arg can be overridden with a specific tag.
The image installs the modules with pwsh, and the second argument sets the version, with the latest as the default:
ARG PS_BASE_TAG=lts-ubuntu-22.04
FROM mcr.microsoft.com/powershell:${PS_BASE_TAG}
ARG VERSION=latestThe install command itself handles both cases in one line, installing the stable module when the version is latest and adding a required version otherwise:
RUN pwsh -c "if ('${VERSION}' -eq 'latest') { Install-Module Microsoft.Graph -Scope CurrentUser -AllowClobber -Force} else { Install-Module Microsoft.Graph -Scope CurrentUser -AllowClobber -Force -RequiredVersion ${VERSION} }"The third run command creates the profile file if it does not exist and appends the authentication import to it, so that a container started with pwsh already has Connect-MgGraph available:
RUN pwsh -c "if (!(Test-Path -Path \$PROFILE)) { New-Item -ItemType File -Path \$PROFILE -Force } echo 'Import-Module Microsoft.Graph.Authentication' >> \$PROFILE"Two details in that command carry over to any environment you build. The modules are installed with Scope CurrentUser rather than AllUsers, which avoids writing to system module paths. And AllowClobber and Force are both set, so the install will overwrite an existing Microsoft.Graph and will not stop on a command name that already exists. That is convenient in a container and worth remembering when you run the same command on a workstation where a module you installed deliberately could be replaced.
A custom licence, a v1.0 and beta split, and release cadence
Three administrative facts belong together, because they are what a platform team actually has to plan for.
The first is the licence. The licence field on the repository says Other, a custom licence GitHub cannot classify, and the tree holds LICENSE.txt. The README's table of contents includes a license section, and the repository also has a SECURITY.md and a CODE_OF_CONDUCT.md. This is a Microsoft-owned repository, and the terms are not one of the standard open source grants. The practical consequence is that a redistribution or embedding decision needs a reading of LICENSE.txt rather than an assumption. This review does not interpret the terms.
The second is the version split. Every scenario exists in a stable module for the v1.0 endpoints and a beta module for the preview endpoints, and the bundles come in the same pair. Beta modules are where new Graph capabilities appear first, and they can change in ways the stable modules do not. For automation that runs unattended, the stable modules are the sensible default, and the beta ones are for exploration.
The third is the release cadence. The recent tags are v2.41.1 from 2026-10-07, v2.41.0 from 2026-09-30 and v2.40.0 from 2026-09-16, so the project ships minor releases every couple of weeks and patch releases within them. The repository is not archived and the last push was on 2026-10-19, on the main branch.
A cadence that fast has a consequence for automation. Because the cmdlets are generated from the Graph service description, a Graph change can surface in a new SDK version without a change in your code, and pinning is how you avoid surprises. The Dockerfile's VERSION argument exists for exactly this, letting an image be built against a specific module version rather than the latest. Applying the same discipline to a workstation or a build agent is the obvious move, and the version numbers in the module table are the thing to record.
The repository also has a .gitmodules file, a scripts/ directory, a tools/ directory, a samples/ directory and an openApiDocs/ directory, which is consistent with a generated SDK with a build pipeline of its own.
Editorial conclusion
Microsoft Graph PowerShell suits a Windows administrator or engineer who already lives in PowerShell and wants to script against a Microsoft 365 tenant, because the scenario modules keep the install small and the sample scripts give a working path from Install-Module to reading tenant information. It is the wrong choice for a team that is not standardised on PowerShell, since the SDK exists only as PowerShell modules, and it is the wrong choice for automation that must run without a signed-in user, because the module set is built around Connect and Get-MgContext. Before you adopt it, read LICENSE.txt in the repository root, because the licence field on the repository is a custom one rather than a standard open source grant, and check which beta endpoints your automation depends on, since the beta modules change with every Graph release.
Frequently asked questions
Should I install the Microsoft.Graph bundle module or a scenario module?
The README recommends the scenario-specific modules you need instead of the complete Microsoft.Graph and Microsoft.Graph.Beta bundles, for faster installation and import, and notes that the bundle modules install all their respective scenario-specific modules as dependencies.
What is the difference between Microsoft.Graph and Microsoft.Graph.Beta?
The repository publishes scenario-specific modules for both the Microsoft Graph v1.0 and beta endpoints, so the stable modules track v1.0 and the Beta modules track the preview endpoints. Each scenario exists in both tracks.
How do I get started with the Microsoft Graph PowerShell SDK?
The repository ships numbered sample scripts that walk through the path: samples/0-InstallModule.ps1, samples/1-FindCommands.ps1, samples/2-ConnectToGraph.ps1, samples/3-TenantInformation.ps1, and then scripts for users and groups, Teams, sites, drives, conditional access, applications and mail.
Can I install a specific version of the Graph modules in a container?
Yes. The repository's Dockerfile takes a VERSION build argument, and the install command adds -RequiredVersion when the version is not latest, while the base image is pinned through the PS_BASE_TAG argument defaulting to lts-ubuntu-22.04.
What licence does the Microsoft Graph PowerShell SDK use?
The licence field on the repository says Other, a custom licence GitHub cannot classify, and the tree contains LICENSE.txt. The repository also ships SECURITY.md and CODE_OF_CONDUCT.md.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/microsoftgraph-msgraph-sdk-powershell)Was this useful?