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)"
}

7 thoughts on “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
      )

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s