This was the only sensible course of action. The Graph APIs for dealing with many Azure AD account interactions, especially license assignments, were sadly undocumented. The suggestion of using cmdlets from the Microsoft Graph PowerShell SDK ran into difficulties because the production version (V1.0) of cmdlets like Get-MgUser didn’t return license information. Allied to that, the documentation for the SDK cmdlets remains poor and inscrutable at times.
Time Helped Improve the Situation
Time is a great healer and allows for improvements to be made. The Graph Explorer works better and the Graph X-Ray tool reveals details about how Microsoft uses Graph calls in places like the Azure AD admin center (or rather, the Microsoft Entra admin center).
In addition, Microsoft developed documentation to help people migrate scripts, including a cmdlet map to translate old cmdlets to new. The important thing to realize here is that automatic translation from one set of cmdlets to the other is difficult. People code in PowerShell in different ways and it’s not always clear how to translate code to a new cmdlet. Some community-based projects do exist (here’s a new one that is spinning up), but any attempt to covert to SDK cmdlets must take the SDK foibles into consideration, like its fundamental disregard for the PowerShell pipeline.
But time eventually runs out and we are now at the point where Microsoft is progressing the retirement of the Azure AD and MSOL modules. Here’s my understanding of the situation based on some discussions with Microsoft:
The licensing cmdlets from the Azure AD and MSOL modules do not work for tenants created after November 1, 2022. These tenants must use Graph APIs or SDK cmdlets to manage license assignments for Azure AD accounts.
For all tenants, March 31, 2023, marked the official retirement date for the licensing cmdlets in the Azure AD and MSOL modules.
Retirement doesn’t mean “stop working.” Instead, Microsoft now throttles cmdlets that assign licenses to Azure AD accounts so that they’re not as responsive as before. This is in line with the warning posted on July 29, 2022, that “Customers may notice performance delays as we approach the retirement deadline,” The affected cmdlets are:
Set-MsolUserLicenseSet-AzureADUserLicense
New-MsolUser (where the creation of an account includes a license assignment)
Figure 1: The Set-AzureADUserLicense cmdlet will stop working before June 30, 2023
From now on, Microsoft will increase the throttling rate to make the licensing cmdlets less attractive. Shortly, Microsoft will initiate short outages to gauge the effect of stopping the cmdlets completely. Doing this allows Microsoft to understand if any major pain is caused to customers.
Before or on June 30, 2023, the licensing cmdlets “will no longer receive a successful response.” In other words, no throttling, no short delays, just nothing. The exact date when the shut-off happens depends on the information Microsoft gains about customer usage. What’s for sure is that the licensing cmdlets in the Azure AD and MSOL modules will stop working soon.
After June 30, 2023, the Azure AD and MSOL modules are unsupported. Cmdlets may still run, but no guarantees exist that they will be successful. Given that the modules have been around for many years, you could anticipate that the cmdlets that don’t interact with the Microsoft 365 licensing platform will be OK. You might be right, but you don’t know how long that state will last because the modules are officially retired.
The Bottom Line About Azure AD PowerShell Deprecation
The Azure AD and MSOL modules are now on borrowed time. If you haven’t already started to upgrade scripts to use the Graph APIs or the Microsoft Graph PowerShell SDK, scripts that use these modules could encounter an unpleasant failure very soon. It’s time to get busy to make sure that all scripts can run after June 30, 2023.
Stay updated with developments across the Microsoft 365 ecosystem by subscribing to the Office 365 for IT Pros eBook. We do the research to make sure that our readers understand the technology.
Do you know why this worked better? I’m getting a permission error and the scopes I have should provide everything. User.ManageIdentities.All, User.EnableDisableAccount.All, User.ReadWrite.All, Directory.ReadWrite.All
Not sure how to get the permissions to test this.
Loading...
The Microsoft documentation says (for using a password profile):
In delegated access, the calling app must be assigned the Directory.AccessAsUser.All delegated permission on behalf of the signed-in user. In application-only access, the calling app must be assigned the User.ReadWrite.All application permission and at least the User Administrator Azure AD role.
Are you doing this interactively or using a program (delegated or application)? That might account for the difference.
Loading...
Never mind I found it needed this as well:
Directory.AccessAsUser.All
Loading...
I think that Directory.ReadWrite.All is a better permission to uss. Directory.AccessAsUser.All is accessing the directory as a user and you’d imagine that the Directory.ReadWrite.All is more appropriate because it’s an admin activity. https://graphpermissions.merill.net/permission/Directory.AccessAsUser.All. In any case, you have a solution…
There isn’t one yet. But that’s OK because Start-ADSyncSyncCycle doesn’t do anything with licenses, which is the first problem that people will run into. A replacement will come in due course.
Hi, Any solution for this ? I tried to apply license for all users in bulk in exchange, but its returning with error
Set-MsolUserLicense : You have exceeded the maximum number of allowable transactions. Please try again later.
At line:1 char:60
+ … | foreach {Set-MsolUserLicense -UserPrincipalName $_.UserPrincipalNa …
I find myself *very* conflicted about Microsoft’s push to retire the Azure AD module and move to the Microsoft Graph modules. On the one hand, there are a few places where the Mg module solves major headaches with the Azure AD modules. On the other hand, the number of Mg modules that are still missing functionality (or force you to fall back to essentially interacting directly with the Graph API via PowerShell) are really frustrating. Multiple Mg modules are still basically unusable. . . and that’s without getting into the abysmal state of the documentation.
It kinda feels like Microsoft is saying, “Helo! We’re going to take away some of your most useful tools shortly. However, don’t worry, we’re going to replace them with “new” tools, and the new tools will have features your current tools don’t have! Admittedly, many of those features don’t exist or don’t work yet. Also, some of the new tools aren’t actually usable tools yet, they’re just pictures of tools we’ll give you later. Probably. And, some of the tools are missing important pieces. Don’t worry, though; a hammer can still be useful, even if it doesn’t have a handle yet. And this drill will amaze you once we add the battery and drill bits! Also, we only have 12 pages out of the 500 page instruction manual written right now. You have until next week to stop using your existing tools (date subject to change at our whim).
Hi Sir, i was using this script for assign bulk user license but its now not working : —
====================================
$AccountSkuId = “EXAMPLE:DESKLESSPACK”
$UsageLocation = “GB”
$Users = Import-Csv C:\Users\girin\OneDrive\Desktop\UPN.csv -delimiter “,”
$Users | ForEach-Object {
$_.UserPrincipalname
Set-MsolUser -UserPrincipalName $_.UserPrincipalName -UsageLocation $UsageLocation
Set-MsolUserLicense -UserPrincipalName $_.UserPrincipalName -AddLicenses $AccountSkuId
}
====================================
Please can you help me to correct this script and share it back
I imagine that you can do a search for “assign licenses with Microsoft Graph PowerShell SDK” and find articles to explain how to do what you want, including articles that I have written.
{"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}
Have you figured out how to reset a user’s password and NOT force a password reset on first signon?
Sure. Use the setting in the password profile used as the input to the Update-MgUser cmdlet to avoid resetting the password.
$NewPassword[“Password”]= “!NewYorkCity2022?”
$NewPassword[“ForceChangePasswordNextSignIn”] = $false
Update-MgUser -UserId $UserId -PasswordProfile $NewPassword
For more details on the password profile see https://learn.microsoft.com/en-us/graph/api/resources/passwordprofile?view=graph-rest-1.0
What you sent didn’t work on PowerShell 5.1. But it led me to another article that worked:
https://learn.microsoft.com/en-us/graph/api/user-update?view=graph-rest-1.0&tabs=powershell#example-3-update-the-passwordprofile-of-a-user-to-reset-their-password
$PasswordProfile = @{
ForceChangePasswordNextSignIn = $false
Password = “riverD@0404”
}
Update-MgUser -UserId $UserId -PasswordProfile $PasswordProfile
Do you know why this worked better? I’m getting a permission error and the scopes I have should provide everything. User.ManageIdentities.All, User.EnableDisableAccount.All, User.ReadWrite.All, Directory.ReadWrite.All
Not sure how to get the permissions to test this.
The Microsoft documentation says (for using a password profile):
In delegated access, the calling app must be assigned the Directory.AccessAsUser.All delegated permission on behalf of the signed-in user. In application-only access, the calling app must be assigned the User.ReadWrite.All application permission and at least the User Administrator Azure AD role.
Are you doing this interactively or using a program (delegated or application)? That might account for the difference.
Never mind I found it needed this as well:
Directory.AccessAsUser.All
I think that Directory.ReadWrite.All is a better permission to uss. Directory.AccessAsUser.All is accessing the directory as a user and you’d imagine that the Directory.ReadWrite.All is more appropriate because it’s an admin activity. https://graphpermissions.merill.net/permission/Directory.AccessAsUser.All. In any case, you have a solution…
What is the equivalent of Start-ADSyncSyncCycle Delta?
There isn’t one yet. But that’s OK because Start-ADSyncSyncCycle doesn’t do anything with licenses, which is the first problem that people will run into. A replacement will come in due course.
Hi, Any solution for this ? I tried to apply license for all users in bulk in exchange, but its returning with error
Set-MsolUserLicense : You have exceeded the maximum number of allowable transactions. Please try again later.
At line:1 char:60
+ … | foreach {Set-MsolUserLicense -UserPrincipalName $_.UserPrincipalNa …
The solution is to use the Microsoft Graph PowerShell SDK to apply licenses. https://practical365.com/microsoft-365-license-graph-sdk/
Any example of Excel sheet ?
What kind of Excel sheet with what data?
I find myself *very* conflicted about Microsoft’s push to retire the Azure AD module and move to the Microsoft Graph modules. On the one hand, there are a few places where the Mg module solves major headaches with the Azure AD modules. On the other hand, the number of Mg modules that are still missing functionality (or force you to fall back to essentially interacting directly with the Graph API via PowerShell) are really frustrating. Multiple Mg modules are still basically unusable. . . and that’s without getting into the abysmal state of the documentation.
It kinda feels like Microsoft is saying, “Helo! We’re going to take away some of your most useful tools shortly. However, don’t worry, we’re going to replace them with “new” tools, and the new tools will have features your current tools don’t have! Admittedly, many of those features don’t exist or don’t work yet. Also, some of the new tools aren’t actually usable tools yet, they’re just pictures of tools we’ll give you later. Probably. And, some of the tools are missing important pieces. Don’t worry, though; a hammer can still be useful, even if it doesn’t have a handle yet. And this drill will amaze you once we add the battery and drill bits! Also, we only have 12 pages out of the 500 page instruction manual written right now. You have until next week to stop using your existing tools (date subject to change at our whim).
As a Microsoft person might say: “thank you for your feedback…”
Hi Sir, i was using this script for assign bulk user license but its now not working : —
====================================
$AccountSkuId = “EXAMPLE:DESKLESSPACK”
$UsageLocation = “GB”
$Users = Import-Csv C:\Users\girin\OneDrive\Desktop\UPN.csv -delimiter “,”
$Users | ForEach-Object {
$_.UserPrincipalname
Set-MsolUser -UserPrincipalName $_.UserPrincipalName -UsageLocation $UsageLocation
Set-MsolUserLicense -UserPrincipalName $_.UserPrincipalName -AddLicenses $AccountSkuId
}
====================================
Please can you help me to correct this script and share it back
thanks
I imagine that you can do a search for “assign licenses with Microsoft Graph PowerShell SDK” and find articles to explain how to do what you want, including articles that I have written.