blog.atwork.at

news and know-how about microsoft, technology, cloud and more.

Provisioning an Office 365 group with an approval flow and Azure functions-part 1

Office 365 groups span over various Office 365 services and provide a great way for collaborating. By default, every user can create an Office 365 group. While self-service is a good thing and many businesses adopted into that direction, some companies still prefer the controlled approach.

In real world environments, organizations usually want to restrict the group provisioning so that IT can control the wild growth of groups. This article series shows how to create an Office 365 group with an attached approval process with SharePoint Online, Flow and Azure functions. See how this works here!

This is part 1 of a 3 part series. This article series was written by Martina Grom and Toni Pohl.

For showing all the technics behind that requirement we developed a demo scenario showing all necessary steps. You need to have a SharePoint Administrator, a Flow license and an Azure subscription and some basic knowledge about web technologies. There are some steps required, but the process is simple. Follow these steps to get your solution up and running.

The scenario

The following graphics delivers the planned steps for the approval workflow. The blue steps require a user interaction, the orange ones are automatic processes. Green and red show an accept or deny decision.


image

If a user requests to create an Office 365 group (which can be requested f.e. in a PowerApp or in a SharePoint list) and it gets accepted, the function provisions the group and the initiator gets a notification email. In this sample, we start with the base part that does the work: provisioning the Office 365 group, first as a demo, then in part two the code follows.

First, see how group operations work with Microsoft Graph Explorer

Open developer.microsoft.com/graph/graph-explorer, sign in and accept the consent for the Microsoft Graph App.

image

Now, try to access the Microsoft groups with a GET request of this URL:
https://graph.microsoft.com/v1.0/groups

If you get an error as here, your account (even if it's the global administrator) does not have the necessary permissions.

image

The error says "Authorization_RequestDenied", and "Insufficient privileges to complete the operation."

You need to modify the permissions. Open the link in the red message box (or on the left below your account). In the Modify Permissions dialog, click "access to your entire organization" and confirm the "Modify Permissions" button. Alternatively, you can add the required permissions "Read and write all groups" manually.

image

Then, sign in again (which happens automatically that you get redirected to the login page again). Now, you get a new consent with all possible permissions. Accept the new consent for your organization.

image

Another box informs about the newly granted permissions, and yes, it can take some minutes before the consent takes effect, but mostly it works instantly.

image

We're done with the permissions for our administrator user.

Update December 2017: All App permissions

Since we got some feedback on the required permissions for the app, see the following screenshots for all activated permissions of that app:

For AAD, the following app permissions were used:

image

For Graph, these permissions have been set.

SNAGHTML8df4fb0

We hope, this clarifies the permissions.

Accessing groups through the Microsoft Graph API

Ok, now we should be able to use the API for Office 365 groups. For our demo, we are using Microsoft Graph API version 1.0 (which is the current version). The next attempt against https://graph.microsoft.com/v1.0/groups works as expected: We get all groups of the tenant - which is one single existing Office 365 group in our sample.

image

Since the API represents an OData interface, we can use expressions as filtering, paging and more. Here we reduce the output to the relevant properties with $select as parameter:

https://graph.microsoft.com/v1.0/groups?$select=displayName,description,groupname,groupTypes,
mailNickname,mailEnabled,securityEnabled,proxyAddresses

image

For a list of more OData options, see Use query parameters to customize responses and Supported queries, filters, and paging options | Graph API concepts.

Create a new Office 365 group with the Microsoft Graph API

We can create a new Office 365 group with a POST operation and the necessary data as follows. First, we simply copy the JSON output from above and adapt it as needed. We create a new group "My Demo 1" with some description and the necessary properties as here:

{
     "displayName": "My Demo 1",
     "description": "This is a demo group",
     "groupTypes": ["Unified"],
     "mailEnabled": true,
     "mailNickname": "mydemo1",
     "securityEnabled": false
}

An Office 365 group is defined by the group type "Unified". This JSON-description must be pasted into the "Request Body". So, let' s execute this operation against https://graph.microsoft.com/v1.0/groups with a POST as here:

image

You should get a HTTP status code 201 (which means Ok, the request has been fulfilled and has resulted in one or more new resources being created.) and the runtime of the operation and some output.

To see, what properties can be used for a POST operation and what properties are read only check out the list at group resource type.

Set the owner of a group

When we create a new group with the Global Administrator with Graph Explorer, that user is automatically owner of the new group which is fine. If we do it (in part 2) with an app, there is no owner set. This means, that the user who requested the new group will not be able to access or to manage it. So, it's essential, that we are able to set the owner of a group programmatically as well.

The good story is that we are able to do this with the Microsoft Graph API. See https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/group_post_owners how this works. Basically, we need to get the User Id of the owner first. We can get it by asking for the user by his UPN:

https://graph.microsoft.com/v1.0/users/admin@M365x127892.onmicrosoft.com

groupowner

In our sample, the User ID is be2cab0f...

Also, we need the Group ID. To get a quick list of all groups, use this GET query:

https://graph.microsoft.com/v1.0/groups/?$select=displayName,id

...and copy the Group ID from the output as we did before with the User ID. Here it's 79744859...

Now we can add that User Id to the list of owners. Create a POST operation in Graph Explorer wit the address of the desired group as follows:

https://graph.microsoft.com/v1.0/groups/79744859-fb99-4a09-8b15-0f3a3d7bb117/owners/$ref

The Request body needs to contain the JSON data of our new owner (the user's address endpoint):

{"@odata.id": "https://graph.microsoft.com/v1.0/users/be2cab0f-1891-41d3-b153-ad15a62d68c9"}

This sets the owner of the new group to a specific user. We also need to add the owner as a member of the group. This is exactly the same method (the same JSON body with the same user), just the endpoint is members instead of owners:

https://graph.microsoft.com/v1.0/groups/79744859-fb99-4a09-8b15-0f3a3d7bb117/members/$ref

The owner now can fully manage the group container object.

Create a new Office 365 group with PowerShell

Of course, we can use PowerShell as well. First, we connect to Exchange Online.

Connect-MsolService -Credential $cred
$session = New-PSSession -ConfigurationName Microsoft.Exchange `
-ConnectionUri https://ps.outlook.com/powershell/ `
-Credential $cred -Authentication Basic -AllowRedirection
Import-PSSession $Session -AllowClobber

To see a list of all existing Office 365 groups, use Get-UnifiedGroup.

Now we can create a new group as described in https://technet.microsoft.com/en-us/library/mt219359%28v=exchg.160%29.aspx?f=255&MSPPError=-2147217396 . There are a bunch of possible options, but this basic syntax is sufficient for the new group:

New-UnifiedGroup -DisplayName "My Demo 2" -Alias "mydemo2" `
-PrimarySmtpAddress "mydemo2@M365x127892.onmicrosoft.com" `
-Owner "admin@M365x127892.onmicrosoft.com"

The group gets provisioned in the same way as before with the Microsoft Graph API.

Check it in Outlook

Open https://outlook.office.com/ and discover the modern groups. "My Demo 1" should show up in the list of Office 365 groups.

SNAGHTML191a6a4a

It worked! The mail nickname is the email address with the primary domain defined in that Office 365 tenant. The email address can be changed later with PowerShell. To do that, see the details at Why we moved away from Exchange distribution groups to Office 365 groups and "Setting custom email addresses for the Office 365 group".

image

Get an Office 365 group with Microsoft Graph

To access one specific group, we can filter that easily: To identify one group, the ID is added to the request. So you can get the ID from the Graph Explorer Request above.

image

So, in our case that's an operation as here:

https://graph.microsoft.com/v1.0/groups/35766673-5f6f-432c-b442-d9114e4ddf62

...and we get just this group.

image

Delete an Office 365 group

Now, deleting that specific group is easy. The HTTP operation is changed to DELETE.

When the query is executed, it delivers HTTP status code 204 (The server has successfully fulfilled the request and that there is no additional content to send in the response payload body).

image

The group has been deleted and should no longer be present in Outlook.

image

Deleted Office 365 groups are (nowadays) soft deleted. This means, you can undelete a group with the Active Directory Module and the PowerShell Cmdlet
Restore-AzureADMSDeletedDirectoryObject -Id <objectId>
as described in Restore a deleted Office 365 Group.

The choice is yours

As we have seen, you can use tools as CURL, Fiddler, Postman, PowerShell or similar or any other programming language as C# to manage Office 365 groups programmatically.

In part two, we develop the code for our planned automation.


Quicklinks:

Comments (5) -

  • joe

    2/6/2018 12:23:51 PM |

    Hi Martina,

    How do you handle the situation where one users data does not get shared with other.
    If all the users are sharing the same list, then each of them can see each others request.

    I think item level permission is required and once a new request is raised it should not be editable as user can go and change the content.

    Thanks,
    joe

  • Toni Pohl

    2/8/2018 5:49:37 PM |

    Hi Joe,
    let me answer that for Martina from my perspective.
    You are absolutely right, the permissions should be handled. One workaround would be to collect the request in one list, execute it, and then remove the item from the original list and "move" the request record to another list with Flow or another tool where the original user has no permissions to archive the request.
    So, the request would be in the request list just for a short time and would be moved to an archive list where other users don't have permissions to.
    I would solve this with such a workaround.
    What do you think?
    br, Toni

  • Toni Pohl

    3/23/2018 10:09:39 AM |

    Hi Jason.,
    usually, a HTTP 400 Bad Request or HTTP 403 Forbidden is thrown, when the Graph request could not be executed because of insufficient permissions.
    Pls. check the "Update December 2017: All App permissions" chapter and click the "Grant permissions" button for accepting the consent as Admin for the app. That should help. Pls. let us know.
    hth, Toni

  • Toni Pohl

    3/23/2018 10:13:47 AM |

    Hi Jolene,
    I'm not sure what you mean by "item level permission where only read permission is given to the user upon execution}". Do you mean that the user has specific permissions or the app? Well, in our scenario, we just have the app with it's permissions that does the job. Every user can trigger that thru a flow, so the user does not need to have any permissions for that operation.
    hth? Toni

  • Toni Pohl

    3/23/2018 10:21:50 AM |

    Hi nj,
    the scenario is exactly for that purpose-if the IT disabled group creation (done by Powershell). As you wrote, an Office 365 (Unfied) group is basis for many other services e.g. Teams. The SP site is just one part of the group - it lives in AAD and provisions an Exchange mailbox, a SPO site, adds members, etc. So, AFAIU your question, you're not depending on a SP group. Any service that's using groups is affected-once you create a new group, it's available for these services automatically. It's just about the permission to provision a new group or not and the scenario shows a way to do that if it's disabled in your organization. hth?
    br, Toni

Pingbacks and trackbacks (6)+

Loading