Microsoft Graph PowerShell v2 is now in public preview, half the size and speeds up automation

Microsoft Graph team

Automate and manage your Microsoft 365 tenant by using the Microsoft Graph PowerShell SDK that brings the Microsoft Graph API to PowerShell. Focus on what really matters and build scripts to automate your work instead of worrying about throttling, retries, redirects, and authentication. The Microsoft Graph PowerShell SDK handles all of that and provides PowerShell cmdlets for all REST APIs available in Microsoft Graph.

Today, we are announcing the public preview of Microsoft Graph PowerShell SDK v2 that includes features to enhance your experience. Read on for details.

Write more robust, less error-prone, and less ambiguous scripts

To help you write more robust scripts, the v1.0 and beta modules will use different prefixes in their cmdlets.

Users should always rely on Microsoft Graph v1.0 when writing scripts. However, sometimes there is a need to use the beta endpoint for testing or early adoption before a feature is available in v1.0. The Microsoft Graph beta endpoint and any functionality there is still in preview status and can change. This makes the beta endpoints unreliable for production usage since it may break existing scenarios without notice. So, thinking of that, you will now be able to easily combine both production and preview in any script you might need, using v1.0 as much as possible and beta only where you truly need. Using prefixes will also help you identify where you are using preview functionalities.

Thus, the v1.0 module will continue to use the same naming as the current v1 version to avoid breaking changes for those running their script against Microsoft Graph v1.0.  Changes will only be observed for beta. Here is an example.

Microsoft Graph API v1.0 endpoint Microsoft Graph API Beta endpoint
Module Names Microsoft.Graph Microsoft.Graph.Beta
Command Names Get-MgUser Get-MgBetaUser
Entity Namespace Microsoft.Graph.PowerShell.Models.Users Microsoft.Graph.Beta.PowerShell.Models.Users


Consider a scenario where users were mixing v1.0 and beta commands, a situation where almost everything needed is available in Microsoft Graph v1 endpoint and only a couple of preview APIs that are only available in beta. With the Microsoft Graph PowerShell SDK v1, we had the following:

Select-MgProfile v1.0
$V1Users = Get-MgUser
Select-MgProfile beta
$BetaDriveActivity = Get-MgDriveActivity

As you can see above, it is quite easy to miss in the middle of a script that cmdlets are using Microsoft Graph beta APIs. With Microsoft Graph PowerShell v2, keeping in mind to have both modules installed, users can accomplish the same result with the following:

$V1Users = Get-MgUser
$BetaDriveActivity = Get-MgBetaDriveActivity


Speed up your automations

With the SDK now 58% smaller, you can choose the module which better suits your needs with the new Microsoft Graph PowerShell v2. The first option, Microsoft.Graph module that targets and it is the home for those who only want to work with stables APIs. The second one, Microsoft.Graph.Beta that targets, which is where you will hit APIs we are still working on and in preview.

You can optimize your scripts even further by installing only the specific modules your scripts will use rather than the entire SDK.

Install-Module Microsoft.Graph.Users
$V1Users = Get-MgUser

PowerShell users will have access to smaller packages that facilitate its management and significantly speed up installation of the SDK, benefiting, but not limited to, CI/CD pipelines and automation on Azure. The installation size of the SDK is reduced by up to 58% in case of using the module targeting Microsoft Graph v1 endpoint.

Version of Microsoft Graph PS SDK Package Size Install Size
Microsoft.Graph V1.19.0 147.57 MB 855.81 MB
Microsoft.Graph V2-preview 64.97 MB (-55.97%) 351.31 MB (-58.95%)
Microsoft.Graph.Beta V2-preview 112.72 MB (-23.63%) 651.31 MB (-23.89%)


New authentication methods for more scenarios

New authentication flows are available for you to decided which ones satisfy your demands.

1. Managed Identity

A common challenge when writing automation scripts is the management of secrets, credentials, certificates, and keys used to secure communication between services. Eliminate the need to manage credentials by allowing the module to obtain access tokens for Azure resources that are protected by Azure Active Directory. The identity is managed by the Azure platform and does not require you to provision or rotate any secrets. See Managed Identities from Azure resources for more details.

a. System-assigned managed identity

Uses an automatically managed identity on a service instance. The identity is tied to the lifecycle of a service instance.

Connect-MgGraph -Identity

b. User-assigned managed identity

Uses a user created managed identity as a standalone Azure resource.

Connect-MgGraph -Identity -ClientId "User_Assigned_Managed_identity_Client_Id"

2. Client Secret Credentials

If you need interactions in the background, without a user to sign in, this type of grant will help you. Support for client secret credentials was added by adding -ClientSecretCredential parameter to Connect-MgGraph. See Get-Credential on how to get or create credentials.

$ClientCredential = Get-Credential -Username "Client_Id"
# Or create a credential object that is identical to the object that Get-Credential returns without prompting the user. This method requires a plain text password, which might violate the security standards in some enterprises. l
# $ClientSecretCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ApplicationId, $SecuredPassword
# Enter client_secret in the password prompt.
Connect-MgGraph -TenantId "Tenant_Id" -ClientSecretCredential $ClientCredential

3. Environment Variables Based Auth

Environment variables store the parameter keys and values, which then serve as input to your script and can help to not leaky information when sharing them with others. Now use -EnvironmentVariable to Connect-MgGraph to support environment variable based auth. It is important to notice that an error will be thrown if username and password are used to authenticate as this is not supported by design and that client secret takes precedence over certificate, i.e., if values for a client secret and certificate are both present, the client secret will be used. See Azure.Identity Environment Variables for more details.

# Add environment variables to be used by Connect-MgGraph.
$Env:AZURE_CLIENT_ID = "application id of the client app"
$Env:AZURE_TENANT_ID = "Id of your tenant"
$Env:AZURE_CLIENT_SECRET = "secret of the client app"

# Tell Connect-MgGraph to use your environment variables.
Connect-MgGraph –EnvironmentVariable

4. Certificate Credentials

Having a certificate only in the current user certificate store is no longer a limitation if you are using Microsoft Graph PowerShell SDK v2; the support to lookup for certificates in both current user and local machine certificate store were added. Priority will be given certificates in current user store if two identical certificates are present in both places.

Connect-MgGraph -ClientId "Client_Id" -Tenant "Tenant" -CertificateThumbprint "Cert_Thumbprint"

Along with all the new ways of authentication, -ForceRefresh is no longer supported by the auth token credentials used in v2. Customers should instead use Disconnect-MgGraph to sign out of current context then call Connect-MgGraph to get a new access token. Also, to keep you even safer, we have changed -AccessToken from String to SecureString type.


Better performance

The HTTP/2 protocol focuses on improving performance and perceived latency by adding support for multiplexing, header compression, and server push. Users will now benefit from improved performance whenever HTTP/2 is available, and the SDK will gracefully fall back to HTTP/1.1 when HTTP/2 is not supported by the API


Unblock scenarios with the new success range code support

Situations where the API was returning a different status code than what was documented in the API will no longer impact users. With success status code range support (2xx), new scenarios were unblocked by allowing all 2xx responses be treated as successful requests, making possible to get information from the response body when its available to use further in the script.

Invoke-MgInstantiateApplicationTemplate -ApplicationTemplateId $applicationTemplateId -BodyParameter $params


DEBUG: ============================ HTTP RESPONSE ============================

Status Code:

Cache-Control                 : no-cache
Transfer-Encoding             : chunked
Location                      :
Vary                          : Accept-Encoding
Strict-Transport-Security     : max-age=31536000
request-id                    : request-id
client-request-id             : client-request-id
x-ms-ags-diagnostic           : {"ServerInfo":{"DataCenter":"Brazil South","Slice":"E","Ring":"3","ScaleUnit":"000","RoleInstance":"CP1PEPF00002F02"}}
OData-Version                 : 4.0
Date                          : Fri, 16 Dec 2022 19:22:27 GMT

  "@odata.context": "$metadata#microsoft.graph.applicationServicePrincipal",
  "application": {
    "id": "id",
    "appId": "app-id",
    "applicationTemplateId": "application-template-id",
    "createdDateTime": "2022-12-16T19:22:26Z",
    "deletedDateTime": null,
    "displayName": "Azure AD SAML Toolkit",
    "description": null,
    "groupMembershipClaims": null,
    "identifierUris": [],
    "isFallbackPublicClient": false,
  "servicePrincipal": {
    "id": "id",
    "deletedDateTime": null,
    "accountEnabled": true,
    "appId": "app-id",
    "applicationTemplateId": "application-template-id",
    "appDisplayName": "Azure AD SAML Toolkit",
    "alternativeNames": [],
    "appOwnerOrganizationId": "app-owner-organization-id",
    "displayName": "Azure AD SAML Toolkit",
    "servicePrincipalNames": [
    "servicePrincipalType": "Application",
    "tags": [
    "tokenEncryptionKeyId": null,
    "samlSingleSignOnSettings": null,
    "addIns": [],

NOTE: The response object shown here is shortened for readability.


Migration tool for scripts

A migration tool will be provided to help customers migrate their scripts from using Microsoft Graph PowerShell SDK v1 to v2. The tool will be available when v2 reaches general availability. Customers can contact us on GitHub and send any script they are willing to share to help us test and verify the tool.

Try out the new version today!

Try out the new version and let us know what you think on GitHub! For questions about the Microsoft Graph API, go to Microsoft Q&A.

Next steps

Check out to access a detailed document that outlines any breaking changes, fixes and will guide you through the migration that an SDK user might run while upgrading to v2 as well as provide examples for implementing the new features, helping you quickly take advantage of all the new capabilities.

Add the new SDK for Microsoft Graph v1.0 module to your project. You can have a side-by-side installation by running the following command in the Package Manager Console or replace the Microsoft Graph PowerShell SDK installed by removing -AllowClobber:

Install-Module Microsoft.Graph -AllowPrerelease -AllowClobber -Force

Or for Microsoft Graph beta module:

Install-Module Microsoft.Graph.Beta -AllowPrerelease -AllowClobber -Force

Get started with the Microsoft Graph API

Microsoft Graph is a single REST API that unifies data across many Microsoft services under one single endpoint. The API is a powerful tool for building applications that work with data from Microsoft 365 and other Microsoft services.

Learn about Microsoft Graph SDKs

The SDK includes a set of tools, libraries, and documentation that make it easy to get started building applications that take advantage of the rich data and insights available through Microsoft Graph API.

Start saving time and removing complexity in your code today. Sign up for the Microsoft 365 Developer Program to get a free Microsoft 365 developer subscription and start using PowerShell to connect to Microsoft Graph. We also recommend that you join our Microsoft 365 Platform community calls and events, and get involved with other developers who use Microsoft Graph and build solutions for Microsoft 365.

Here are some resources we have pulled together to help you get started.

  1. Explore our public documentation, where you can find how to install the SDK, authenticate, discover which API a cmdlet is calling and more.
  2. Walk through the learning module.
  3. Use the Microsoft Graph Explorer, a tool that lets you make requests and see responses against the Microsoft Graph, and which displays corresponding snippets to requests you make.
  4. Visit our Microsoft Graph Dev Center.

Thank you!

We would like to thank all the members of the community who have helped us make this release better by reporting issues in GitHub! Keep them coming!

Follow us on Twitter @Microsoft365Dev for the latest announcements and resources!


Discussion is closed. Login to edit/delete existing comments.

  • Ondrej Šebela 0

    When do you think final version will be released? We are now migrating (because of the azuread module depreciation) to the graph sdk, so it is desired to wait?

    • Maisa RissiMicrosoft employee 1

      We have plans to GA the Microsoft Graph PowerShell SDK v2 by the end of Feb/early March.

  • Grzegorz Wierzbicki 0

    With AccessToken now a secure string, how do I now connect using MSAL.PS wrapper module ?

    $AccessToken = Get-MsalToken -ClientId $PowerShellGraphAppID -TenantId $TenantId -UserCredential $creds -Scopes "User.ReadWrite.All"
    Connect-MgGraph -AccessToken $AccessToken.AccessToken
    Connect-MgGraph : Cannot bind parameter 'AccessToken'. Cannot convert the "eyJ....5bA" value of type "System.String" to type "System.Security.SecureString"
  • Denise Child 0

    When will SignInActivity be fixed to where we don’t need to use the Beta profile?
    This takes 3 hours to run for 1350 membes. Without signininfo it takes less than a minute to run with Microsoft Graph v2.

    Connect-MgGraph -Scopes AuditLog.Read.All, Organization.Read.All, User.Read.All
    Select-MgProfile beta

    $users = get-mguser -All

    $signininfo = @()

    #Loop for all users
    Foreach ($u in $users) {
    $signininfo += Get-MgUser -UserId $u.Id -Property employeeid,displayName,userPrincipalName,usertype,accountenabled,signInActivity,createdDateTime,Department,JobTitle| select-object employeeid,displayName,userPrincipalName,usertype,accountenabled,createdDateTime,Department,JobTitle,@{Name = ‘LastSignInDateTime’; Expression = {$_.SignInActivity.LastSignInDateTime}}

    $signininfo |Export-Csv -Path d:\downloads\AAD-Signininfo.csv -NoTypeInformation -Encoding UTF8

    • Andre Lennon 1

      You can just request signInActivity in your initial “users” request (this won’t work for every user property, but it seems to work for signInActivity)

      Connect-MgGraph -Scopes AuditLog.Read.All, Organization.Read.All, User.Read.All
      Select-MgProfile beta
      $users = Get-MgUser -All -Property employeeid, displayName, userPrincipalName, usertype, accountenabled, signInActivity, createdDateTime, Department, JobTitle
      $signininfo = $users | Select-Object employeeid, displayName, userPrincipalName, usertype, accountenabled, createdDateTime, Department, JobTitle, @{ Name = "LastSignInDateTime"; Expression = { $_.SignInActivity.LastSignInDateTime } } 
      $signininfo | Export-Csv -Path d:\downloads\AAD-Signininfo.csv -NoTypeInformation -Encoding UTF8
      • Denise Child 0

        Perfect! That took seconds to run. Thank you very much Andre.


Feedback usabilla icon