Category: Exchange Online


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 https://ps.outlook.com/powershell/ -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.

However..

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=”Hosted__exap.um.outlook.com__<multipleSMTPdomains>”; umserver=”exap.um.outlook.com”;responsecode=”503″; msexchDomain=”<primarySMTPdomain>”; msexchPeerServer=”exap.um.outlook.com”; msexchsource=”<edgeaccessfqdn>”; appName=”ExumRouting”

Followed by:

ms-diagnostics: 15030; reason=”Failed to route to Exchange Server”; source=”<fe-server>“;dialplan=”Hosted__exap.um.outlook.com__<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 exap.um.outlook.com -Description “Hosted voice mail policy for O365 users.” -Organization “domain.com”

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>.onmicrosoft.com 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.

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