Script to remove user(s) from all groups in Office 365

Often times when a user leaves the company, or for whatever other reason, you are tasked with making sure said user is removed as member from any and all groups. In the Office 365 world, this means going over each Security, Distribution, Mail-Enabled Security and Office 365 (Modern) group and removing the user. If you are a fan of the UI approach, you can simply navigate to the Office 365 Admin Center, find and click on the user in the list of Active users, then click the Edit button next to Group membership and press the small X next to each group object.

While this approach works and is easy enough to follow, having to perform the same task over and over again is definitely not something I enjoy, so prepared a short script for this scenario. We have already discussed the quickest way to list all groups given user is a member of in a previous article, so half of the script was already done. After obtaining the list, all that’s left is to iterate over each group and depending on the group type, use the relevant cmdlet to remove the user. Now, as we deal with few very different group types, different cmdlets and even modules will be needed. For any Exchange-related groups, we can of course use the Remove-DistributionGroupMember cmdlet. Exchange remote PowerShell also exposes the cmdlet needed to handle Office 365 Groups: Remove-UnifiedGroupLinks. To handle Azure AD Security groups however, we need the Remove-AzureADGroupMember cmdlet and thus the AzureAD PowerShell module.

To add some flexibility to the script, few parameters have been introduced to handle the different group types. By default, only Exchange-related groups will be handled¬†(DGs and MESGs). To include Office 365 Groups, use the –IncludeOffice365Groups switch. To include Azure AD Security groups, use the –IncludeAADSecurityGroups switch. The -Identity parameter has been coded to accept multiple user objects as an array, and to also handle pipeline input. Any valid user identifier will be accepted, but it’s strongly recommended to use unique-valued properties such as UPN or PrimarySmtpAddress.

To simulate the script action without making any actual changes, which is a very good idea when trying to use it against a large number of objects, use the –WhatIf switch. Lastly, for troubleshooting purpose you can specify the –Verbose switch and get additional information about each step of the script execution. While the script includes some basic code to handle connectivity to Exchange Online and/or Azure AD PowerShell, this will not work in all scenarios. Make sure to execute your “connect to Office 365” script first and establish any needed sessions, otherwise the script will halt.

Combining all of the above, the script does the following:

  • Checks for connectivity to ExO and/or AzureAD
  • Builds a list of all the users to process, removing any invalid entries
  • For each user, obtains the list of all Exchange groups
    • If the –IncludeOffice365Groups switch is used, the list will include Office 365 Groups as well
  • For each group in the list, the relevant cmdlet is issued to remove the user as member
  • If the switch –IncludeAADSecurityGroups ¬†is used, Azure AD groups are enumerated next
  • For any Azure AD group returned, the Remove-AzureADGroupMember cmdlet is run to remove the user as member

If you are running the script against a large number of users, or if the user is member of to many groups, potential throttling issues might arise. To address those, a small artificial delay is added on lines 104 and 117, feel free to adjust it as needed. Additional information about the script usage and parameters can be found in the built-in help.

You can find the script on the TechNet Gallery here:

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

12 Responses to Script to remove user(s) from all groups in Office 365

  1. John says:

    Hey Vasil,
    Great job on the script. Since this handles O365 Groups, I was wondering if removing users like this as part of a deprovisioning process will auto-remove them from any MS Teams of which they were members?

    Also, have you had any success dealing with ‘orphaned’ members in Teams that show up as ‘Unknown User’? Can this script or a variant be used to perform housekeeping on existing orphaned Team members?

    • Vasil Michev says:

      It should, although there might be slight delay due to the “loose coupling” model utilized by O365 Groups. But it’s best to use the Team cmdlets/APIs when dealing with Team members.

      The UU members are a known issue, and it’s beyond me what exactly is taking Microsoft so long to fix it. You’d figure concept as basic as membership should be polished out from the start, but alas…

  2. eys says:

    Question, I am a newbie when it comes to PS. I was wondering how do I pass on a CSV file to the script. It only asks for identity when I ran the script.

    • Vasil Michev says:

      Something like this:

      Import-CSV blabla.csv | % { .\Remove_User_All_Groups.ps1 -Identity $_.User }

      where blabla.csv has a column named User, containing the user identifier.

  3. gino says:

    Where on the script can you place this line so I don’t have to input each user:

    Import-CSV blabla.csv | % { .\Remove_User_All_Groups.ps1 -Identity $_.User }

    • Vasil Michev says:

      It’s not *in* the script, you’re basically going to call the script numerous times, once for each user in the CSV file.

  4. Gino says:

    Vasil, So the script is is called everytime a user in the csv is entered so if i had 50 users the script will run 50 times?
    IS there a way for the script to just call the csv once and run thru a loop and exceute the remove cmdlt

    • Vasil Michev says:

      Doesn’t make much of a difference really, whether it’s a single script execution or 50x, it will still do the loop over each user 50 times to handle this case. If you want to do it on a “single” run, use this:

      .\Remove_User_All_Groups.ps1 -Identity (Import-Csv .\test.csv | select -ExpandProperty User) -WhatIf -Verbose

      where you have a property User in the test.csv file.

  5. nvader2000 says:

    This script does not work under PS 5.1, or am I missing something?

    “Remove-UserFromAllGroups : The term ‘Remove-UserFromAllGroups’ is not recognized as the name of a cmdlet, function, script file, or
    operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.”

    Please advise.

    • Vasil Michev says:

      You are calling the cmdlet, not the script. If you want to use the cmdlet, you need to dot-source the script beforehand.

  6. Ben Dyke says:

    Do you know what happens if the user is the only member and owner of a Microsoft Team?

    • Vasil Michev says:

      It will throw an error, that’s a limitation of the cmdlet. You can certainly update the script to auto-add/promote another user as owner for such groups/teams.

Leave a Reply

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