Lack of Control Over Self-Service Purchases Makes Office 365 Tenants Unhappy
Update: In an update to the self-service purchase FAQ posted on October 31, Microsoft announced that based on customer feedback, they will provide Office 365 tenants with a PowerShell-based method to turn off self-service purchasing on a per-product basis. They also said that the launch date for self-service purchases has been pushed out to January 14, 2020.
The unfavorable customer reaction to Microsoft’s decision to allow Office 365 users make self-service purchases for Power Platform licenses (starting November 19 – Figure 1) hasn’t calmed down. Multiple people have weighed in on the subject in the Microsoft Technical Community, and none seem too pleased. Comments like “an underhanded money grab by Microsoft,” “unacceptable practice,” and “flipping unbelievable” are representative of the feedback seen there, Twitter, Facebook, and other fora. A user voice on the topic has clocked up many votes since the announcement.
Figure 1: Microsoft announces self-service purchases for Power Platform apps
Anyone with an Azure Active Directory account in an Office
365 commercial tenant will be able to buy through self-service. It’s an oddity of
the program that self-service purchases won’t be available to users in
government, non-profit, or education sector tenants, possibly because Microsoft
could run into difficulties if government users (in particular) started to buy
their own software.
The biggest issue is the lack of control for tenant administrators. Simply put, introducing a feature to allow employees of a company buy their own licenses for tools that might be unapproved by the organization is unacceptable, especially when the organization has no way of blocking these purchases. In one way, it’s like Microsoft is endorsing shadow IT on one hand while advocating the use of tools like Cloud App Security to discover and suppress shadow IT on the other.
An Unhelpful Self-Service
Purchases FAQ
Microsoft’s FAQ about self-service purchases published on October 25 isn’t really much help. It smells like a hastily-put together document that tries to put lipstick on a pig. Bland marketing assertions like “The intent of the self-service purchase option is to enable users to develop their own solutions to unlock productivity and drive business impact, while respecting organizations’ data governance and compliance” don’t address tenant concerns. No evidence is offered to prove the existence of “increased demand from both users and organizations to enable users to buy subscriptions on their own.”
Blather, Fud, and Incoherence
Buried in the FAQ is an incoherent statement saying: ”We’re being responsive to our customers who have requested this capability while allowing admins to maintain control over the services and respecting data governance and compliance. To learn more about managing Azure AD service principals, see Set-MsolServicePrincipal.”
Figure 2: An extract from the FAQ about Self-Service Purchases for Power Platform apps
First, apart from allowing admins to see when self-service
purchases are made, there’s no evidence that Microsoft is giving admins control
over the services. The comment about respecting data governance and compliance
is surely nonsensical in the light of poor organization oversight and no
ability to block these purchases. Allowing self-service purchases drives a
coach and horses through the governance that a tenant is entitled to exert if
it says that its policy is that all software purchases must go corporate procurement.
Just what compliance happens in that case?
A Buried Hint?
The comment about Azure
Active Directory Service Principals hangs out there its own and doesn’t
appear to have anything to do with self-service purchases. Unless someone put
the sentence into the FAQ to mean that self-service purchases might depend on a
service principal that a tenant can disable to block purchases. Service
principals exist to allow apps and services to access Azure services in a
controlled manner. If you look in your tenant, you might find that more service
principals exist than you expect or know about.
I looked in my tenant and used a PowerShell script (below) to discover the set of service principals holding Azure Active Directory roles within the tenant.
# Report Service Principals holding Azure AD admin roles
$Roles = Get-MSolRole
Foreach ($Role in $Roles) {
$RoleMembers = $Null
$RoleMembers = (Get-MsolRoleMember -RoleObjectId $Role.ObjectId)
If ($RoleMembers) {
ForEach ($RoleMember in $RoleMembers) {
If ($RoleMember.RoleMemberType -eq "ServicePrincipal") {Write-Host $Role.Name "service principal:" $RoleMember.DisplayName }}
}}
Company Administrator service principal: Microsoft Rights Management Services
Directory Readers service principal: Power BI Service
Directory Readers service principal: Office 365 Yammer
Directory Readers service principal: Cogmotive Reports
Directory Readers service principal: O365SecureScore
Directory Readers service principal: MS-PIM
Directory Readers service principal: MicrosoftAzureActiveAuthn
Directory Writers service principal: O365trustportal
Directory Writers service principal: O365 Secure Score
If you prefer to use the Azure AD cmdlets, the code is:
# Report Service Principals holding Azure AD admin roles
$Roles = Get-AzureADDirectoryRole
Foreach ($Role in $Roles) {
$RoleMembers = $Null
$RoleMembers = (Get-AzureADDirectoryRoleMember -ObjectId $Role.ObjectId)
If ($RoleMembers) {
ForEach ($RoleMember in $RoleMembers) {
If ($RoleMember.ObjectType -eq "ServicePrincipal") {Write-Host $Role.DisplayName "service principal:" $RoleMember.DisplayName }}
}}
Some of the role assignments seem duplications (like the two
for Office 365 Secure Score. All except one hold the Directory Readers role,
which means that they can read Azure Active Directory for information. The
exception is Rights Management, which has full administrative rights.
A Route to the Solution?
The point
is this: it may be the case that self-service purchases depend on a service
principal that reads Azure Active Directory to confirm that someone belongs to
a tenant. If so, disabling that service principal by removing its role
assigning to the Directory Readers role should be enough to knock self-service
purchases on the head.
Wouldn’t it be delicious if a hint dropped in the FAQ turned out to be the way to the block that administrators want, and Microsoft is curiously reluctant to deliver? I’ve created a To Do task to remind myself to check this out on November 19.
Keeping track of Office 365 Administration is tough enough without Microsoft making it hard through some odd decisions. We do our best to help by chasing things down and explaining what’s important in the Office 365 for IT Pros eBook. If you have anything to do with Office 365 administration, you should be a subscriber!
UPDATE as of October 31, 2019: Over the past week, we’ve been listening to customer feedback regarding the rollout of our self-service purchase capabilities for Power Platform products. Based on the feedback, we’re making the following changes to our plan:
On November 19th, we will provide IT admins a way to turn off self-service purchasing on a per product basis via PowerShell. More details will be forthcoming.
To provide more time to prepare for this change, we are updating the launch for self-service purchase capabilities for Power Platform products to start with Power BI on January 14th for all commercial cloud customers.
{"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}
Looks like Microsoft have heard the complaints and are backtracking: https://docs.microsoft.com/en-us/microsoft-365/commerce/subscriptions/self-service-purchase-faq
UPDATE as of October 31, 2019: Over the past week, we’ve been listening to customer feedback regarding the rollout of our self-service purchase capabilities for Power Platform products. Based on the feedback, we’re making the following changes to our plan:
On November 19th, we will provide IT admins a way to turn off self-service purchasing on a per product basis via PowerShell. More details will be forthcoming.
To provide more time to prepare for this change, we are updating the launch for self-service purchase capabilities for Power Platform products to start with Power BI on January 14th for all commercial cloud customers.