SOLVED

Recursive Script to Get/Set/Remove Exchange Mailbox Folder Permissions

Brass Contributor

Okay, I have a tiny issue.  I'm okay at PS scripting, not a guru by any stretch of the imagination.  So here's the situation.

 

Situation:

  • Mailbox needs to move from on-prem to Exchange Online.  I know how to do this...easy peasy.
  • Mailbox move request errors out because of invalid permissions on some of the folders.
  • Mailbox contains 12,053 folders.
  • I have a one line command that will go and get all of the folder names and spit them out on the screen.  It works just fine.
    • $folders = Get-Mailbox <Alias> | ForEach-object {Get-MailboxFolderStatistics -Identity $_.alias | Select-Object Identity, ItemsInFolder, DeletePolicy, FolderSize}; $folders | Out-GridView
  • I expanded upon that and went out to the Internet and found one that will recursively get the folder list and the permissions for each folder:
    • $Perms = ForEach ($f in (Get-MailboxFolderStatistics <Alias> | Where {$_.FolderPath.Contains("/") -eq $True } ) ) {$fname = "<Alias>:" + $f.FolderPath.Replace("/", "\"); Get-MailboxFolderPermission $fname}; $Perms | Out-GridView

Problem:

  • For most mailboxes, this command works fine.  However, this mailbox is determined to make me have a mental breakdown.  In the folder names, they have used forward slash "/", open and close braces "[", "]", colons ":", hyphens "-", At signs "@", open and close parenthesis "(", ")", and ampersands "&".
  • If I manually enter all those characters into the Get-MailboxFolderPermission command for the folder name, with quotes around the entire thing, it doesn't have any issue.
    For example: Get-MailboxFolderPermission -Identity "<Alias>:\2023 Meetings/Trips/Events\02 February\[02/05 2:00-3:00 pm Telecon w/XYZ & Joe Smith]"
  • If I run:  Get-MailboxFolderPermission and that long, screwed up path, it works fine.
  • If I run:  Get-MailboxFolderStatistics with that same Identity value, I get:

Unable to retrieve mailbox folder statistics for mailbox <Alias>:\2023 Meetings/Trips/Events\02 February\[02/05 2:00-3:00 pm Telecon w/XYZ & Joe Smith]. Failure: Couldn't find '<Alias>:\2023 Meetings/Trips/Events\02 February\[02/05 2:00-3:00 pm Telecon w/XYZ & Joe Smith]' as a recipient.

 

  • If I run:  Get-MailboxFolder with the same Identity value, I get:

The specified mailbox "<Alias>" doesn't exist.

 

  •  If I run the script as originally written in the bottom bullet of the Problem, I get an error like this:

The operation couldn't be performed because '<Alias>:\2023 Meetings/Trips/Events\02 February\[02/05 2:00-3:00 pm Telecon w/XYZ & Joe Smith]' couldn't be found.
    + CategoryInfo          : NotSpecified: (:) [Get-MailboxFolderPermission], ManagementObjectNotFoundException
    + FullyQualifiedErrorId : [Server=ServerName,RequestId=47c592c0-dbc1-4ca5-b873-1dc5825aa23a,TimeStamp=9/7/2023 4:12:03 PM] [FailureCategory=Cmdlet-Manag
   ementObjectNotFoundException] CDF486FF,Microsoft.Exchange.Management.StoreTasks.GetMailboxFolderPermission
    + PSComputerName        : ServerName.domain.com

 

What can I do?  How can I rewrite that script in order to parse that folder name correctly?

Thanks in advance, 
Jim

 

3 Replies
What I really need to know, is how to escape special characters in a folder name, so that it doesn't try and change them. Currently, it's interpreting them as "".

Hi @JimBlunt,

Let´s try to solve your problem completely or at least help you to get closer to the soultion.

let's rewrite the script from your original question to handle folder names with special characters properly. We'll use the -EscapeCharacters parameter when constructing folder identities. Here's the modified script:

 

# Define the mailbox alias
$mailboxAlias = "<Alias>"

# Function to recursively process mailbox folder permissions
function Process-FolderPermissions($folderPath) {
    $escapedFolderPath = $folderPath.Replace("/", "\")
    $folderIdentity = "$mailboxAlias:`"$escapedFolderPath`""

    # Get folder permissions
    $folderPermissions = Get-MailboxFolderPermission -Identity $folderIdentity

    # Process folder permissions as needed (e.g., set, remove, or display)
    # Example: Set-MailboxFolderPermission -Identity $folderIdentity -User email address removed for privacy reasons -AccessRights FullAccess

    # Display folder permissions
    Write-Host "Folder: $folderPath"
    $folderPermissions | Format-Table -AutoSize

    # Recursively process subfolders
    $subfolders = Get-MailboxFolderStatistics -Identity $mailboxAlias | Where-Object { $_.FolderPath -like "$folderPath/*" }
    foreach ($subfolder in $subfolders) {
        Process-FolderPermissions "$folderPath/$($subfolder.FolderName)"
    }
}

# Start processing folder permissions from the root folder
Process-FolderPermissions ""

 

In this corrected script:

- We still define the $mailboxAlias variable to specify the mailbox alias.

- The Process-FolderPermissions function now properly escapes the folder names using the .Replace() method to replace forward slashes ("/") with backslashes ("").

- We construct the folder identity using the -EscapeCharacters parameter, which allows us to include folder names with special characters without encountering issues.

 

Replace <Alias> with the actual mailbox alias, and customize the permission processing logic as needed for your specific use case.

Please click Mark as Best Response & Like if my post helped you to solve your issue.
This will help others to find the correct solution easily. It also closes the item.


If the post was useful in other ways, please consider giving it Like.


Kindest regards,


Leon Pavesic

best response confirmed by JimBlunt (Brass Contributor)
Solution

@LeonPavesic Over the weekend, I found something that works for me and it's only 6 lines of code.  So, in the first 4 lines of code:

  • $Alias = Read-Host "Please enter the mailbox alias"
  • $Folders = Get-MailboxFolderStatistics -Identity $Alias | Where-Object {$_.FolderType}
  • $FolderID = ForEach ($F in $Folders) {$Alias + ":" + $F.FolderID}
  • $Perms = ForEach ($F in $FolderID) {Get-MailboxFolderPermission -Identity $F}

 

Once I take the output from $Perms and condense it down to a usable user list, I can run the last two:

  • $Users = Get-Content "C:\Temp\Users.txt"
  • ForEach ($F in $FolderID) {ForEach ($U in $Users) {Remove-MailboxFolderPermission $F -User $U -Confirm:$false | Write-Host $F}}
1 best response

Accepted Solutions
best response confirmed by JimBlunt (Brass Contributor)
Solution

@LeonPavesic Over the weekend, I found something that works for me and it's only 6 lines of code.  So, in the first 4 lines of code:

  • $Alias = Read-Host "Please enter the mailbox alias"
  • $Folders = Get-MailboxFolderStatistics -Identity $Alias | Where-Object {$_.FolderType}
  • $FolderID = ForEach ($F in $Folders) {$Alias + ":" + $F.FolderID}
  • $Perms = ForEach ($F in $FolderID) {Get-MailboxFolderPermission -Identity $F}

 

Once I take the output from $Perms and condense it down to a usable user list, I can run the last two:

  • $Users = Get-Content "C:\Temp\Users.txt"
  • ForEach ($F in $FolderID) {ForEach ($U in $Users) {Remove-MailboxFolderPermission $F -User $U -Confirm:$false | Write-Host $F}}

View solution in original post