New Pause Processing Toggle Appears in Azure AD Admin Center
A recent Azure AD admin center update for Azure AD dynamic groups allows administrators to pause processing of the membership query that identifies group members. I can’t find any announcement about the change, and it’s not tagged as a preview, but a toggle is there to pause processing (Figure 1) and it works.
Figure 1: Pause processing for an Azure AD dynamic group
Switching the pause processing toggle back to off allows Azure AD to continue processing membership rules. The properties of a dynamic group tell you the current state of processing and when the last membership change happened. Common processing states for Azure AD dynamic groups are:
Succeeded: Azure AD has evaluated the membership query and the membership is up to date.
Evaluating: Azure AD is currently resolving the membership query to identify group members.
Processing: Azure AD is currently processing the membership.
Processing error: Azure AD was unable to evaluate the membership query.
Updates paused: An administrator has paused updates. The membership remains static until updates resume.
Not started: Azure AD has not yet started to evaluate the membership of a dynamic group.
Azure AD reassesses membership as demand on the service allows, with the goal of checking at least once daily. It’s therefore possible that Azure AD will not process changes made to user objects that bring them within the scope of a membership rule for up to 24 hours. My experience is that updates often occur earlier, but it’s wise to set this expectation.
Reporting Dynamic Membership Updates
To check the current situation with dynamic membership updates, we can use PowerShell to find all the dynamic groups in the tenant and report the timestamp for the last membership update, whether processing is enabled, and the current update status. Here’s how to do the job with the Microsoft Graph PowerShell SDK:
You can see that the code uses separate calls to the Get-MgGroup cmdlet to fetch the property holding the membership rule processing status for the groups. For some reason, the original call to fetch a set of filtered groups fails if this property is included in the list to be retrieved. As revealed by the Graph X-Ray add-on, the same flow happens in the Azure AD admin center.
The code also includes calls to the Get-MgGroupOwner, Get-MgGroupMember, and Get-MgUser cmdlets to fetch the set of owners and members for each group. Although the Get-MgGroupOwner and Get-MgGroupMember cmdlets returns the set of owners and members respectively for a group, they return object identifiers instead of display names. While we can use the information to report counts, to report the owner names, we need to run Get-MgUser. See these articles for more information about using the Microsoft Graph PowerShell SDK to work with Azure AD users and Azure AD Groups. Figure 2 shows the output of the report.
Figure 2: Reporting Azure AD dynamic groups and their membership status
Dynamic groups with paused membership updates show a last update of 1 January 2000. Two other groups in Figure 2 have odd dates (1/1/0001). These are old dynamic groups (created in 2017) whose membership hasn’t changed since. When a membership change happens, the date will be correct.
Dynamic Groups and Dynamic Distribution Lists
Azure AD dynamic groups and dynamic distribution lists are very different objects, but some people confuse the two or believe that the two objects are roughly the same. Apart from the requirement to have Azure AD Premium P1 licenses for Azure AD dynamic groups, the three biggest differences are:
Dynamic distribution lists don’t exist in Azure AD. They are an Exchange object.
Dynamic distribution lists support a wider set of member objects (any mail-enabled recipient).
Dynamic distribution lists support a wider set of properties for building custom membership filters (queries).
See this article for more information about the differences between the two types of dynamic group.
Although I appreciate Microsoft adding the extra flexibility in pausing membership processing, I’m struggling to find a good use case. One might be in a merger and acquisition scenario where the directory is in a state of flux, and you want consistency in dynamic group memberships for a period. Apart from that, I don’t know why Microsoft introduced the feature. However, it’s here now and available if you need it.
Learn how to exploit the data available to Microsoft 365 tenant administrators through the Office 365 for IT Pros eBook. We love figuring out how things work.
5 Replies to “How to Pause Membership Processing for Azure AD Dynamic Group Membership”
As you mentioned, the purpose of pausing dynamic membership processing is unclear, it would be better if you were able to pause the processing then be able to perform a what-if query similar to that of conditional access… that would make this useful in the case of organisational structure changes or mergers.
great script. it is exactly what I am looking for. however, i never get results. The gridview output will not show up. once I run the script, I can select $Results the correct information is scrolled on the output, but I cannot get the gridview that is sorted. I suspect that i am missing one little piece but for the life of me cannot determine what that would be. Any ideas?
Thank you! I now get results, but one output for each group (I have 102 dynamic groups). I’ll work through what I have to get it all in one window. This will help us with monitoring our dynamic group’s status
It’s PowerShell, so you can do what you like with the code to extend it or amend it to fit your circumstances. I try to explain the principle and leave detailed implementations to those who need a solution.
{"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}
As you mentioned, the purpose of pausing dynamic membership processing is unclear, it would be better if you were able to pause the processing then be able to perform a what-if query similar to that of conditional access… that would make this useful in the case of organisational structure changes or mergers.
great script. it is exactly what I am looking for. however, i never get results. The gridview output will not show up. once I run the script, I can select $Results the correct information is scrolled on the output, but I cannot get the gridview that is sorted. I suspect that i am missing one little piece but for the life of me cannot determine what that would be. Any ideas?
If the $Report is populated with data, you should be able to sort the data and pipe to the Out-GridView cmdlet with a command like:
$Report | Sort-Object DisplayName | Out-GridView
Does that not work?
Thank you! I now get results, but one output for each group (I have 102 dynamic groups). I’ll work through what I have to get it all in one window. This will help us with monitoring our dynamic group’s status
It’s PowerShell, so you can do what you like with the code to extend it or amend it to fit your circumstances. I try to explain the principle and leave detailed implementations to those who need a solution.