Providing Licenses to a Large Number of Users
An example demonstrating how to read accounts from a CSV and assign licenses to those accounts was requested in a reader comment for the post describing how to assign licenses to user accounts using the Microsoft Graph PowerShell SDK. Or, how to assign licenses in bulk to specific user accounts using PowerShell. People typically do that when introducing new products to a tenant.
After deciding who will receive Copilot licenses, companies that are ready to pay the $30 per user/month pricing when Microsoft eventually makes Microsoft 365 Copilot available to the public may look for some kind of bulk assignment mechanism. Tenants of Copilot may employ group-based licensing as long as they own Microsoft 365 corporate licenses. This script is pretty much a do-it-yourself assignment mechanism for individuals who are unable to use group-based licensing, and it is the best method. However, it’s always beneficial to be aware of how things operate so that, if necessary, you may develop your own automation.
Processing User Accounts to Find
The processing processes are straightforward conceptually. The first step entails importing target user account information from a CSV file. The set of target accounts can also be established using a different approach. A few appropriate mechanisms are:
- Microsoft 365 group’s membership, including dynamic groups. To eliminate any visitor accounts from the group membership, you must filter it.
- Distribution list’s membership (including dynamic distribution lists). Some filtering is required since distribution lists may contain items that cannot be specifically targeted for license assignment, such as public files or mail users.
- Membership of an Entra ID administrative unit.
- The Get-MgUser cmdlet can be filtered to find user accounts.
As an illustration, you may locate a group of target accounts by searching for all the accounts based in a particular nation:
Of course, appropriate data must be entered into account properties for filters to be effective in locating user accounts.
Target Users Array Creation for Bulk License Assignment
The key idea is that it is irrelevant how you produce a list of target accounts. Your script’s ability to provide a collection of identifiers that can be utilized for license assignment is all that matters. These codes could be user principal names or account object identifiers (GUIDs).
In the sample script, I do the following because so many people utilize CSV files to identify target accounts in this case:
The user’s principal name and display name of the accounts to which we want to give licenses are stored in the $Users array of data.
Giving Each User Account a License
When the group of target user accounts is available, the job is halfway complete. After all, the only thing left to do is to issue each account with a Set-MgUserLicense cmdlet. That’s true if you want to run a one-time operation, for sure, but it’s best to add certain checks and balances to any script code that might be used often.
- Identifies the tenant-known subscribed products (SKUs) and chooses the SKUs for which there are still some licenses available.
- Provides the user with a list of SKUs so they can select the license to give to the intended users.
- Verifies that there are enough available licenses to distribute to all the target users.
- Verifies that no target user has the license in their assigned set before.
- Try to assign the license to the account if the user does not already have it. If your tenant employs restricted administrative units, only accounts with administrator responsibilities for those administrative units are able to do this.
- Captures information about the license assignment’s success or failure and saves it as a list object.
- Reports processing information, including the number of successful and unsuccessful license assignments.
Additional Upgrades Are Possible
To prepare for some of the circumstances you can run across during license assignment operations, I had a great time playing around with the script. However, I feel like I only scratched the surface. There is a lot more that could be done to improve the script’s ability to handle various situations, like:
- Transferring several product SKUs at once.
- Removing service plans from product SKUs that the company doesn’t want customers to utilize. For example, the company may determine that Viva Engage (Yammer) is not necessary and disable the Viva Engage Core service plan in SKUs like Office 365 E3 and E5. That is conceivable, however disabling Viva Engage disables some Teams features, such as the meeting Q&A app.
- Via email or Teams, distribute the outcomes of the license assignment processing to others.