Remove all Office 365 licenses for a group of users from CSV file

A recent question over at the Spiceworks community asked for a PowerShell sample that will go over a list of users imported via CSV file and remove any and all Office 365 licenses for each user. Since this is a question I’ve seen asked previously, I decided to write a quick blog post about it and add some additional notes besides the actual code.

The first step is to make sure we have a proper input file. You can easily prepare such by using the Get-MsolUser cmdlet and filtering out users based on specific criteria, or you can just populate it manually via Excel. The important thing is that you have at least one column that designates users unambiguously. The UserPrincipalName or ObjectId properties should do. You can use other properties as necessary, but make sure to adjust the code below to account for that, as it expects to see a column named UserPrincipalName in the input CSV file.

Once we have the list of users, the task of removing licenses is a simple one. The only tricky part is that we actually need to have a list of licenses to remove, as there is no -RemoveAllLicenses switch or similar. Thus, for each user we will first run the Get-MsolUser cmdlet and gather the list of currently assigned SKUs and store them in the $SKUs variable. If said variable is empty, say because the user has no licenses assigned or no matching user was found, we skip to the next user. Then, for each individual license we can go ahead and run the Set-MsolUserLicense cmdlet.

One last remark is due here – licenses can also be assigned by using the group-based licensing feature. If that’s the case, using the Set-MsolUserLicense cmdlet will throw an error, so we can add a simple check in the script to avoid that. Instead, you should use the Azure AD blade in the Azure portal to adjust the group-based license.

Without further ado, here’s the code that does the trick. Make sure to update it to reflect the path to the CSV file and make sure that the CSV file has a column named UserPrincipalName (or adjust that in the code below):

$users = Import-Csv .\Users-to-disable.csv

foreach ($user in $users) {
Write-Verbose "Processing licenses for user $($user.UserPrincipalName)"
try { $user = Get-MsolUser -UserPrincipalName $user.UserPrincipalName -ErrorAction Stop }
catch { continue }

$SKUs = @($user.Licenses)
if (!$SKUs) { Write-Verbose "No Licenses found for user $($user.UserPrincipalName), skipping..." ; continue }

foreach ($SKU in $SKUs) {
if (($SKU.GroupsAssigningLicense.Guid -ieq $user.ObjectId.Guid) -or (!$SKU.GroupsAssigningLicense.Guid)) {
Write-Verbose "Removing license $($Sku.AccountSkuId) from user $($user.UserPrincipalName)"
Set-MsolUserLicense -UserPrincipalName $user.UserPrincipalName -RemoveLicenses $SKU.AccountSkuId
else {
Write-Verbose "License $($Sku.AccountSkuId) is assigned via Group, use the Azure AD blade to remove it!"

Some final remarks. The script can produce some information output via the Write-Verbose statements, if you want to see this info make sure to set the value of the $VerbosePreference variable to “Continue”. If you want additional output, such as detailed logging or producing a list of users for which licenses could not be removed, feel free to adjust the code. And you might want to expand on the error handling of the script 🙂

UPDATE: the script had some logic issues which Tony Redmond was able to catch, so thank him for the updated version 🙂

This entry was posted in Azure AD, Office 365, PowerShell. Bookmark the permalink.

10 Responses to Remove all Office 365 licenses for a group of users from CSV file

  1. Danny Roberson says:

    Would there be a way to make this attack on one type of directly assigned license?

    • Vasil Michev says:

      Sure, just put another check inside the

      foreach ($SKU in $SKUs)

      loop. For example:

      if ($SKU.AccountSkuId -ne “TENANT:LICENSE_YOU_WANT_REMOVED”) { continue }

      • Danny Roberson says:

        Awesome, so (bear with me I am a very novice powershell user so learning as I go) would need to replace the first if statement?:

        if (($SKU.GroupAssigningLicense.Guid -ieq $user.ObjectId.Guid) to:

        if (($SKU.AccountSKUId -ne “DOMAIN:STUDENTWOFFPACK_IW_STUDENT” -ieq $user.ObjectId.Guid)

        I used this to remove any license before and it worked beautifully, but now I fear I have to target just two license types.

        • Vasil Michev says:

          No need to replace anything, just add the additional line (insert it after the foreach statement, so line 12). That way the script will ignore any license apart from the one you specify in the if statement.

        • Danny Roberson says:

          I got it to work! Woo hoo. It doesn’t seem to want to attack two licenses, just one at a time, but it does work only on the specified I ask for.

  2. Pingback: Remove all Office 365 licenses for a group of users from CSV file via the Azure AD PowerShell module | Blog

  3. Samy says:

    Hi, Great script! I was wondering how this will change with the newer Azure Active Directory PowerShell for Graph module. We have a need to do this with the newer module as it supports MFA for Admin Accounts and also have use cases where we would only Remove Licenses from a list of users. Thank you!


  4. meb says:

    Thank you!

  5. Pingback: Report Office 365 License Assignments to User Accounts - Office 365 for IT Pros

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.