PowerShell: Export All Exchange Mailbox Folder Permissions In A Format For Further Processing

Within Exchange (on-premise or Online) it’s sometimes helpful to export the delegate permissions that a user can set within their mailbox.  Get-MailboxFolderPermission is the cmdlet which will export that information for a particular folder.  The identifier needs to be in the format “john@contoso.com:\Marketing\Reports”.

That said there’s not an easy way to export the permissions on ALL folders within a mailbox and the output for that command isn’t very helpful for further processing.

So;  script.  It’ll take a mailbox as a parameter and output the permissions on all the mailbox folders (and subfolders) as objects.

I wrote a post about the initial version of the script and how it works in Part 1 here.

The first update, allowing the function to deal with special folders and the root better is here (Part 2).

I’ve also made the script stand-alone now (rather than a function).  So just save this as a .ps1 file and run it with the MailboxToProcess parameter and it will work.

ie;

$MB=Get-Mailbox Ororo.Monroe

c:\scripts\path\New-FolderPermissionReportObjectArray.ps1 -MailboxToProcess $MB
The following is the most recent version of the script;

[CmdletBinding()]
param
(
    [Parameter(Mandatory=$true,
        ValueFromPipeline=$true)]
    [Microsoft.Exchange.Data.Directory.Management.Mailbox]$MailboxToProcess
)
BEGIN
{
    Write-Verbose "Started running $($MyInvocation.MyCommand)"
    [string[]]$FolderExclusions = @("/Sync Issues","/Sync Issues/Conflicts","/Sync Issues/Local Failures","/Sync Issues/Server Failures","/Recoverable Items","/Deletions","/Purges","/Versions")
}
PROCESS
{
    Write-Verbose "Getting array of all mailbox folder permissions"
    Write-Verbose ("Mailbox: "+$MailboxToProcess.PrimarySMTPAddress)

    $FolderNames=$MailboxToProcess| Get-MailboxFolderStatistics | Where-Object {!($FolderExclusions -icontains $_.FolderPath)} |
            Select-Object -ExpandProperty FolderPath | ForEach-Object{$MailboxToProcess.DistinguishedName.ToString() +":"+($_ -replace ("/","\"))}
    $PermissionsList=@()
    Foreach ($FolderName in $FolderNames)
    {
        Write-Verbose "Getting Permissions On $FolderName"
        $FolderName=$FolderName -replace ("Top Of Information Store","")
        $FolderPermissions=Get-MailboxFolderPermission -Identity $FolderName
        foreach ($FolderPermission in $FolderPermissions)
        {
            $PermissionsObject=New-Object -typename PSObject
            $PermissionsObject | Add-Member -MemberType NoteProperty -Name "Identity" -Value ([string]$FolderName)
            $PermissionsObject | Add-Member -MemberType NoteProperty -Name "User" -Value ([string]($FolderPermission.User.ToString()))
            [string[]]$AccessRightsStringArray=@()
            foreach ($Right in $FolderPermission.AccessRights)
            {
                $AccessRightsStringArray+=$Right.ToString()
            }
            if ($AccessRightsStringArray.Count -eq 0)
            {
                Write-Verbose "No Access Rights detected"
                Continue
            }
            if ($AccessRightsStringArray.Count -eq 1)
            {
                $AccessRightsString=$AccessRightsStringArray[0]
            }else
            {
                $AccessRightsString=$AccessRightsStringArray -Join ","
            }
            $PermissionsObject | Add-Member -MemberType NoteProperty -Name "AccessRights" -Value ([string]$AccessRightsString)
            $PermissionsList+=$PermissionsObject
        }
    }
    Return @($PermissionsList | ?{!((($_.User -eq "Default") -or ($_.User -eq "Anonymous")) -and ($_.AccessRights -eq "None"))})
}
END
{
    Write-Verbose "Stopped running $($MyInvocation.MyCommand)"
}

9 Replies to “PowerShell: Export All Exchange Mailbox Folder Permissions In A Format For Further Processing”

  1. Would love to know the version of PowerShell used for this. Trying to do similar things with the pipeline input for the mailbox object type but running into either pipeline is already executing or if I handle that with old methods I’m getting duplicates in my output.

  2. I would love to know the version of PowerShell and Operating System used for this. I’m trying to do something similar with accepting the mailbox object from the pipeline, with 2012R2 and PowerShell 4.0 but running into Pipeline is already executing errors. When I try to address that using new variables in the script with | foreach, that works but I’m getting duplicates in my final output.

    1. Hi. Just tested it on Windows 2008 R2 + PowerShell 2 (the version with Exchange 2010). I piped a variable containing the results of “Get-Mailbox” to it and it worked ok.

      I “.” sourced the script (. [Path the script]) and ran the command with $MBS | New-PermissionReportObjectArray.

      Looking at it I’ve made some improvements though; I’ll post the updated version at the end of the week.

  3. I’m having a bit of trouble getting your script to work as I’m still somewhat a newbie in Powershell. Could you possibly provide at bit more of an explanation as to how is should be used?

    Running the script, I currently get a few errors as can be seen here: http://imgur.com/a/SDges

    I also tried to do a get-mailbox and save that to the $MailboxToProcess variable, to no avail.

    1. Hi. I’ve tweaked it so that it’s no longer part of a function. You should be able to just save it as a script and run it now. I’ve also added a few lines about how to run it. Hope it helps!

  4. Hi, and thanks for responding so quickly.

    I’ve given it another try and now I get an entirely new kind of error 🙂

    This leads me to think that maybe your script is only compatible with Exchange Server – not Exchange Online. Could that be the case?

    Here’s what I did in Visual Studio Code (script saved as Untitled-2.ps1) followed by the error message:

    PS $MB=Get-Mailbox
    PS .\Untitled-2.ps1 -mailboxtoprocess $MB

    .\Untitled-2.ps1 : Unable to find type [Microsoft.Exchange.Data.Directory.Management.Mailbox].
    At line:1 char:1
    + .\Untitled-2.ps1 -mailboxtoprocess $MB
    + ~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (Microsoft.Excha…agement.Mailbox:TypeName) [], RuntimeException
    + FullyQualifiedErrorId : TypeNotFound

    1. Hi. Yes, I only tested this with OnPrem Exchange but there’s no reason it shouldn’t work in a remote PS session to Exchange Online. It’s complaining about the type of the parameter though at the start;

      param
      (
      [Parameter(Mandatory=$true,
      ValueFromPipeline=$true)]
      [Microsoft.Exchange.Data.Directory.Management.Mailbox]$MailboxToProcess
      )

      You could try changing that to a more generic object like;

      param
      (
      [Parameter(Mandatory=$true,
      ValueFromPipeline=$true)]
      [PSObject]$MailboxToProcess
      )

  5. I changed the permission per your suggestion, and now I do in fact get some output, after the script throwing a couple of errors regarding mailbox folders not being found (ManagementObjectNotFoundException).

    The output is, however, not very useful to me in its current form which looks to be just a listing of the complete directory structure of my mailbox where, for some reason, each dir is then listed multiple times. For instance, the entry below, which I’ve included as an example, is listed 5 times.

    Identity
    ——–
    CN=Søren ,OU=.onmicrosoft.com,OU=Microsoft Exchange Hosted Organizations,DC=EURPR07A001,DC=prod,DC=outlook,DC=com:\Clutter

    I’m wondering if the full output simply can’t be displayed properly in the terminal screen and therefore I should export the data? Whether that’s the case or not, I would like very much if you could explain how I should go about doing the data export? I know how to dump the contents of a var to CSV, but I’m unsure of how and where I should implement an export-csv in your script.

    If you believe that I lack knowledge about some PowerShell or general scripting concepts that are essential to understanding the inner workings of the script, then please do not hesitate to let me know.

    Thanks for your patience and help this far.

    1. Hi. Yes, that’s right, it outputs an stream of objects, each representing a permission on a folder. If you have lots of permissions on a single folder you will get a lot of output objects. The theory is you can take this output and then do further processing with it. By default the output goes to the screen (Host) and some of the fields are dropped to make it fit.

      If you assign the output of the script to a variable you can have a play;

      $Output=c:\scripts\path\New-FolderPermissionReportObjectArray.ps1 -MailboxToProcess $MB

      And then you can do;

      $Output | FL
      To get a full list of all the data in each.

      Or you could filter it;

      $Output | Where-Object {$_.AccessRights -eq “Owner”} | Fl

      You can use the output to get the mailboxes involved, list all the folders a user has access to, list all the non-default permissions etc.

Leave a reply to h3rring Cancel reply