License Stacking Allows Workloads to Manage Multiple Licenses
Exchange Online
The Exchange Online blog post of January 20 “Introducing Support for Concurrent Exchange Online License Assignments” caused some furrowed brows because on first glance it doesn’t seem like an important announcement. The impact of the change depends on the size of a Microsoft 365 tenant and the processes used for license management. If your tenant is small and licenses are relatively static, you can safely ignore this topic. But those who run large tenants and use features like group-based license assignments are likely to be much more interested.
License stacking means that an Azure AD user account can hold multiple licenses for the same workload. Some of the licenses might be inherited from products (SKUs) that bundle multiple service plans (a not-for-sale license included in a SKU). Others come from specific products or add-ons. For instance, an account might hold the Teams Exploratory license and also have a license for Teams through the Office 365 E3 or E5 SKUs. When license stacking is in place, the workload is responsible for resolving the capabilities made available through the different licenses and allowing the account access to the feature set available from the best (“most superior”) license. In the example above, Teams would respect the license from Office 365 E3 or E5 because it covers more functionality than the Teams Exploratory license.
Exchange Online Licenses
In the case of Exchange Online, four licenses are available:
Exchange Online Essentials (BPOS_S_Essentials).
Exchange Online Kiosk (BPOS_S_Deskless).
Exchange Online Plan 1 (BPOS_S_Standard).
Exchange Online Plan 2 (BPOS_S_Enterprise).
BPOS refers to Business Productivity Online Suite, a predecessor to Office 365 based on Exchange 2007.
Microsoft says that they have updated the Get-ExoMailbox (Get-Mailbox) and Get-Recipient cmdlets to give tenants insight into the Exchange capabilities assigned to accounts through the licenses assigned to the accounts. I found that the data isn’t fully populated for all mailboxes (this will happen over time). However, it’s possible to run a command like this to report assignments:
Get-Recipient -RecipientTypeDetails UserMailbox -ResultSize Unlimited | Format-Table DisplayName, RootCapabilities
DisplayName RootCapabilities
----------- ----------------
Tony Redmond BPOS_S_Enterprise
Ben Owens (DCPG) None
Andy Ruth (Director) BPOS_S_Standard, BPOS_S_Enterprise
James Ryan BPOS_S_Enterprise
The Ben Owens account is an example where the assignment information isn’t yet populated. The Andy Ruth account is an example where two licenses are in place that include an Exchange service plan (one for Exchange Online Plan 1, the other for Plan 2). In this case, because Exchange Online Plan 2 enables more functionality than Plan 1, it’s the one that Exchange Online respects.
Concurrent License Assignments for Exchange Online
Traditionally, Exchange Online has not supported license stacking, which means that an Azure AD account can hold a single Exchange Online license. Most of the time this doesn’t matter because the usual situation is for an account to receive an Exchange Online license through a product SKU. For instance, Office 365 E3 and E5 both include the Exchange Online Plan 2 service plan.
However, it’s possible that an account might start out with a Microsoft 365 Business Basic license that includes Exchange Online Plan 1. The account belongs to a user who’s promoted to a management position that the organization requires to come within the scope of a retention policy and have an online archive. These features require Exchange Online Plan 2, so the organization removes the Microsoft 365 Business Basic license and assigns the account an Office 365 E3 license.
Exchange Online mandates that all user mailboxes have licenses. When the organization removes the Exchange Online Plan 1 license from the account, a chance exists that Exchange Online might soft-delete the mailbox and make it unavailable. The mailbox becomes available again when the account gains the Exchange Online Plan 2 license through Office 365 E3, but it’s not a great situation to be in if a user loses access to their mailbox while license administration is in progress.
Why Exchange Online License Stacking is Helpful
Support for license stacking (multiple concurrent licenses) means that the organization can assign the superior license to the account before removing the other license. This might happen through an automated process. For instance, a group-based licensing assignment might occur and assign the license because of the user’s new job means that they join a group. Later, another process might remove the inferior license from the account to return it to the unused license pool. Automated license assignment by reference to a property of Azure AD accounts is very common, both through Azure AD group-based assignment and purpose-built license management tools. Organizations often go down this route because of the complexity that’s sometimes found in understanding the combinations and permutations available in Azure AD licensing.
The current schedule deprecates the licensing cmdlets on March 31, 2023, and perhaps this will mark the point when Microsoft allows everyone to use group-based licensing. If you haven’t already migrated PowerShell scripts that do license management to the Microsoft Graph PowerShell SDK, it’s time to get going.
Good Housekeeping Change
Microsoft is rolling stacked licenses support for Exchange Online in the commercial clouds. Government clouds are next and will be done by the end of H1 2023. It’s not an exciting change, but it’s a good example of a housekeeping enhancement that will stop users losing access to their mailboxes due to internal license management.
One Reply to “Exchange Online Adds Support for License Stacking”
Hello Tony,
Thanks for the information, very useful as always.
I understand the scenario of the possibility to soft-delete mailbox during the license re-assignment state, but do you know if license stacking also mean there are no conflicts when two different EXO (or other mutually exclusive licenses) are assigned to the user by GBL?
From my understanding, this is how it works, but this conflicting plan scenario isn’t mentioned either in your post or on related Exchange Blog post.
{"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}
Hello Tony,
Thanks for the information, very useful as always.
I understand the scenario of the possibility to soft-delete mailbox during the license re-assignment state, but do you know if license stacking also mean there are no conflicts when two different EXO (or other mutually exclusive licenses) are assigned to the user by GBL?
From my understanding, this is how it works, but this conflicting plan scenario isn’t mentioned either in your post or on related Exchange Blog post.