For anyone who’s ever used the Azure AD or Microsoft Online Services (MSOL) PowerShell modules to write PowerShell code to automate some aspect of tenant administration, Microsoft’s June 2 announcement about their future direction for Azure AD PowerShell was big news. In a nutshell, Microsoft is focusing on the Graph APIs for identity management. As a consequence, any software which leverages the Azure AD Graph API, like the Azure AD module, is on the runway to deprecation.
Important Points for the Next Year
Last year, Microsoft announced that they would no longer support or provide security updates for the Azure AD Graph API after 30 June 2022. Now they are being more specific about what this end of support decision means for customers. The following points are important:
The Azure AD and MSOL modules will not be supported for PowerShell 7.
New identity APIs will be available through the Microsoft Graph PowerShell SDK (Figure 1).
Microsoft’s investments will center on user, group, and application management, plus role-based access control (RBAC), which is important in terms of making sure that administrators don’t need all-powerful permissions to get work done. Microsoft 365 uses an increasing number of role groups to assign administrative work to different accounts.
Microsoft also says that they will invest in usability for the Microsoft Graph PowerShell SDK, which is a good thing because the SDK cmdlets aren’t quite as approachable as those in other modules. The documentation is not in good shape either. See my articles covering basic Azure AD user account management and group management for details.
Figure 1: Connecting to the Microsoft Graph PowerShell SDK
Microsoft says that their goal is that “every Azure AD feature has an API in Microsoft Graph so you can administer Azure AD through the Microsoft Graph API or Microsoft Graph SDK for PowerShell.” They don’t say that every feature will be accessible through the Microsoft Graph PowerShell SDK. In some cases, you’ll need to run pure Graph API calls, but that’s easily done using PowerShell (for an example, see this article on accessing Azure AD access reviews from PowerShell.
Update August 1, 2022: Microsoft has pushed out the previously announced retirement date for the license management cmdlets in the Azure AD and MSOL modules (August 26, 2022) to March 31, 2023. They have delayed the retirement of the Azure AD Graph API until the end of 2022 to give customers extra time to adjust.
It’s Different With the Graph
The net takeaway is that tenants need to review any PowerShell scripts which use the Azure AD or MSOL modules to prepare plans to upgrade scripts to use the Microsoft Graph PowerShell SDK or Graph API calls in the future. Given the number of Office 365 tenants, the pervasive use of PowerShell to automate operations, and the core position of Azure AD in those operations, it’s likely that millions of scripts will need upgrades. I know that I have a bunch of scripts to review and will discuss how the upgrade process proceeds in future articles. Already, I know it won’t be simply a case of replacing all occurrences of Azure AD cmdlets with equivalent Graph SDK calls, like replacing Get-AzureADUser with Get-MgUser. Parameters and output are likely to be different and code will need to be adjusted to cope.
While upgrading scripts is a big job, each script is a one-time activity. Interactive access is another issue. Today, it’s easy to run Connect-AzureAD to connect to Azure AD and then run whatever cmdlets you need to interrogate the directory. The equivalent actions with the SDK are:
First, you connect to the Graph and set the scope (permissions) needed to interact with Azure AD. Unless a suitable access token is available, this starts a device authentication sequence.
Connect-MgGraph -Scopes "User.Read.All","Group.ReadWrite.All"
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code D7DPGD3WL to authenticate.
Opening a web page and inputting the code causes another dialog to appear to confirm consent for the operation (Figure 2).
Figure 2: App consent required to use the Microsoft Graph PowerShell SDK
After consent is granted, you can then go ahead and issue commands. For example, here’s how to fetch a list of guest accounts:
Like most Graph commands, the amount of data returned is constrained to 100 items, so if you want more, you need to specify the All parameter.
The bottom line is that some more up-front thought is needed (to set permissions) before connecting to the Graph SDK and that the authentication flow is not as seamless as it is when running Connect-AzureAD. No doubt this is an area where Microsoft might look at to remove some rough edges.
Time to Prepare Upgrades
Losing support for the Azure AD and MSOL modules sometime in 2022 is a concern, but we’ve seen other instances when Microsoft has extended support to allow customers extra time to get work done, and anyway, losing support doesn’t mean that code will suddenly stop working. Scripts will continue to run. You just won’t be able to ask Microsoft to fix bugs.
One thing you can guarantee in the cloud is that change happens. This is just another example of how that change occurs.
The Office 365 for IT Pros team will document our learning with upgrading PowerShell scripts from the Azure AD module to use the Microsoft Graph PowerShell SDK in the months ago. It should be fun… Subscribe now to make sure that you stay abreast of developments.
I am admittedly not an expert here, however I am finding some contradictory evidence to the statement “As a consequence, any software which leverages the Azure AD Graph API, like the Azure AD module, is on the runway to deprecation.”. Does the AzureAD powershell library definitely use the Graph library under the hood? This other reference is saying that the pure powershell library is not being deprecated and eludes to some confusion over the deprecation of the Powershell Graph API instead. It then references this post on the Azure AD powershell github page that tells us that AzureAD powershell is not abandonware https://github.com/Azure/azure-docs-powershell-azuread/issues/621
I don’t think Microsoft will abandon the Azure AD PowerShell module. Instead, I think they will put it into maintenance mode and eventually deprecate it.
Microsoft Azure AD development is putting its weight being the SDK. That’s not abandonment of the current module. It’s more like favoring one child over another.
The picture seems much more dire than an eventual depreciation – sounds like all AzureAD-Graph-dependant code will stop working after June 30, 2022, and doesn’t the AzureAD powershell module use the AzureAD Graph API?
“Azure Active Directory (Azure AD) Graph is deprecated. To avoid loss of functionality, migrate your applications to Microsoft Graph before June 30, 2022 when Azure AD Graph API endpoints will stop responding to requests.
Microsoft will continue technical support and apply security fixes for Azure AD Graph until June 30, 2022 when all functionality and support will end. If you fail to migrate your applications to Microsoft Graph before June 30, 2022, you put their functionality and stability at risk.”
I imagine that things will be a little less serious than that… I imagine that everything (except license management) will continue working for quite a while after the deprecation. But that’s no excuse to avoid the necessity to upgrade scripts before the axe descends.
{"id":null,"mode":"button","open_style":"in_modal","currency_code":"EUR","currency_symbol":"\u20ac","currency_type":"decimal","blank_flag_url":"https:\/\/office365itpros.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/blank.gif","flag_sprite_url":"https:\/\/office365itpros.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/flags.png","default_amount":100,"top_media_type":"featured_image","featured_image_url":"https:\/\/office365itpros.com\/wp-content\/uploads\/2022\/11\/cover-141x200.jpg","featured_embed":"","header_media":null,"file_download_attachment_data":null,"recurring_options_enabled":true,"recurring_options":{"never":{"selected":true,"after_output":"One time only"},"weekly":{"selected":false,"after_output":"Every week"},"monthly":{"selected":false,"after_output":"Every month"},"yearly":{"selected":false,"after_output":"Every year"}},"strings":{"current_user_email":"","current_user_name":"","link_text":"Virtual Tip Jar","complete_payment_button_error_text":"Check info and try again","payment_verb":"Pay","payment_request_label":"Office 365 for IT Pros","form_has_an_error":"Please check and fix the errors above","general_server_error":"Something isn't working right at the moment. Please try again.","form_title":"Office 365 for IT Pros","form_subtitle":null,"currency_search_text":"Country or Currency here","other_payment_option":"Other payment option","manage_payments_button_text":"Manage your payments","thank_you_message":"Thank you for supporting the work of Office 365 for IT Pros!","payment_confirmation_title":"Office 365 for IT Pros","receipt_title":"Your Receipt","print_receipt":"Print Receipt","email_receipt":"Email Receipt","email_receipt_sending":"Sending receipt...","email_receipt_success":"Email receipt successfully sent","email_receipt_failed":"Email receipt failed to send. Please try again.","receipt_payee":"Paid to","receipt_statement_descriptor":"This will show up on your statement as","receipt_date":"Date","receipt_transaction_id":"Transaction ID","receipt_transaction_amount":"Amount","refund_payer":"Refund from","login":"Log in to manage your payments","manage_payments":"Manage Payments","transactions_title":"Your Transactions","transaction_title":"Transaction Receipt","transaction_period":"Plan Period","arrangements_title":"Your Plans","arrangement_title":"Manage Plan","arrangement_details":"Plan Details","arrangement_id_title":"Plan ID","arrangement_payment_method_title":"Payment Method","arrangement_amount_title":"Plan Amount","arrangement_renewal_title":"Next renewal date","arrangement_action_cancel":"Cancel Plan","arrangement_action_cant_cancel":"Cancelling is currently not available.","arrangement_action_cancel_double":"Are you sure you'd like to cancel?","arrangement_cancelling":"Cancelling Plan...","arrangement_cancelled":"Plan Cancelled","arrangement_failed_to_cancel":"Failed to cancel plan","back_to_plans":"\u2190 Back to Plans","update_payment_method_verb":"Update","sca_auth_description":"Your have a pending renewal payment which requires authorization.","sca_auth_verb":"Authorize renewal payment","sca_authing_verb":"Authorizing payment","sca_authed_verb":"Payment successfully authorized!","sca_auth_failed":"Unable to authorize! Please try again.","login_button_text":"Log in","login_form_has_an_error":"Please check and fix the errors above","uppercase_search":"Search","lowercase_search":"search","uppercase_page":"Page","lowercase_page":"page","uppercase_items":"Items","lowercase_items":"items","uppercase_per":"Per","lowercase_per":"per","uppercase_of":"Of","lowercase_of":"of","back":"Back to plans","zip_code_placeholder":"Zip\/Postal Code","download_file_button_text":"Download File","input_field_instructions":{"tip_amount":{"placeholder_text":"How much would you like to tip?","initial":{"instruction_type":"normal","instruction_message":"How much would you like to tip? Choose any currency."},"empty":{"instruction_type":"error","instruction_message":"How much would you like to tip? Choose any currency."},"invalid_curency":{"instruction_type":"error","instruction_message":"Please choose a valid currency."}},"recurring":{"placeholder_text":"Recurring","initial":{"instruction_type":"normal","instruction_message":"How often would you like to give this?"},"success":{"instruction_type":"success","instruction_message":"How often would you like to give this?"},"empty":{"instruction_type":"error","instruction_message":"How often would you like to give this?"}},"name":{"placeholder_text":"Name on Credit Card","initial":{"instruction_type":"normal","instruction_message":"Enter the name on your card."},"success":{"instruction_type":"success","instruction_message":"Enter the name on your card."},"empty":{"instruction_type":"error","instruction_message":"Please enter the name on your card."}},"privacy_policy":{"terms_title":"Terms and conditions","terms_body":null,"terms_show_text":"View Terms","terms_hide_text":"Hide Terms","initial":{"instruction_type":"normal","instruction_message":"I agree to the terms."},"unchecked":{"instruction_type":"error","instruction_message":"Please agree to the terms."},"checked":{"instruction_type":"success","instruction_message":"I agree to the terms."}},"email":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email address"},"success":{"instruction_type":"success","instruction_message":"Enter your email address"},"blank":{"instruction_type":"error","instruction_message":"Enter your email address"},"not_an_email_address":{"instruction_type":"error","instruction_message":"Make sure you have entered a valid email address"}},"note_with_tip":{"placeholder_text":"Your note here...","initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"empty":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"not_empty_initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"saving":{"instruction_type":"normal","instruction_message":"Saving note..."},"success":{"instruction_type":"success","instruction_message":"Note successfully saved!"},"error":{"instruction_type":"error","instruction_message":"Unable to save note note at this time. Please try again."}},"email_for_login_code":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email to log in."},"success":{"instruction_type":"success","instruction_message":"Enter your email to log in."},"blank":{"instruction_type":"error","instruction_message":"Enter your email to log in."},"empty":{"instruction_type":"error","instruction_message":"Enter your email to log in."}},"login_code":{"initial":{"instruction_type":"normal","instruction_message":"Check your email and enter the login code."},"success":{"instruction_type":"success","instruction_message":"Check your email and enter the login code."},"blank":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."},"empty":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."}},"stripe_all_in_one":{"initial":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"empty":{"instruction_type":"error","instruction_message":"Enter your credit card details here."},"success":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"invalid_number":{"instruction_type":"error","instruction_message":"The card number is not a valid credit card number."},"invalid_expiry_month":{"instruction_type":"error","instruction_message":"The card's expiration month is invalid."},"invalid_expiry_year":{"instruction_type":"error","instruction_message":"The card's expiration year is invalid."},"invalid_cvc":{"instruction_type":"error","instruction_message":"The card's security code is invalid."},"incorrect_number":{"instruction_type":"error","instruction_message":"The card number is incorrect."},"incomplete_number":{"instruction_type":"error","instruction_message":"The card number is incomplete."},"incomplete_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incomplete."},"incomplete_expiry":{"instruction_type":"error","instruction_message":"The card's expiration date is incomplete."},"incomplete_zip":{"instruction_type":"error","instruction_message":"The card's zip code is incomplete."},"expired_card":{"instruction_type":"error","instruction_message":"The card has expired."},"incorrect_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incorrect."},"incorrect_zip":{"instruction_type":"error","instruction_message":"The card's zip code failed validation."},"invalid_expiry_year_past":{"instruction_type":"error","instruction_message":"The card's expiration year is in the past"},"card_declined":{"instruction_type":"error","instruction_message":"The card was declined."},"missing":{"instruction_type":"error","instruction_message":"There is no card on a customer that is being charged."},"processing_error":{"instruction_type":"error","instruction_message":"An error occurred while processing the card."},"invalid_request_error":{"instruction_type":"error","instruction_message":"Unable to process this payment, please try again or use alternative method."},"invalid_sofort_country":{"instruction_type":"error","instruction_message":"The billing country is not accepted by SOFORT. Please try another country."}}}},"fetched_oembed_html":false}
I am admittedly not an expert here, however I am finding some contradictory evidence to the statement “As a consequence, any software which leverages the Azure AD Graph API, like the Azure AD module, is on the runway to deprecation.”. Does the AzureAD powershell library definitely use the Graph library under the hood? This other reference is saying that the pure powershell library is not being deprecated and eludes to some confusion over the deprecation of the Powershell Graph API instead. It then references this post on the Azure AD powershell github page that tells us that AzureAD powershell is not abandonware https://github.com/Azure/azure-docs-powershell-azuread/issues/621
I don’t think Microsoft will abandon the Azure AD PowerShell module. Instead, I think they will put it into maintenance mode and eventually deprecate it.
The first obvious change will happen in late June 2022 when the cmdlets which deal with licenses stop working. This is because Microsoft is moving to a new license management platform (see https://practical365.com/microsoft-forces-move-from-azure-ad-cmdlets-for-license-management/). The new license management capabilities will be available through the Microsoft Graph SDK for PowerShell, as per the statement made by Alex Simon in https://techcommunity.microsoft.com/t5/azure-active-directory-identity/automate-and-manage-azure-ad-tasks-at-scale-with-the-microsoft/ba-p/1942489. He also says there that the Azure AD module won’t work on PowerShell 7.
Microsoft Azure AD development is putting its weight being the SDK. That’s not abandonment of the current module. It’s more like favoring one child over another.
According to: https://docs.microsoft.com/en-us/graph/migrate-azure-ad-graph-overview
The picture seems much more dire than an eventual depreciation – sounds like all AzureAD-Graph-dependant code will stop working after June 30, 2022, and doesn’t the AzureAD powershell module use the AzureAD Graph API?
“Azure Active Directory (Azure AD) Graph is deprecated. To avoid loss of functionality, migrate your applications to Microsoft Graph before June 30, 2022 when Azure AD Graph API endpoints will stop responding to requests.
Microsoft will continue technical support and apply security fixes for Azure AD Graph until June 30, 2022 when all functionality and support will end. If you fail to migrate your applications to Microsoft Graph before June 30, 2022, you put their functionality and stability at risk.”
I imagine that things will be a little less serious than that… I imagine that everything (except license management) will continue working for quite a while after the deprecation. But that’s no excuse to avoid the necessity to upgrade scripts before the axe descends.