Month: April 2016

Apply default calendar permissions in Office 365

Something that’s often frustrated me as an O365 Administrator is the lack of ability to craft and apply default calendar sharing permissions in Office 365. Sure you can create sharing policy for external organisaitons, but what about all your internal users? This is pretty standard stuff for internal collaboration, so why can’t we do it via the Admin Portal?

Like most things though, if you can’t do it via the UI, you can probably do it via PowerShell. Guess what.. you can do this too..

I love PowerShell so I’m ok with this, but on the off-chance you’re less excited by the ‘shell approach, feel free to steal this and claim it as your own (I don’t care – own it).

So first up, get your ‘Shell sessions sorted – if you’re already sorted here, skip to the next bit. If you’re not, check this out (I don’t tend to do this bit quite like other folks – mostly cos I’m lazy and don’t like typing in my username).

$cred = get-credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $cred -Authentication Basic -AllowRedirection
Import-PSSession $Session
Connect-msolservice -credential $cred

If you’re wondering why I’m calling an Outlook session and the MSOLService, that’s cos we’re going to cross both the Office 365 and Azure AD environments. Madness.

There are a bunch of blog posts out there that talk about how to apply permissions for a given user, but frankly that’s what the GUI is for, so why bother do that via PowerShell. I’m more interested in bulk application of permissions, so that’s what you’ll find below.

Let’s assume you have (like I do) a security group that includes all your users (or at least a big chunk of the ones you care about). And lets assume you want to apply the same set of standard calendar sharing permissions to all your users – so all staff can see the same properties of all other staff. That’s what this bit does…

Now, like many a lazy (pragmatic?) admin, my ‘all staff’ group is actually a set of nested groups – in my case, one for each of our global offices. Not an unusual scenario I suspect. So first thing I need to do is expand those out to their actual members. Let’s do that first. Note that if you are not using nested groups, you can skip this step.

<Group DisplayName> is the name of your ‘all staff’ group. This step will find all the groups that exist within your ‘all staff’ group.

$id = Get-MsolGroup -all | ?{$_.Displayname -eq '<Group DisplayName'} | select ObjectID
$groups = Get-MsolGroupMember -GroupObjectId $id.ObjectId | ?{$_.GroupMemberType -eq 'Group'} | Select DisplayName

Now that we have the list of actual groups in your main group, we’re going to iterate through each one, find the members, and set a given set of permissions for each mailbox. The syntax here is set/add-mailboxfodlermission -identity <calendar being impacted> – user <user being granted permission> -accessrights <specific access control>.

foreach ($grp in $groups){
$grpname = $grp.DisplayName

# Gets the object ID for the given group
$grpid = get-msolgroup -all | ?{$_.DisplayName -eq $grpname} | select ObjectID
Write-Host Iterating through $grpname

# Gets the members of the given group and returns their mailbox
$who = Get-MsolGroupMember -GroupObjectId $grpid.ObjectID | Select EmailAddress

# Iterates through each mailbox and sets permissions
foreach ($w in $who)
$eml = $w.EmailAddress
$cal = $w.EmailAddress + ':calendar'

# Assigns the 'Limited Details' permission (Free/Busy/Subject/Location) on the mailbox, for all members of the original group (eg. all staff in this example)
add-MailboxFolderPermission -Identity $cal -user <> -AccessRights LimitedDetails -ErrorAction SilentlyContinue
# Assigns the 'Availability Only' permission (Free/Busy only) to the system 'Default' role.
set-MailboxFolderPermission -Identity $cal -user Default -AccessRights AvailabilityOnly -ErrorAction SilentlyContinue
# Removes any permissions for anonymous users
set-MailboxFolderPermission -Identity $cal -user Anonymous -AccessRights None -ErrorAction SilentlyContinue

This will step through each nested group, expand the members, and assign the permissions define above to each member. In addition it will set basic permissions for the system roles ‘Default’ and ‘Anonymous’. Feel free to adjust these to suit your purposes.

I confess, I’m being a little lazy here. What I probably should do here is apply some if/then/else logic to determine what the current sharing permissions are, to ensure only actual changes are processed, which would (massively) speed up the script, but I ran out of time to get the logic working (it’s more complicated than just a simple ‘where equals’ unfortunately). It’s on my backlog – I’ll update this post if (when?) I get it working.

Hope this is useful.

JB / TheGingerOne

JB / The Daywalker

Ginger IT dude hanging out down in New Zealand, playing with technology since ages ago.

Currently Service Delivery Manager at Silicon Systems, formerly Skype for Business MVP, and generally into all things Microsoft (and a few things that aren’t).

When I’m not nerding out on technology, you can find me running ultramarathons, brewing beer, or in my woodshop building something.

On The Socials

Visit Us On LinkedinVisit Us On TwitterVisit Us On Facebook