In part one, we saw how the Microsoft Graph API enables programmatic access to Office 365 groups. Now it's time to letAzure Functionshelp us with the desired workflow.
For the following steps, an Azure subscription and a Global Admin in the target Office 365 tenant is required.
We want our provision group function to be able to create a new Office 365 group without any user interaction. So, we need an app with the permission to accomplish the operations in our Office 365 tenant, in the same way as did for the administrator account in part 1. The key is, to create such an application first and to use that access data in our code. The workflow will execute our function, pass the parameters, and the function will do the work. So, these are the necessary steps.
Create a new App
Open theAzure portal(in the target Office 365 tenant) with a Global Admin and click on the the "Azure Active Directory" service. Go to "App registrations". In here, click "New application registration".
...and fill out the new app "provisiongroupfunction" as Web app/API with a fake Sign-on URL as https://localhost:40000 (we won't need that) as follows:
After the app was created, go to "Keys".
Add a new key "clientSecret", make it valid for 1 year and click "Save". Keys can be generated for 1 year, 2 years or without any expiration date. If you chose an expiration (which is usually a good idea), you need to renew the key from time to time.
Now the key is generated. You will not get any access to that key later, so save the key value, best to your OneNote, Notepad or similar tool.
We also need the "Application ID" property: 516b...
And of course, we need to set the permissions: Go to "Required Permissions", select the "Microsoft Graph" and select "Application Permissions" for "Read and write all groups". "Save" the app permissions.
Select more permissions depending on the desired features of the function if needed. We're done with the app, but...
Get the tenant ID
..we need the "Tenant ID" as well. You get that in the "Properties" of the AAD with the "Directory-ID" property as shown here.
The Directory-ID d302... needs to go to our note. Now we're done with the AAD. So we have this data collected:
The idea is to use server-less technology to provision an Office 365 group. No worries, we won't needVisual Studio,Visual Studio Code(which BTW are great tools and highly recommended for larger code projects...) or any similar environment. We can perform all necessary steps online directly in theAzure Portal.
So, let's create the new Azure function and fill it out... We are working with loose coupled architecture, so we can use any Azure subscription which must not be associated with the Office 365 tenant. This approach allows to build "black boxes" and to tie them together as needed easily. In our case, we let the function run in another Azure subscription.
Of course, Azure functions are a wide topic with many details, but this article concentrates on the solution. To learn more about Azure functions, seehereand thevideos on channel9.
Use a programing language - PowerShell is good enough
The function name shall be "ProvisionGroup". Let's create that with the default authorization level "Function" - we don't want to use a user authorization in our scenario.
...and we get the new function with some default code from a template. When clicking "Run", the function shows the basic concept with an HTTP POST operation, a JSON input and a text output as here:
Develop the function and configure it
The function needs to perform several operations. Keep in mind that Azure functions run in a sandbox, to be more specific, in an App service in a Virtual machine. You can use default functionality, but you need to take care if you need to integrate other libraries or modules that by default are not installed in the Windows environment. We don't have any dependencies in our sample. Currently, PowerShell version 4.0 is available.
Ok, we also need to store the app data somewhere. Instead of having these values in the code, it's more elegant (and safe) to save these as App Settings. In here, we need to add keys for theTenantID. theAppIDand theAppSecretas here. The values must be inserted from the app we created above.
The functions reads two parameters from the HTTP body:groupnameandupn.groupnameis the name of the new group and since this is also the email address of the group, this must be compliant.upnis the login name of the group owner who shall be responsible for the group.
Then, it calls theInitialize-AuthorizationPowerShell function to authenticate with the app values from ourAppSettings. If this works, we get an AccessToken that is stored in the global variable$script:APIHeader. This is the key we need to add to each Graph API operation. It must be sent in the HTTP header with theBearerkey name. So, this header is fully generated by theInitialize-Authorizationfunction and can be added for each call.
Now back to the literal functionality. We need to do four operations:
Create the group and get back theGroupID
Get theUserIDof the UPN passed as parameter
Add theUserIDas owner of the group with theGroupID
Add theUserIDas member of the group with theGroupID
Each request is sent as a HTTP POST operation with the PowerShell command$result = Invoke-RestMethod -Method Postand a JSON body as described inpart 1. If the HTTP result of the operation is OK or Created, we know that the operation was successful and continue. In all cases, the function itself returns HTTP OK for not stopping the Flow (which will be described in part 3).
Add the parameters in the "Test" request body textbox.