Thursday, March 22, 2012

Update Calendar folder permission

Most admins have one time or another come across the need for changing permission on individual folders in mailboxes.
Most common cases I have seen this is for calendar folder in resource mailboxes.
This is an easy task but some challenges exist. To start with you use the MailboxFolderPermission cmdlet to set/add/remove permissions.

To read the existing permission on the calendar folder, run.

Get-MailboxFolderPermission -Identity LasseP

And you will see the following output.

FolderName : Top of Information Store
User : Default
AccessRights : {None}
Identity : Default
IsValid : True


FolderName : Top of Information Store
User : Anonymous
AccessRights : {None}
Identity : Anonymous
IsValid : True


You see the usual Anonymous and Default permission group. Interesting here is that you see the permission for “Top of Information Store” which is the root folder in the mailbox.


To get permission for a specific folder you have to specify this as a parameter and here we must know the exact folder name. This gives us some interesting challenges for Multilanguage organization because the calendar folder can have different names.
So if I specify the calendar folder name in Swedish

Get-MailboxFolderPermission -Identity LasseP:\Kalender

I get an error because the folder name is not “Kalender”, but when specifying the English name I get what I want.

Get-MailboxFolderPermission -Identity LasseP:\Calendar

FolderName : Calendar
User : Default
AccessRights : {AvailabilityOnly}
Identity : Default
IsValid : True


FolderName : Calendar
User : Anonymous
AccessRights : {None}
Identity : Anonymous
IsValid : True


Folder name must also be correct when using Set/Add-MailboxFolderPermission.
So how do we know the calendar folder name for a mailbox?
Here is neat trick we can use to get the name with Get- MailboxFolderStatistics cmdlet.

Get-MailboxFolderStatistics -Identity LasseP -FolderScope Calendar | Select-Object -First 1).Name

The output will be a text string with the calendar folder name, in our example it is “Calendar”.
Selecting only the first object is needed because users can have more than a single calendar folder and we want only the default calendar folder in the mailbox which is returned first.
Next step is to update the ACL with new permission, and here we have one more challenge. We need to figure out if we want to add permission or change existing reason for this is that we have two cmdlet to use, Add-MailboxFodlerPermission and Set- MailboxFodlerPermission. Each one of them will give an error if used in the wrong context.

To add a new user (or a group) to the ACL, run.

Add-MailboxFolderPermission -Identity LasseP:\Calendar -User Eva -AccessRights Reviewer

This will grant user Eva the reviewer permission on LasseP’s calendar folder.
Running the same cmdlet again will give you an error with “Add-MailboxFolderPermission : An existing permission entry was found for user: Eva”.

To change the permission you must use Set-MailboxFolderPermission

Set-MailboxFolderPermission -Identity LasseP:\Calendar -User Eva -AccessRights Owner

The vice versa is true if you run Set-MailboxFolderPermission and the user being granted permission is not in the ACL you will get an error saying “Set-MailboxFolderPermission : There is no existing permission entry found for user: Axel”
So before we can update the folder permission you must know if the user/group is already member of the ACL. This is accomplished by using Get-MailboxFolderPermission, this we already tried earlier.
To make things easier without issuing multiple commands I created a script.

Update-CalendarFolderPermission.ps1
########################################
# Update-CalendarPermission.ps1 -Identify <mailbox> -User <xxx> -Permission <permission>

param
(
    [Parameter(Mandatory = $true, HelpMessage="Enter a mailbox where you apply permission to")]
    [ValidateNotNullOrEmpty()]
    [string]$Identity ,

    [Parameter(Mandatory = $true, HelpMessage="Enter a user/group who will be granted the permission  syntax domain\xxx might be needed")]
    [ValidateNotNullOrEmpty()]
    [string]$User = "",
    
    [parameter(Mandatory = $true, HelpMessage="Enter a valid permission set")]
    [ValidateSet("ReadItems","CreateItems","EditOwnedItems","DeleteOwnedItems","EditAllItems","DeleteAllItems","CreateSubfolders","FolderOwner","FolderContact","FolderVisible","None","Owner","PublishingEditor","Editor","PublishingAuthor","Author","NonEditingAuthor","Reviewer","Contributor","AvailabilityOnly","LimitedDetails","Remove")]
    [string]$Permission = ""
)

#Add Exchange 2010 Management Shell if needed
if (! (Get-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction:SilentlyContinue) )    {
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction:Stop
}

$MBX = Get-Mailbox $identity

$CalendarName = (Get-MailboxFolderStatistics -Identity $MBX.alias -FolderScope Calendar | Select-Object -First 1).Name
$folderID = $MBX.alias + ':\' + $CalendarName

if ($Permission -eq 'remove') {
    # special case, remove permission from user
    Remove-MailboxFolderPermission -Identity $folderID -User $User -Confirm:$False
}
else {
    $i = @(Get-MailboxFolderPermission -Identity $folderID -User $User -ErrorAction SilentlyContinue).count
    if ($i -eq 0) {
        # not in ACL, add permission
        Add-MailboxFolderPermission -Identity $folderID -User $User -AccessRights $Permission > $Null
    }
    else {
        # user is already in ACL, change permission
        Set-MailboxFolderPermission -Identity $folderID -User $User -AccessRights $Permission
    }

    # display new permission for $user
    Get-MailboxFolderPermission -Identity $folderID -User $User
}




Script isn't that hard to follow, there is some required input parameters needed. When this is handled, script continue with figuring out the calendar folder name then add or set permission depending on if user is already on ACL.

I also built in a special case where you could set permission to "remove" to remove the user from ACL on the calendar folder.


An example would be.

Update-Calendarpermission -identity Eva -User Lassep -Permission ReadItems

This will grant Lassep Read permission on Eva's calendar folder.


Script don't accept pipelining from other commands so if you want to update permission on multiple mailboxes you need to do this with two lines of code instead.


$mbx = Get-Mailbox conf*
foreach($mb in $mbx) { .\update-calendarpermission.ps1 -Identity $mb.Alias -User Lassep -Permission ReadItems}




First line is save mailboxes you want to change permission on into the $mbx variable.

Second line calls the Update-CalendarPermission script once for each mailbox in the $mbx variable.

The two line script will grant LasseP Read Permission on all 'conf*' mailboxes


now, go and play with this is a lab before running it on every mailbox in your production environment.