Monday, January 24, 2011

Default Calendar permission Powershell GUI for Exchange 2010 SP1 and up

One of the new cmdlets in Exchange 2010 SP1 is the Set-MailboxFolderPermission cmdlet which was an addition to the other Exchange 2010 RTM folder permission cmdlets get-MailboxFolderPermission and add-MailboxFolderPermission. What this cmdlet gives you the ability to do is update the permissions of any folder within a mailbox as long as you are a member of the RBAC roles that allows you set them as specified in http://technet.microsoft.com/en-us/library/dd638132.aspx. Another thing this cmdlet does is give me the ability to revisit the default calendar folder permission GUI from this post(which used EWS and will still work okay on 2010) and rewrite this to be able to be used in Remote powershell so it will work against any 2010 SP1 server as well as anything else that supports these cmdlets such as live@edu or Office365.

If you don't really want a GUI and would rather just export the permissions to CSV modify them and then reimport them that's easy to do for example to export the settings to a csv file.

$rptCollection = @()
$mailboxes = get-mailbox -ResultSize Unlimited
$mailboxes | foreach-object{
$alias = $_.alias + ":\Calendar"
$displayName = $_.DisplayName
write-host $alias
$permissions = Get-MailboxFolderPermission $alias | Where-Object {$_.Identity.ToString() -eq "Default"}
if($permissions -ne $null){
$stringPerms = ""
foreach($perms in $permissions.AccessRights){$stringPerms = $stringPerms + $perms + " "}
Add-Member -InputObject $permissions -MemberType NoteProperty -Name "Alias" -Value $alias -Force
Add-Member -InputObject $permissions -MemberType NoteProperty -Name "StringAccessRights" -Value $stringPerms -Force
$rptCollection += $permissions
}

}
$rptCollection | export-csv -notypeInformation c:\defaultperms.csv

To then re-import them from a csv file you can use

import-csv c:\defaultperms.csv | foreach-object{
"Seting Rights on " + $_.alias
Set-MailboxFolderPermission -id $_.alias -User $_.Identity -AccessRights $_.StringAccessRights

}

Personally i like the GUI which is a little more snappier with the GUI I left the permission descriptions in Outlook format rather then switching them to the accessrights role format(the great thing about standards is there are so many to choose from). To run this GUI you need to first start a Remote powershell session and import the Exchange 2010 cmdlets or run it directly from within the EMS. I've put a download of the new script here the code looks like

[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")


function GetPerms(){
$logTable.clear()

If ($seAuthCheck.Checked -eq $true){
$mailboxes = get-mailbox -server $snServerNameTextBox.Text -ResultSize Unlimited
}
else{
$mailboxes = get-mailbox -ResultSize Unlimited
}
$mailboxes | foreach-object{
$alias = $_.alias + ":\Calendar"
$displayName = $_.DisplayName
write-host $alias
$permissions = Get-MailboxFolderPermission $alias | Where-Object {$_.Identity.ToString() -eq "Default"}
if($permissions -ne $null){
Add-Member -InputObject $permissions -MemberType NoteProperty -Name "Alias" -Value $alias -Force
$stringPerms = ""
foreach($perms in $permissions.AccessRights){$stringPerms = $stringPerms + $perms + " "}
$logTable.rows.add($displayName,$permissions.alias,$stringPerms)
}

}
$dgDataGrid.DataSource = $logTable

}

Function UpdatePerms{
if ($dgDataGrid.SelectedRows.Count -eq 0){
$mbtoSet = $dgDataGrid.Rows[$dgDataGrid.CurrentCell.RowIndex].Cells[1].Value
$newperm = ""
switch ($npNewpermDrop.Text){
"None" {$newperm = "None"}
"FreeBusyTimeOnly" {$newperm = "AvailabilityOnly"}
"FreeBusyTimeAndSubjectAndLocation" {$newperm = "LimitedDetails"}
"Reviewer" {$newperm = "Reviewer"}
"Contributer" {$newperm = "Contributer"}
"Author" {$newperm = "Author"}
"NonEditingAuthor" {$newperm = "NonEditingAuthor"}
"PublishingAuthor"{$newperm = "PublishingAuthor"}
"Author" {$newperm = "Author"}
"Editor" {$newperm = "Editor"}
"PublishingEditor"{$newperm = "PublishingEditor"}
}
Set-MailboxFolderPermission -id $mbtoSet -User Default -AccessRights $newperm
write-host "Permission updated" + $npNewpermDrop.Text
}
else{
$lcLoopCount = 0
while ($lcLoopCount -le ($dgDataGrid.SelectedRows.Count-1)) {
$mbtoSet = $dgDataGrid.SelectedRows[$lcLoopCount].Cells[1].Value

switch ($npNewpermDrop.Text){
"None" {$newperm = "None"}
"FreeBusyTimeOnly" {$newperm = "AvailabilityOnly"}
"FreeBusyTimeAndSubjectAndLocation" {$newperm = "LimitedDetails"}
"Reviewer" {$newperm = "Reviewer"}
"Contributer" {$newperm = "Contributer"}
"Author" {$newperm = "Author"}
"NonEditingAuthor" {$newperm = "NonEditingAuthor"}
"PublishingAuthor"{$newperm = "PublishingAuthor"}
"Author" {$newperm = "Author"}
"Editor" {$newperm = "Editor"}
"PublishingEditor"{$newperm = "PublishingEditor"}
}
Set-MailboxFolderPermission -id $mbtoSet -User Default -AccessRights $newperm
write-host "Permission updated" + $npNewpermDrop.Text
$lcLoopCount += 1
}
}
write-host "end PermUpdate"
write-host "Refresh Perms"
GetPerms
}


$form = new-object System.Windows.Forms.form
$form.Text = "Calender Permission Enum Tool"
$Dataset = New-Object System.Data.DataSet
$logTable = New-Object System.Data.DataTable
$logTable.TableName = "ActiveSyncLogs"
$logTable.Columns.Add("DisplayName");
$logTable.Columns.Add("MailboxFolderId");
$logTable.Columns.Add("Default-Permissions");



# Add Server DropLable
$snServerNamelableBox = new-object System.Windows.Forms.Label
$snServerNamelableBox.Location = new-object System.Drawing.Size(10,60)
$snServerNamelableBox.size = new-object System.Drawing.Size(70,20)
$snServerNamelableBox.Text = "ServerName"
$form.Controls.Add($snServerNamelableBox)

# Add ServerNameText
$snServerNameTextBox = new-object System.Windows.Forms.TextBox
$snServerNameTextBox.Location = new-object System.Drawing.Size(90,60)
$snServerNameTextBox.size = new-object System.Drawing.Size(150,20)
$snServerNameTextBox.Enabled = $false
$form.Controls.Add($snServerNameTextBox)

$seAuthCheck = new-object System.Windows.Forms.CheckBox
$seAuthCheck.Location = new-object System.Drawing.Size(250,60)
$seAuthCheck.Size = new-object System.Drawing.Size(130,25)
$seAuthCheck.Text = "Filter by"
$seAuthCheck.Add_Click({if ($seAuthCheck.Checked -eq $true){
$snServerNameTextBox.Enabled = $true
}
else{
$snServerNameTextBox.Enabled = $false}})
$form.Controls.Add($seAuthCheck)

# Add Get Perms Button

$gpgetperms = new-object System.Windows.Forms.Button
$gpgetperms.Location = new-object System.Drawing.Size(10,20)
$gpgetperms.Size = new-object System.Drawing.Size(140,23)
$gpgetperms.Text = "Enumerate Permissions"
$gpgetperms.Add_Click({GetPerms})
$form.Controls.Add($gpgetperms)

# Add New Permission Drop Down
$npNewpermDrop = new-object System.Windows.Forms.ComboBox
$npNewpermDrop.Location = new-object System.Drawing.Size(350,20)
$npNewpermDrop.Size = new-object System.Drawing.Size(190,30)
$npNewpermDrop.Items.Add("None")
$npNewpermDrop.Items.Add("FreeBusyTimeOnly")
$npNewpermDrop.Items.Add("FreeBusyTimeAndSubjectAndLocation")
$npNewpermDrop.Items.Add("Reviewer")
$npNewpermDrop.Items.Add("Contributer")
$npNewpermDrop.Items.Add("Author")
$npNewpermDrop.Items.Add("NonEditingAuthor")
$npNewpermDrop.Items.Add("PublishingAuthor")
$npNewpermDrop.Items.Add("Editor")
$npNewpermDrop.Items.Add("PublishingEditor")
$form.Controls.Add($npNewpermDrop)

# Add Apply Button

$exButton = new-object System.Windows.Forms.Button
$exButton.Location = new-object System.Drawing.Size(550,20)
$exButton.Size = new-object System.Drawing.Size(60,20)
$exButton.Text = "Apply"
$exButton.Add_Click({UpdatePerms})
$form.Controls.Add($exButton)

# New setting Group Box

$OfGbox = new-object System.Windows.Forms.GroupBox
$OfGbox.Location = new-object System.Drawing.Size(320,0)
$OfGbox.Size = new-object System.Drawing.Size(300,50)
$OfGbox.Text = "New Permission Settings"
$form.Controls.Add($OfGbox)

# Add DataGrid View

$dgDataGrid = new-object System.windows.forms.DataGridView
$dgDataGrid.Location = new-object System.Drawing.Size(10,130)
$dgDataGrid.size = new-object System.Drawing.Size(750,550)
$dgDataGrid.AutoSizeColumnsMode = "AllCells"
$dgDataGrid.SelectionMode = "FullRowSelect"
$form.Controls.Add($dgDataGrid)


$form.Text = "Exchange 2010 Default Calendar Permissions Form"
$form.size = new-object System.Drawing.Size(800,730)

$form.autoscroll = $true
$form.topmost = $true
$form.Add_Shown({$form.Activate()})
$form.ShowDialog()

19 comments:

Anonymous said...

The GUI script works very well. Thanks for post

Search is on for "Purpose of Life" said...

Thanks for the script. I ran the script to export calendar permission for all the users in my organization to a csv. Then I edited the csv to only have users whose permissions I want to change. I am not very clear on the import-csv process. Do I run just the part of the whole script that starts with Import-csv ?? Can you please clarify the import process. Will really appreciate it.

Search is on for "Purpose of Life" said...

Thanks for the script. I ran the script to export calendar permission for all the users in my organization to a csv. Then I edited the csv to only have users whose permissions I want to change. I am not very clear on the import-csv process. Do I run just the part of the whole script that starts with Import-csv ?? Can you please clarify the import process. Will really appreciate it.

Anonymous said...

Hey Glen,

I've just tried your csv export/import script! Works great. (Just had to change calendar to Kalender, because our's on German)

Thx for the script!!

Greetings from Swiss
Shan

Steve said...

Thanks for the terrific script. I didn't completely understand it, but took a chance and it did exactly what I wanted.

Thanks,
Steve

Eugene said...

Glen,

there is a problem with removing a calendar permission. Assume that first we invoke Get-MailboxFolderPermission -identity ... and it returns us user 'Smith, John'. We want to delete this user and use Remove-MailboxFolderPermission -identity ... -user 'Smith, John' but the command fails because the user 'Smith, John' is not unique. This name exists in a number of containers. And we have no way to figure from Get-MailboxFolderPermission which 'Smith, John' is that. Do you know a way to resolve this issue?

Glen said...

You should use the primary SMTP address as the Identity rather then the display name then will avoid those type of problems

Cheers
Glen

Anonymous said...

Thank you for the script, Works great.

Darkahn said...

Anyone else ever have this go into an endless error loop in the Exchange Shell running in the background? I have this problem as soon as I try and change the perms to Reviewer for any mailbox.

Glen Scales said...

It sounds like the permission change is failing on one mailbox that should really be a breaking error but it could be causing problems in the loop try moving the line

$lcLoopCount += 1

before

Set-MailboxFolderPermission -id $mbtoSet -User Default -AccessRights $newperm

Cheers
Glen

Darkahn said...

That fixed it!
Many thanks for such a great tool!

Anonymous said...

Great script. Any chance you will upgrade this script to support Exchange 2013?

Anonymous said...

And btw. "Default" has to changed into "Standard". ;)

Anonymous said...

Hi,

Although script works great, it will fail in a multi-language environment (8 languages in our environment) as the name 'Calendar' changes based on the Outlook client language used.
Richard

Anonymous said...

I have tried the script to export the permissions to a csv file. The script run fine but the csv is empty. Do I need to change anything?

Anonymous said...

Does this work with Exchange 2013 CU7?

Glen Scales said...

It should work okay

WiredEarp said...

This was really handy. I've used other scripts before, but I especially like the GUI version, since it makes it easy and quick to just change SOME permissions. Thanks!

Jeremy Montoya said...

Same thing here, but I ran this against exchange online. No Joy.