Quickly list all mailboxes to which a particular user has access

​This question seems to get asked a lot, and people are unaware how easy the answer really is. Here it is:

  • List all mailboxes to which a particular user has Full Access permissions:
PS C:\> Get-Mailbox | Get-MailboxPermission -User vasil

Identity             User                 AccessRights

--------             ----                 ------------
HuKu                 Vasil Michev         {FullAccess}
retail               Vasil Michev         {FullAccess}
sharednew            Vasil Michev         {FullAccess}
testplan2            Vasil Michev         {FullAccess}
WC                   Vasil Michev         {FullAccess}
  • List all shared/user/room/whatever mailboxes to which particular user has Full Access permissions:
PS C:\> Get-Mailbox -RecipientTypeDetails UserMailbox,SharedMailbox -ResultSize Unlimited | Get-MailboxPermission -User vasil

Identity             User                 AccessRights

--------             ----                 ------------
HuKu                 Vasil Michev         {FullAccess}
retail               Vasil Michev         {FullAccess}
sharednew            Vasil Michev         {FullAccess}
testplan2            Vasil Michev         {FullAccess}
  • List all mailboxes to which members of a particular security group have access:
PS C:\> Get-Mailbox | Get-MailboxPermission -User secgrp

Identity             User                 AccessRights
--------             ----                 ------------
Bathroom             secgrp               {FullAccess}
  • List all mailboxes to which a user has Send As permissions:
PS C:\> Get-Mailbox | Get-RecipientPermission -Trustee vasil

Identity                            Trustee                             AccessControlType                   AccessRights
--------                            -------                             -----------------                   ------------
sharednew                           Vasil Michev                        Allow                               {SendAs}
  • List all user mailboxes to which members of a particular security group have Send As access:
PS C:\> Get-Mailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited | Get-RecipientPermission -Trustee secgrp

Identity                            Trustee                             AccessControlType                   AccessRights
--------                            -------                             -----------------                   ------------
HuKu                                secgrp                              Allow                               {SendAs}
  • List all mailboxes to which a particular security principal has Send on behalf of permissions:
PS C:\> Get-Mailbox | ? {$_.GrantSendOnBehalfTo -match "vasil"}

Name                      Alias                ServerName       ProhibitSendQuota
----                      -----                ----------       -----------------
Bathroom                  bathroom             amspr03mb084     49.5 GB (53,150,220,288 bytes)
WC                        WC                   dbxpr03mb096     9.5 GB (10,200,547,328 bytes)

There will be slight differences if you are running this against on-prem Exchange, but remember that you can also look at the AD attributes there (msExchDelegateListLink and msExchDelegateListBL). 

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

62 Responses to Quickly list all mailboxes to which a particular user has access

  1. josh says:

    : The term ‘get-mailbox’ is not recognized as the name of a cmdlet, function, script file, or operable
    program.

  2. steve says:

    is this valid for Office 365 also? We have hybrid environment running on prem and cloud. while this gave me output from the exchange server does this also cover mailboxes that are only on the cloud?

    • Vasil Michev says:

      You can run the same cmdlets in EO Remote PowerShell. Cross-prem permissions should be listed where appropriate, if that’s what you mean.

  3. James says:

    Hi Vasil

    How would we find out who’s calendars a user has access to and what level of access they have?

    • Vasil Michev says:

      James, Calendar and folders in general are a bit trickier, as permissions can be given on multiple levels. That is directly to the user, or via the Default level, or via Group, etc. If you only care about direct assignment, something like this should work:

      /// Get all the Calendars (folder name can be localized)
      $calendars = Get-Mailbox -RecipientTypeDetails UserMailbox | Get-MailboxFolderStatistics | ? {$_.FolderType -eq “Calendar”} | select @{n=”Identity”; e={$_.Identity.Replace(“\”,”:\”)}}

      ///Check which Calendars user XXX has access to:
      $calendars | % {Get-MailboxFolderPermission -Identity $_.Identity -User vasil -ErrorAction SilentlyContinue}

      • Justin Irving says:

        Thanks for this great post. I learnt about Calculated Properties!

        • Muhammad Kamran Khan says:

          Hello Can you tell me how export list of users have calender permssion on which mailbox calander i want output in CSV with email address

          • Muhammad Kamran Khan says:

            Your command running perfectly but not showing output when i See Using $calendar, it give blank result. i think some thing need to be done this portion

            | select @{n=”Identity”; e={$_.Identity.Replace(“\”,”:\”)}}

            can you revert back i am stuck in between, i have 1000 users . i need to check whether who has permission 1000 users calendar and 1000 users have permission on whom mailbox calendar. want output in excel.

      • Muhammad Kamran Khan says:

        Hello Can you tell me how export list of users have calender permssion on which mailbox calander i want output in CSV with email address

        Your command running perfectly but not showing output when i See Using $calendar, it give blank result. i think some thing need to be done this portion

        | select @{n=”Identity”; e={$_.Identity.Replace(“\”,”:\”)}}

        can you revert back i am stuck in between, i have 1000 users . i need to check whether who has permission 1000 users calendar and 1000 users have permission on whom mailbox calendar. want output in excel.

        • Vasil Michev says:

          Calendar permissions are a bit trickier, as you can have multiple entries affecting the same user (i.e. you need to check the Default entry too), you need to check for the actual Calendar folder name, and so on.

          In general, you can do something like this:

          Get-Mailbox | % { Get-MailboxFolderPermission (($_.PrimarySmtpAddress)+”:\Calendar”) -User vasil -ErrorAction SilentlyContinue} | select Identity,User,AccessRights

          But that’s very simplistic and some major improvements can be made. I’m doing a Permissions Inventory series for Cogmotive now, I’ll do a Calendar permissions article as part of those in the near future and provide sample script.

          • Muhammad Kamran Khan says:

            Thanks Vasil, can you help me out. i am in mid of migration. 1000 user have permission on others mailboxes Calendar which are either on-premises / Cloud. same i need vice versa those have permission on 1000 mailbox. i need report in Excel.

            realy appreciate if you help me create short script. thanks in Advance.

          • Muhammad Kamran Khan says:

            I am getting error by running above command.

            foreach : Method invocation failed because [Microsoft.Exchange.Data.SmtpAddress] does not contain a method named
            ‘op_Addition’.
            At line:1 char:15
            + Get-Mailbox | foreach{Get-MailboxFolderPermission (($_.PrimarySmtpAddress)+”:\Ca …
            + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            + CategoryInfo : InvalidOperation: (op_Addition:String) [ForEach-Object], RuntimeException
            + FullyQualifiedErrorId : MethodNotFound,Microsoft.PowerShell.Commands.ForEachObjectCommand

          • Vasil Michev says:

            If you are doing this On-Prem, put a ToString() to get the proper value. This should work:

            Get-MailboxFolderPermission (($_.PrimarySmtpAddress.ToString())+”:\Calendar”) blablabla

      • Chad E says:

        So this is only giving me output about what permissions the specified user has but it doesn’t tell me to which mailbox they have the permissions to .. am i missing something?

        • Vasil Michev says:

          Which one of the examples is “this”? In most of them, the Identity column designates the mailbox on which the permissions are granted.

          • Chad E says:

            Apologies, this function

            // Get all the Calendars (folder name can be localized)
            $calendars = Get-Mailbox -RecipientTypeDetails UserMailbox | Get-MailboxFolderStatistics | ? {$_.FolderType -eq “Calendar”} | select @{n=”Identity”; e={$_.Identity.Replace(“\”,”:\”)}}

            ///Check which Calendars user XXX has access to:
            $calendars | % {Get-MailboxFolderPermission -Identity $_.Identity -User vasil -ErrorAction SilentlyContinue}

          • Vasil Michev says:

            Right, this example is simply missing the select operation at the end, try it like this:

            $calendars | % {Get-MailboxFolderPermission -Identity $_.Identity -User vasil -ErrorAction SilentlyContinue | select Identity,User,AccessRights}

            I’ve published a more detailed script for that, check it out here: https://gallery.technet.microsoft.com/Office-365-Calendar-29ef6211?redir=0

  4. Kevin Payton says:

    I have a list of users (Approximately 300) that I need to find out what Shared Mailbox’s they have access to. I assume I can use the PS command:

    Get-Mailbox -RecipientTypeDetails UserMailbox,SharedMailbox -ResultSize Unlimited | Get-MailboxPermission -User vasil

    But I don’t want to run that 300 Times 🙂 I have the 300 Users in a Excel document. How would I inject that in and have it exported to a xls document?

    • Vasil Michev says:

      That’s a loot of looping, I’d suggest using some permission inventory script.

      But something like this can work:

      $sharedmailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited

      Import-CSV blabla.csv | % {
      $sharedmailboxes | Get-MailboxPermission -User $_.User }

      where the blabla.csv file contains the user list under a column called “User”.

      Pretty sure you’d get throttled though, so maybe add some delay in between the iterations (Start-Sleep 3 or similar).

  5. Kevin Payton says:

    That appears to list Every Shared Mailbox in the Organization alone with the users. We have about 18,000 associates so Yeah Is there a way to zero that down a little more? I ran the first list with only 106 people in it, but it was grabbing names from more than just that.

    • Vasil Michev says:

      The name for the column that designates users in your CSV file needs to match the one in the script, otherwise the Get-MailboxPermission will return all permissions (including the “default” ones).

  6. Eddie says:

    Hello

    I cannot see the name of mail box as the identity path is too long. Have outputted the command to text file but still i just get

    Domain.local/London/…
    Domain.local/London/…
    Domain.local/London/…

    Am I am doing something stupid?

    Thank you !

  7. Steph says:

    Hi,

    I have logged into 365 using powershell and it has connected fine – but ”Get-Mailbox’ command is not working.

    PS C:\scripts> PS C:\ Get-Mailbox -RecipientTypeDetails UserMailbox,SharedMailbox -ResultSize Unlimited | Get-MailboxPermission -User DanielleA
    Get-Process : A positional parameter cannot be found that accepts argument ‘Get-Mailbox’.
    At line:1 char:1
    + PS C:\ Get-Mailbox -RecipientTypeDetails UserMailbox,SharedMailbox -R …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [Get-Process], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetProcessCommand

    Please can you help?
    Thanks

  8. John says:

    Hello!

    We have a huge directory so I tried to use the Get-Mailbox -OrganizationalUnit and it sort of worked. But when I add the | Get-MailboxPermission -User then it results in just nothing. If I remove the “-User” and only have the | Get-MailboxPermission then it lists all the permissions of the users in the specific OU which is too much.

    How can I see the permission of a single user without having to loop through all the users in the directory?

    • Vasil Michev says:

      It should work just fine with OU based or any other type of filter. No output from the cmdlets simply means the user has no permissions on any of the mailboxes in the scope of the filter.

  9. Pingback: List mailboxes user has Full Control permissions to – Just another WordPress site

  10. Rashi says:

    Hi Vasil,

    I have connected to O365 using powershell and run the above commands like
    get-mailbox -ResultSize Unlimited| get-mailboxpermission -User “XXXX” | fl id* however it does not give any output and shows like this “WARNING: By default, only the first 1000 items are returned. Use the ResultSize parameter to specify the number of items returned. To return all items, specify “-ResultSize Unlimited
    “. Be aware that, depending on the actual number of items, returning all items can take a long time and consume a large amount of memory. Also, we don’t recommend storing the results
    in a variable. Instead, pipe the results to another task or script to perform batch changes.

    • Vasil Michev says:

      That’s simply because you have a large number of mailboxes in the company, and only a limited number are returned by default. Use the second example instead or this cmdlet:

      Get-Mailbox -ResultSize Unlimited | Get-MailboxPermission -User vasil

  11. Stephen Watson says:

    Hi Vasil,

    This is fantastic. Thanks for posting. I have a question though, using the command to get send as permissions. However this isn’t showing up all results. For instance, it is showing me shared mailboxes that were created in exchange online, but the ones that were imported from our old on-prem exchange are not showing up.

    Can you think of a possible reason for this?

    Thanks

    Steve

    • Vasil Michev says:

      Cross-premises Send As permissions are not supported, if that’s what you mean? Or you mean migrated mailboxes?

      • Stephen Watson says:

        Sorry, they are migrated mailboxes. They all reside in the same tenant now.

        • Vasil Michev says:

          They should be covered too. Make sure you use the -ResultSize Unlimited parameter and try not filtering by recipient type.

  12. Dusty says:

    Is there a way to list out the mailboxes a user has then remove the user as in the case of a terminated user?

    • Vasil Michev says:

      If I understand you correctly, this should do it:

      Get-Mailbox -RecipientTypeDetails UserMailbox,SharedMailbox -ResultSize Unlimited | Remove-MailboxPermission -User user@domain.com -AccessRights FullAccess -Confirm:$false

      It will generate Warning messages for all mailboxes the user doesn’t have access to, but you can just ignore those. Or just write a proper script to handle this 🙂

  13. Troy says:

    I am trying to get a folder count for individuals that include all mailboxes they have access to. I tried the following however it did not return what I was expecting. Any direction on this would be greatly appreciated.

    Get-Mailbox -ResultSize Unlimited | Get-MailboxPermission -User trosmi | Get-MailboxFolderStatistics |%{$_.folderID} | measure-object | fl count | Export-Csv -NoTypeInformation resultaug2.csv

    Thank You
    Troy

    • Vasil Michev says:

      Not sure what you are expecting here? The example you gave above will return the number of folders across all mailboxes the user has access. Do you perhaps want to count them per mailbox or?

  14. jeremy says:

    Hello

    i am trying to find out the correlation of the send-as, send-on.-behalf and delegate for my on-premise users to know what will break when i move certain users to Office 365 since the above doesnt support cross-permission.

    would you happen to know how?

    • Vasil Michev says:

      Best thing to do is to contact the FastTrack center – they have a ready PowerShell script you can use for that. We’re not allowed to distribute it, sorry.

  15. kumar says:

    Hi

    How to get, the user in exchange server to whom send the mail and from whom he has got mail details in Exchange server 2016.

  16. milen nikolov says:

    Hello

    i looking for command for :
    i need 1 accunt which can send mail for all user send as behalf coukd you help me

    • Vasil Michev says:

      There is no one command that will work for all, the permissions need to be added to all users that currently exist (Get-Mailbox -RecipientTypeDetails UserMailbox | Set-Mailbox -GrantSendOnBehalfTo user), and repeat the same for any newly added mailboxes.

  17. Dan says:

    How would I structure my script if I wanted to get mailbox permissions for users that are members of a group that has full-access permission to a mailbox? The group would be different for each mailbox and they may still have directly assigned full-access permission to a mailbox as well, so I’d like the search to be recursive to groups that have full access. I already know the syntax for ignoring inherited permissions and specific system assigned permissions. I just can’t figure out how to get powershell to check for a specific user within a group that has mailbox permission.

    • Vasil Michev says:

      That scenario calls for a proper script, and not the one-liner approach presented in this article. But in nutshell, you get the permissions, check the recipient type of the “User” value (as User objects are represented by the UPN in O365 now, you can just check for the presence of the @ sign), then if it’s a group, use the relevant cmdlets to expand the membership. Store the results in a variable or CSV file, then check against each user you care about.

      • Dan says:

        Thanks! I think I’ll approach it as storing results of each query in a variable then running a comparison and seeing if the group permissions on the mailbox match one of the groups a user is a member of. I appreciate the feedback.

  18. Ravi says:

    hey can u tell me how to find user’s listing from mailboxsubfolder. I used below
    $inbox = Get-Mailbox -Identity $Id | Get-MailboxFolderStatistics | ? {$_.FolderType -eq “Inbox”} | select @{n=”Identity”; e={$_.Identity.Replace(“\”,”:\”)}}
    $inboxlist = ($inbox | % {Get-MailboxFolderPermission -Identity $_.Identity}).Identity

    can u tell me how to find users list under inbox.

    • Vasil Michev says:

      That should do it, simply replace Identity with User at the end:

      $inboxlist = ($inbox | % {Get-MailboxFolderPermission -Identity $_.Identity}).User

      Or a faster variant:

      Get-Mailbox blabla | Get-MailboxFolderStatistics -FolderScope Inbox | select @{n=”Identity”; e={$_.Identity.Replace(“\”,”:\”)}} | Get-MailboxFolderPermission | select User,AccessRights

      • Ravi says:

        That thing I knew, I want subfolder of inbox userlisting, not inbox userlisting.

        • Vasil Michev says:

          So just enumerate the folders under Inbox then. Don’t use FolderType as a filter, as that will change the output of the Identity parameter. You can still filter them out client-side:

          Get-Mailbox blabla | Get-MailboxFolderStatistics | ? {$_.FolderPath -like “/Inbox/*”} | select @{n=”Identity”; e={$_.Identity -replace ‘^([^\\]+)\\’,’$1:\’}} | Get-MailboxFolderPermission | select FolderName,User,AccessRights

  19. Minto says:

    Hi Vasil,

    I am not able to get any info with this commands. See below error and help.

    WARNING: By default, only the first 1000 items are returned. Use the ResultSize parameter to specify the number of
    items returned. To return all items, specify “-ResultSize Unlimited”. Be aware that, depending on the actual number of
    items, returning all items can take a long time and consume a large amount of memory. Also, we don’t recommend storing
    the results in a variable. Instead, pipe the results to another task or script to perform batch changes.

    • Vasil Michev says:

      You seem to have over 1000 mailboxes in the organization, so you will have to run the cmdlets with the -ResultSize Unlimited switch.

  20. Bstoller says:

    Nice commands ! Thx!

  21. PETIT CHRISTOPHE says:

    Hello, great job !
    Is there any way to list acces on all mailboxes ???
    Thanks

  22. Savio says:

    Hi Vasil
    Thanks for the above command …
    How do I get the mailbox name under ” identity ” instead of the path as below

    Identity User AccessRights IsInherited Deny
    ——– —- ———— ———– —-
    abc.ae/XYZX/Grou… ABC\savio {FullAccess} False False
    abc.ae/XYZX/Grou… ABC\savio {FullAccess} False False

    Appreciate

    Best Regards
    Savio

    • Vasil Michev says:

      You can use calculated properties:

      Get-Mailbox | Get-MailboxPermission -User vasil | select @{n=”Identity”;e={(Get-Mailbox $_.Identity).DisplayName}},User,AccessRights

      As this is a string value though, and not the full object, it can lead to duplicate/missing results

      • savio says:

        After running the above command , I do get the identity properly except that some are missing

        Identity User AccessRights
        ——– —- ————
        ABC\savio {FullAccess}
        Info Sec ABC\savio {FullAccess}

        Any idea ?

        Thanks

        • Vasil Michev says:

          I told you it’s not a perfect solution, you should avoid using any attribute that returns a simple string, non-unique value. This one should be a bit better:

          Get-Mailbox | % { Get-MailboxPermission $_.PrimarySmtpAddress -User vasil | select @{n=”Identity”;e={(Get-Mailbox $_.Identity).DisplayName}},User,AccessRights }

          But it still doesn’t solve issues with duplicates.

Leave a Reply

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