Assigning Licenses to a Bunch of Users

A reader comment for the article covering how to assign licenses to user accounts with the Microsoft Graph PowerShell SDK asked for an example showing how to read accounts from a CSV and assign licenses to those accounts. In other words, how to use PowerShell for bulk assignment of licenses to target user accounts. It’s the kind of thing people do when introducing new products to a tenant.

When Microsoft eventually releases Microsoft 365 Copilot for public consumption, I imagine that organizations willing to stump up the $30/user/month price will look for some sort of bulk assignment mechanism after they decide who gets Copilot licenses. Given that Copilot requires tenants to have Microsoft 365 enterprise licenses, they can use group-based licensing. That’s the best approach and the script discussed here is very much a do-it-yourself assignment mechanism for those who can’t use group-based licensing. Then again, it’s always nice to understand how things work so that you can create your own automation if necessary.

Finding User Accounts to Process

Conceptually, the processing steps are simple. The first step is to import details of target user accounts from a CSV file. Alternatively, you can use another mechanism to establish the set of target accounts. Suitable mechanisms include:

  • Membership of a Microsoft 365 group (including dynamic groups). You need to filter the group membership to remove any guest accounts.
  • Membership of a distribution list (including dynamic distribution lists). Distribution lists can include objects that can’t be targeted for license assignment, like public folders or mail users, so some filtering is necessary.
  • Membership of an Entra ID administrative unit.
  • User accounts are found by applying a filter to the Get-MgUser cmdlet.

For example, you could find a set of target accounts by looking for all the accounts located in a certain country:

[array]$Users = Get-MgUser -All -Filter "country eq 'United States'"

Of course, using filters to find user accounts only works if account properties are populated with accurate information.

Creating a Target Users Array for Bulk License Assignment

The point is that it doesn’t matter how you generate a set of target accounts. All that’s important is that your script provides a set of identifiers that can be used for license assignment. Those identifiers can be account object identifiers (GUIDs) or user principal names.

For this example, because so many people use CSV files to point to target accounts, that’s what I do in the example script:

$InputFile = "c:\temp\Users.csv"
[array]$Users = Import-CSV $InputFile

The data contained in the $Users array holds the user principal name and display name of the accounts we want to assign licenses to:

UPN                                DisplayName
---                                -----------   Lotte Vetler     Otto Flick     James Ryan   Hans Geering                Joe Sop      Ben James Brian Weakliam

Assigning Licenses to Each User Account

The job’s half done when the set of target user accounts is available. After all, the only thing that’s left to do is to run the Set-MgUserLicense cmdlet for each account. Well, that’s certainly true if you want to perform a one-off operation, but it’s best to build some checks and balances in any script code that might be reused.

To illustrate what I mean, examine the processing displayed in Figure 1.

Running the License assignment script

Bulk license assignment Microsoft 365
Figure 1: Running the License assignment script

The script:

  • Finds the subscribed products (SKUs) known to the tenant and selects the SKUs that still have some available licenses.
  • Presents the list of SKUs to the user to allow them to choose which license to assign to the target users.
  • Checks that sufficient available licenses exist to assign to all the target users.
  • Checks that each target user does not already have the license in their assigned set.
  • If the license is not present for a user, attempt to assign the license to the account (note: if your tenant uses restricted administrative units, only accounts holding administrator roles for the administrative units can assign licenses to member accounts).
  • Captures details of the success or failure of the license assignment and records the information in a list object (Figure 2).
  • Reports details of the processing, including how many successful and failed license assignments occurred.
Results of the license assignment script
Figure 2: Results of the license assignment script

Do you have what it takes to become the TEC 2023 PowerShell Script-Off Challenge Champion?

Register Today!

More Improvements Possible

I spent a happy afternoon playing with the script to anticipate some of the situations that you might encounter during license assignment operations, but I think I barely scratched the surface. There is much more that could be done to expand the script to handle different conditions, such as:

  • Assigning multiple product SKUs at one time.
  • Disabling service plans that the organization doesn’t want people to use from product SKUs. For instance, the organization might decide that Viva Engage (Yammer) isn’t required and therefore disables the Viva Engage Core service plan in SKUs like Office 365 E3 and E5. That’s possible, but if you disable Viva Engage, you lose some Teams functionality, like the Q&A app in meetings.
  • Share the results of the license assignment processing with other people via email or Teams.

Please feel free to amend the script I wrote (available for download from GitHub) to add your ideas. I might disagree with your suggestions, but at least we can have a discussion.

Bulk License Assignment Automated Your Way

PowerShell makes it possible to automate operations the way you want things done rather than the way Microsoft thinks things should be done. That’s its big advantage and it’s the core reason why every Microsoft 365 administrator should be passingly fluent in PowerShell.

If you attend The Experts Conference in Atlanta (Sept 19-20, 2023), make sure to come to the Great PowerShell Script-Off to have some fun and support the contestants as they struggle with the challenges we’ll set for them. All the challenges are common Microsoft 365 tenant automation tasks, so you might even learn something too!

About the Author

Tony Redmond

Tony Redmond has written thousands of articles about Microsoft technology since 1996. He is the lead author for the Office 365 for IT Pros eBook, the only book covering Office 365 that is updated monthly to keep pace with change in the cloud. Apart from contributing to, Tony also writes at to support the development of the eBook. He has been a Microsoft MVP since 2004.

Leave a Reply