0

When doing O365 migrations, part of the 'Planning' session includes an analysis of how users Share and give access to each others calendars and folders. I have this Function wrapped inside a ForEach loop which gets those permissions via native Exchange PS cmdlets:

Function Pull-MBXFolderPerms {
Param ([string]$MBXName)
    Start-Sleep -Milliseconds 600
        $Mailbox = '' + $MBXName
        $Folders = Get-MailboxFolderStatistics $Mailbox | % {$_.folderpath} | % {$_.replace("/","\")}
        Write-host "Processing folders on mailbox $Mailbox"

ForEach ($Fold in $Folders) {
            $FolderKey = $Mailbox + ":" + $Fold
            $Permissions = Get-MailboxFolderPermission -identity $FolderKey -ErrorAction silentlycontinue
            $FolderPerms += $Permissions | ? {$_.User -notlike "Default" -and $_.User -notlike "Anonymous" -and $_.AccessRights -notlike "None" -and $_.AccessRights -notlike "Owner" } | Select-Object @{name='Mailbox';expression={$MBXName}},FolderName,@{name='UserWithAccess';expression={$_.User -join ','}},@{name='AccessRights';expression={$_.AccessRights -join ','}}
}
    Return $FolderPerms
}

When doing this in bulk it takes days to complete in a large environment because there is an LDAP lookup on EACH ACE on every folder so that the User's Displayname can be shown in the results.

In order to speed this process up, I want to record the Security Descriptor off of the folder in its SDDL format to bypass the lookup on each ACE. I can then do th lookup later in bulk rather than opening and closing an LDAP session on each ACE

This code can be used to 'Loop' through ACEs for file systems:

$addACL=[System.Security.AccessControl.DirectorySecurity]::new($Fold,'Access')).GetSecurityDescriptorSddlForm(('Access'))
    # Remove leading and trailing parenthesis from ACLs 
        $splitFirst = $addACL.split("(")
        $splitDone = $splitFirst.TrimEnd(")")
    # Filter for explicit permissions and remove implicit deny from each ACL
    ForEach ($ACE in $splitDone) {
        If ($ACE.Contains("ID")) {
                continue
        }
    ElseIf ($FinalACE = $ACE | where {$ACE -notlike 'D:AI' -and $ACE -notlike 'D:PAI'}) {

        $Script:ACLOutput += New-Object PSObject -Property @{
    
        FullName = $Fold
        sddlACE = $FinalACE
        }   
    }   
}

I am looking for a similar way of doing this with Exchange Mailbox folders and am at a loss as to how to get to the SDDL. We would also like to do this natively without using MFCMAPI

Any help would be appreciated!

PJBuckley
  • 13
  • 3
  • In your function, variable `$FolderPerms` comes from nowhere. Since you are adding to it with `+=` you are expecting an array, but doing it that way will gobble up time and memory. Just have the function output the permissions and capture that when calling it like `$FolderPerms = Pull-MBXFolderPerms`. Next, without wildcards, the `-like` operator works as `-eq` (same for `-notlike`) – Theo Dec 15 '22 at 14:44
  • All of the above code works in production, we have yet to encounter the issue you are refering to when running the above code. Thanks. – PJBuckley Dec 16 '22 at 16:43

0 Answers0