Category: Cloud Services

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 [email protected]
$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 <[email protected]> -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

Gotcha – Integrating Lync On-Prem with Exchange Online UM

As part of our (Provoke’s) recent migration of our corporate email to Office 365 and Exchange Online, we wanted to include migration of the Exchange Unified Messaging role to Exchange Online as well. Simple enough, and the UCGuys have a superb post that breaks down the process in real simple terms.


We struck an issue after completing the process whereby calling voicemail, or trying to dial the UM dial-in numbers failed. Checking the logs revealed an error along the following lines:

ms-diagnostics: 1036; reason=”Previous hop shared address space peer did not report diagnostic information”; source=”<fe-server>”; dialplan=”<multipleSMTPdomains>”; umserver=””;responsecode=”503″; msexchDomain=”<primarySMTPdomain>”; msexchPeerServer=””; msexchsource=”<edgeaccessfqdn>”; appName=”ExumRouting”

Followed by:

ms-diagnostics: 15030; reason=”Failed to route to Exchange Server”; source=”<fe-server>“;dialplan=”<multipleSMTPdomains>“; appName=”ExumRouting”

Turns out we (and by that I mean me) had made an error when running the command:

New-CsHostedVoicemailPolicy -Identity Office365UM -Destination -Description “Hosted voice mail policy for O365 users.” -Organization “”

In my desire to validate blog posts before blindly following them (crazy right!), I’d checked the UCGuys’ NewCsHostedVoicemailPolicy  syntax against the Technet cmdlet library for New-CsHostedVoicemailPolicy, which states for the Organisation field..

This parameter contains a comma-separated list of the Exchange tenants that contain Lync Server 2010 users. Each tenant must be specified as an FQDN of the tenant on the hosted Exchange Service.

Which I duly interpreted as meaning all SMTP domains associated with the Exchange Online tenant – of which we had three. Especially as the example syntax at the bottom of the article does exactly that.

Turns out, that aint gonna fly.

For Exchange Online UM, you must specify one domain only in the Organisation field. And that domain must be one that Exchange Online is authorative for. If you’ve done a cutover migration, that will mean you can probably use your primary SMTP domain, as by dint of the cutover, Exchange Online will be authorative for that domain. However if you’ve done a hybrid migration, chances are good that your on-premise Exchange platform is still authorative for your primary SMTP domain. So best option here is to use your <customer> domain, as Exchange Online will always be authorative for that one.

This is briefly outlined at the end of the Connect Lync Server 2010 to Exchange Online UM Checklist from Microsoft.

Lync On-Premises vs Lync Online

A common question about Lync Online (and the other Office 365 products too, but this post is Lync-centric) is “how is this different from the on-premises solution?” And there is a comprehensive feature comparison available at the Office 365 Community site, but usually the next question I get is “yeah yeah, but what does that really mean for me?”

So here’s a shortlist of the more pertinant features that you don’t get with Lync Online.

  • PSTN calling (incoming or outgoing)
  • PBX integration
  • Advanced call handling (hold, redirection, park)
  • IP Phone support (USB only)
  • Analog line support (eg. fax)
  • Response groups (ie. Direct inbound call to a recipient group)
  • Persistent group chat
  • Skill search from SharePoint (either on-premise or online)
  • Client-side recording
  • Dial-in conferencing
  • Interop with on-premise video conferencing systems (eg. Polycom suites)
  • QoS
  • Quality of Experience Reporting

This usually leads to a question like, “ok, so what do they have in common then?”

So for completeness, here’s some of the more popular things you can do with both versions of the product.

  • PC-to-PC audio/video
  • Address book search
  • IMPresence
  • Office application integration (click-to-chat)
  • Federation with Lync Online, Lync On-Premise, and OCS On-Premise
  • Application/Desktop/Whiteboard/Presentation sharing
  • Online Meetings
  • Guest attendees (via rich client and web client)
  • Roundtable support
  • Meeting lobby

Hope that’s helpful.  Might add SharePoint Online and Exchange Online comparisons too.

SharePoint column lookup and calculation limitations

List lookup columns in SharePoint are great. Easy to setup, simple to use, and powerful. But they have some limitations that can be frustrating.

Let me paint you a picture..

You have a SharePoint list that contains information about a customer entity (yes it should probably be in CRM, but lets assume you don’t have one) – fields like contact names/numbers, addresses, unique systems, notes, etc. Some of these fields are single lines of text, pull-down menus, yes/no radio buttons, multiple lines of text, you name it.

You have another list that relates to sales of products to customers. Unsurprisingly, you want to link a sale to a customer, and you want to leverage the power of lookup columns to make that a simple and seamless process.

Not an unrealistic scenario. Sure there are better ways of doing it with the likes of webservices into CRM or BCS connections into LOB databases, but they all involve additional systems, coding skills, and generally more effort. All things that aren’t always readily available.

By adding a lookup column type to the sales list you can allow a customer entity to be selected from your customer list. Where this gets handier is you can have the sales list pull other values from the customer list without adding extra columns. Awesome.

But… not all the columns from your customer list are available. Why not?

SharePoint can only perform a lookup of values from columns that contain a ‘text’ value, and then only if it contains a single line of normal text (ie. “Single line of text”, a “number”, or “date”). Any field that contains multiple lines of text, other lookups, or multi-select items won’t be available to you, as SharePoint will automatically hide any columns that it knows it can’t return.

This same restriction applies to using these column types in calculated columns, and there is a great post by Dessie Lunsford on getting around this limitation in terms of calculated columns which you’ll find here –

The workaround involves creating your problem field as a “single line of text” column, then creating a second calculated column that references the first column name – eg. [=ColumnName]. You then delete the first column and recreate it with the exact same name but this time selecting your column type of choice.

While Dessie’s post deals specifically with referencing these columns via calculated fields, by dint of good fortune and SharePoint consistency, the same workaround fixes the lookup problem as well. Thanks Dessie!

This issue applies to all versions of SharePoint since 2007, including SharePoint Online (BPOS/Office365)

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