Migrating PowerShell Scripts from AzureAD to Microsoft.Graph


For a long time, the PowerShell modules AzureAD, AzureADPreview and still MSOnline became the standard for accessing Azure Active Directory and Microsoft 365. After June 2023, these modules and the underlying Azure AD Graph API will retire, so it’s time to migrate your scripts to Microsoft.Graph.

In this blog post, I will highlight how you can benefit from the modernization when using the Microsoft Graph PowerShell SDK.

Comparing the Old and New PowerShell Modules

The script samples in the following image summarize the difference between the old AzureAD-based and the new Microsoft.Graph-based PowerShell cmdlets:

Migrating PowerShell Scripts from AzureAD to Microsoft.Graph
Difference between AzureAD and Microsoft.Graph PowerShell cmdlets

In short, you need to replace all AzureAD cmdlets with the Mg equivalent. For example, Get-AzureADUser is transformed to Get-MgUser. With several commands of the new module, you can benefit from improved server-side filtering and property selection. In our brief example, we reduce the payload returned from the underlying API by applying the -Property parameter of the Get-MgUser cmdlet, while Get-AzureADUser returned many more properties from the server that we are actually not interested in. Thus, the new SDK can improve the performance of your scripts.

Besides, authentication is of one the key differences. When using the new module, we are leveraging OAuth 2.0-based authentication and we are dealing with the registration of an enterprise application in your Azure AD. First, we can differentiate between delegated and app-only authentication. Delegate auth means that you sign-in with an account, which holds appropriate permissions (e.g. Azure AD admin roles) to execute the script logic. App-only auth means that you connect as a daemon and you have assigned particular permissions to the app identity itself to run the script commands (see below). Second, running Connect-MgGraph will either register a predefined “Microsoft Graph PowerShell” app in your tenant. Alternatively, I recommend to configure an own app registration to isolate different script use cases from each other.

Moving Towards App-Only Authentication

In many cases, organizations have scheduled PowerShell scripts in place. The scripts probably run as background tasks on some machines in your environments. With the Microsoft.Graph module, I encourage you to move towards certificate-based app-only authentication as shown in the following script snippet. Instead of still scheduling the scripts on local servers, please feel free to try out Azure Automation runbooks. Just upload the app certificate to your Automation account (will be stored securely in Azure Key Vault) and use the -ClientId and -CertificateThumbprint parameters in your Connect-MgGraph command.

# You may need to use the "beta" endpoint of Microsoft Graph (https://graph.microsoft.com/beta/...) instead of the v1 endpoints, which are used by default
# Select-MgProfile -Name "beta"
# Connect to Microsoft Graph with app-only authentication (API permissions have been defined in the app registration in Azure AD)
# See also: https://docs.microsoft.com/en-us/powershell/microsoftgraph/app-only
Connect-MgGraph `
   -TenantId "{TENANT_ID}" `
   -ClientId "{CLIENT_ID}" `
   -CertificateThumbprint "{CERTIFICATE_THUMBPRINT}"
# The Find-MgGraphCommand cmdlet can be used to discover the required permissions for cmdlets. For example, to see all permissions to call Get-MgUser, run:
# Find-MgGraphCommand -Command Get-MgUser | Select -First 1 -ExpandProperty Permissions
# More details: https://docs.microsoft.com/en-us/powershell/microsoftgraph/get-started
# Fetch some data from Microsoft Graph, e.g. all users except guest users, and export to CSV
$users = Get-MgUser `
   -Filter "UserType eq 'Member'" `
   -All `
   -Property UserPrincipalName, DisplayName, Department `
   | Select-Object -Property UserPrincipalName, DisplayName, Department
$users | Export-Csv `
   -LiteralPath "Users.csv" `
   -Delimiter ";" `
   -Encoding UTF8 `
# Disconnect

Beyond that, starting with version 2 (currently only available as preview), the Microsoft Graph PowerShell SDK will offer native support for authentication based on managed identities. With this upgrade, you can leverage the Connect-MgGraph -Identity command. As a result, your Azure Automation runbooks will become even more elegant and maintenance efforts, e.g. for the renewal of your app certificate, will be reduced.

Current Limitations of the new Microsoft Graph SDK

Unfortunately, there is still a gap between the old AzureAD/AzureADPreview/MSOnline cmdlets and the modern Microsoft.Graph approach. If you study the official cmdlet comparison tables, you will recognize that some Mg cmdlets are missing yet. So before migrating your PowerShell scripts, please check out Microsoft’s documentation or use Find-MgGraphCommand to determine whether each of your script commands already have a corresponding modern version.

Sources and Further Readings

  • February 12, 2023
Consent Management Platform by Real Cookie Banner