I’ve seen few request for addressing the “remove all permissions a given user has across mailboxes” scenario, so I decided to give it a go. Here we’re talking about mailbox level permissions, and specifically Full Access. A script like that can be useful in scenarios where a given user has been compromised, or is leaving the company, or you simply want to clean up old/unused permissions.
The first issue to solve here is gathering an inventory of all the permissions a user had been granted. To date, there is no easy way to do this in Exchange or its cloud sibling, and we’re effectively left with having to iterate over each mailbox in the organization. For a single user (and a small number of mailboxes), this is relatively simple, as discussed in one of my most popular articles. When you have to perform the same task against a large number of users and have to account for throttling though, using the pipeline method is a no go, thus I’ve also released a full-blown script to gather mailbox permission inventory.
Once we get the list of mailboxes over which a given user has been granted Full Access permissions, the rest of the script is just a simple loop, executing the Remove-MailboxPermission cmdlet as necessary. Some additional plumbing has been added to address throttling, basic error handling and quality of life, including the ability to provide a list of users against which to run the script. As with most other “destructive” cmdlets, I’ve made an effort to support the –WhatIf switch in order to preview the results before actually applying them. Using –Verbose will make the script spill out additional information on every step. Finally, some basic “report” will also be provided.
As usual, I’ve made no attempt to include a comprehensive “connect to Exchange” function, due to the multitude of methods currently available. If an existing remote PowerShell session is detected, it will be reused. If not, the script will try to connect to Exchange Online via the basic authentication method, requiring you to provide credentials in the process. To avoid issues with this, and account for your specific needs, either connect to Exchange Remote PowerShell before running the script or add the corresponding function in code. On the bright side, the script can run against Exchange Server too, as there are no dependencies on Exchange Online connectivity.
Apart form the “check connectivity” function, the script has one other function, namely Remove-UserMBPermissions, which does all the heavy lifting. To provide some flexibility, the –Identity (aliased as “UserToRemove”) parameter supports a comma-separated list of users and also takes pipeline input. Any entries you provide will be checked against the Get-User cmdlet to make sure a valid, unique security principal can be found before running the removal cmdlet.
If a single entry is provided, for the sake of simplicity the script will use the “stupid” pipeline-based method as detailed here. While this is an acceptable approach for a one-off operation, this method is not practical for large environments. To see why, you can use the –Verbose or –WhatIf switch – the output will illustrate that the Remove-MailboxPermission cmdlet is run against each and every mailbox within the organization, regardless of whether the user actually has permissions on them.
A better approach, one based on obtaining the full list of Full Access permissions within the organization before doing the removal, will be used if you’ve provided more than 5 users. This in turns makes the script dependent on the Mailbox permissions inventory script, which you can get from GitHub. After downloading, make sure to place the Mailbox_Permissions_inventory.ps1 script in the same directory as the current one. Once you do that, the script will do a loop over just the mailboxes that actually have Full Access permission entries for a given user, which will help avoid throttling issues and should speed up the script execution in at least some scenarios.
If for some reason we’re not able to obtain the Full access permissions inventory, the “stupid” method will be used instead, so the script should still work. If you want to always use the “proper” method or change the number of values for which it will be triggered, adjust the relevant setting in the if statement of line 109.
In addition, two other parameters are added in case you want to cover Shared (-IncludeSharedMailboxes) and room/equipment (-IncludeResourceMailboxes) mailboxes respectively. Lastly, the function supports the –Verbose and –WhatIf parameters as mentioned above. All the parameters can be passed directly to the script as well.
By default, the script will run against all user mailboxes and remove any Full Access permission entries for the user(s) you provided:
.\Remove_user_MBpermissions.ps1 -Identity vasil
To do the same for a set of users, use the following syntax:
.\Remove_user_MBpermissions.ps1 -Identity AdeleV,IsaiahL,DebraB,PradeepG
To cover all mailbox types and preview the changes before committing:
.\Remove_user_MBpermissions.ps1 -Identity AdeleV,IsaiahL,DebraB,PradeepG,admin -IncludeSharedMailboxes -IncludeResourceMailboxes -WhatIf
Lastly, the script will also spill out a CSV file, detailing the permissions that were removed, which you can find in the working directory.
Without further ado, you can find the script over at GitHub. Here’s also the relevant help file. You can refer to it or the built-in script help for some examples on how to run it and description of the relevant parameters.
Before I forget, the script should also run fine on-premises, though I only did a handful of tests against my Exchange 2019 box, so no guarantees.
It’s also worth mentioning some other scripts that might be relevant. If you want to address the “remove folder permissions” scenario as well, refer to the script detailed in this article. Similarly, this article addresses the scenario where you want to ‘clear’ user’s membership, as in remove him from all groups within Office 365.
2 thoughts on “Script to remove mailbox permissions for a user, in bulk”