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.

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

  1. Doug Traylor says:

    I have a script that calls this script with all the switches and verbose. What would be the best way to send all the verbose output to a TXT file as a log?
    Thanks again.

  2. Doug Traylor says:

    Where will you be hosting your code once Microsoft shuts down the Technet Gallery?

    • Vasil Michev says:

      All of them are over at GitHub, but there’s always the occasional link I’ve failed to update… 😀

  3. Doug Traylor says:

    Thank you! Great script and exactly what I/we needed. Using it with a CSV list to remove users from groups in Office 365 upon termination.

    Since AD DirSynced groups error out for us, I added a filter to exclude them in the Group accumulation command.
    Get-Recipient -Filter “(Members -eq ‘$($using:user.Value.DistinguishedName)’) -and (IsDirSynced -eq ‘$false’)”

    Don’t know if that is the best way to do it, but it works. 🙂
    Kinda new at all this.

    Thanks again.

  4. Niraaz says:


    I am absolutely new at this but here goes. I have run the script with the following :

    .\Remove_User_All_Groups.ps1 -Identity (Import-Csv .\Cookery.csv | select -ExpandProperty User) -Whatif -Verbose -IncludeOffice365Groups.

    It completes successfully with the following outputs for each of the users:
    VERBOSE: Processing user “”…
    VERBOSE: Obtaining group list for user “”…
    VERBOSE: User “” is a member of 2 group(s).
    VERBOSE: Removing user “” from group “SIT40516 Certificate IV in Commercial Cookery”
    What if: Removing links from unified group “79f6493f-6d5a-42e5-9fea-3a6e26e5211f” will remove the links permanently.
    VERBOSE: Removing user “” from group “SCCM Current Students”
    What if: Removing links from unified group “2a391430-eb2d-4bf2-b2c5-588cdf9b3515” will remove the links permanently.
    VERBOSE: Processing user “”…

    …. and so on…

    however, when I verify the results in the Admin Centre, the users are still in their relative groups. Is there something I am missing?


    • Vasil Michev says:

      When you run this with the -WhatIf switch, no changes are actually made. It simply shows you what will be changed once you rerun the cmdlet without the switch.

  5. Muhamed Rafeeq says:

    Dear Vasil,
    I am in urgent requirement to remove all the owners and members from a list of 600+ teams and add a new user id as the new owner.
    ( School academic year ended and needs to remove the staffs and students urgently)
    Can you please help me witth a powershell script that calls the teams details from a csv file and do the above action? I can download the group id’s, display name, email id of the teams from Azure active directory as csv.


  6. Sam says:

    Hi Vasil,
    I’m using another script that is already connected to exchange using PowerShell and the script converts the $user mailbox to a shared mailbox and I want this script to be the second part of my script.

    I use param($user) to feed in the username within my script. How can I include this script into the same session so that it doesn’t check to reconnect to exchange and also picks the identity $user

    This would be such a time saver and I really appreciate your help.

    • Vasil Michev says:

      Simply call the script with the -Identity parameter? Or if you prefer you can dot-source it and expose the cmdlet directly.

  7. manoj kumar says:

    Hi Vasil

    Goal is to remove users from Single office 365 group and this script will let you remove from all Office 365 group and its very powerful. How will i run against single Office 365 group.

    • Vasil Michev says:

      Well if it’s a single group, why do you even need a script 🙂 Simply use the corresponding cmdlet, either Remove-DistributionGroupMember or Remove-UnifiedGroupLink.

  8. Magnus says:

    How does the script works with dynamic groups in AAD ? Will it be error or will it just try to remove the users?
    It doesn´t looks like it´s an attribute for dynamic groups on the group itself in AAD.

    • Vasil Michev says:

      It doesn’t, Dynamic DG’s membership is governed by recipient filters, to remove the user you have to edit the filter. The script doesn’t support DDGs.

  9. 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.

  10. 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.

  11. 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.

  12. 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.

  13. 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.

  14. 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…

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.