Governing Office 365 with Power Automate

Ben Stegink


In this eBook companion to the video “Governing Office 365 with Microsoft Flow”, we will learn about how we can use Flow to build our capabilities for monitoring and governing Office 365. We will look at some of the connectors which we can use, and how we can use them within Flow to build real-life solutions to maintain control over your tenancy.

What can you Govern?

There are a number of things that we can govern within Office 365 to allow you to maintain control over your environment or maintain awareness of what your users are actually doing.

Offce 365 Groups & Teams Creation

In the Microsoft Teams Virtual Summit, we went through the process of governing Microsoft Teams. Using Flow, we can build the processes which will allow the automatic provisioning of new Office 365 sites and Teams, allowing you to govern the collaboration elements of O365 without taking away the end-user empowerment.

Group and Team Reviews

Group and Team Reviews are a natural extension to the first element of governance, Office 365 Groups and Teams creation. Part of the site request may be asking the users for a date at which the site is no longer needed, which we can then use Flow to manage a review process.

This could be an annual or bi-annual review of all teams which have been created as an example.

Flows & PowerApps

There are management connectors to help manage the life cycle of Flows and PowerApps. There are some interesting things that you can do with these connectors whereby you could use Flow to collect data on your Flows and PowerApps and write them into a list so that you have a comprehensive catalogue of what is your tenancy.

Azure AD Groups and Flows

When we start to look at Azure AD users and groups, there are connectors that allow us to interact with Azure AD giving us the ability to interact with objects such as users to assign or remove licenses or govern what they can or can’t do.

Out of the Box Connectors

There are a large number of Out of Box connectors that can be utilised to manage various aspects of your Office 365 tenancy.

You should always be aware that some of the connectors are premium connectors which means that you need at least a Flow Plan 1 to be able to use them.

Key documentation

It is highly recommended that you review the documentation of each of the connectors to understand what the benefits are for using them.

Azure AD:


Azure Log Analytics:

Cloud App Security:

Flow for Admins:

Flow Management:

Graph Security:

Offce 365 Groups:

Offce 365 Users:

PowerApps for Admins:


Power platform for Admins:



A combination of these connectors can really help you to build out a fully functional governance solution to take your organisation beyond manual management. Remember one of the key aspects of Flow is to enable you to automate some of your tasks so that you can spend your day doing something more productive.


Whilst there are triggers associated with most of the connectors we have just looked at, there are some key triggers that should be highlighted when we talk about Governance. Combining these triggers with the elements which can be monitored within Office 365, then we are starting to build out quite a robust governance solution. The better your governance solution is, the more in control of your environment you are.

Cloud App Security

We have the ability to trigger a Flow when an alert is generated as there are a number of different events which can generate alerts. There are alerts such as a user externally sharing content from SharePoint or OneDrive for Business, which the organisation may need to be aware of.

We also have the ability to monitor for impossible logins, where we can detect multiple logins which are geographically impossible e.g. a sign in from Florida and then a second sign in from somewhere in Europe. It’s feasible that a VPN was being used, and in this case, the report can be resolved, but otherwise, we can build in a response to the event within Flow.

There are many more activities which we can monitor within Cloud App Security, therefore you should consider looking at what is available and feeding that into your governance plan.

Offce 365 Groups

The triggers which we can investigate here are related to users being added or removed from a group. Whilst it’s not feasible to monitor every single group within Azure AD, there may be key groups e.g. Legal which you want to monitor for activity and then report on.


If you’re using PowerBI to monitor the data being recorded about your O365 environment, then you could consider generating data generated alerts and use this to launch your Flow. All of this is available from the PowerBI connector.


With SharePoint we’re not necessarily monitoring SharePoint, more using SharePoint to store data from the other triggers, and then using Flows triggering from SharePoint lists to perform actions to support our governance solution.

Scheduled Flow

This is the perfect method to schedule checks of various assets with Office 365.

You could run a Flow on a daily basis which checks your SharePoint lists for items that need to be reviewed. You could use them to look at your Office 365 Groups, or connect to Exchange and monitor inboxes. Treat scheduled Flows as scheduled tasks, where you can configure them to run at specific intervals or at specific days/hours within the week.


It is always worth considering the ways in which you can alert your users, as you can reach out to them in a number of different ways. There are standard ways such as sending an email, or by sending a message within Teams. You can also configure text messages to be sent, so if you have detected an event that is classed as needing urgent attention, then you may want to explore this avenue so that you can reach an admin even if they’re not sat at their machine.

Taking action in Offce 365

We have so far looked at triggers, so what we can react to which tied into monitoring what is going on with Office 365. If we want to be a little bit more proactive, then we can leverage Flow to provision Office 365, Groups Teams and SharePoint Sites.

You can also use Flow to add and manage users. You can then extend this by using Flow to assign licenses or configure the services which they are licensed for without having to always be dependent on the help desk for this.

If you have multiple aliases for each user, then rather than creating them manually, again you could consider using Flow to automate this process. Automating manual processes such as this means that you are reducing the chances of error which humans are prone to.

Now that we have looked at how we can use Flow, we will look at some examples of where we could actually leverage Flow and how we would do it.

Real Life Examples

Azure Automation

The first example is just to illustrate how to connect Microsoft Flow to Azure Automation. If you can understand the way to achieve co-working between Flow and PowerShell in Azure Automation, then you unlock a huge amount of functionality that isn’t always directly available from Flow alone.

To set up Azure Automation, the first thing we need to do is navigate to the Azure Portal ( and create an Azure Automation Account. This is a free account and will run up to 500 minutes of PowerShell. This isn’t 500 minutes per month, or 500 minutes since it was deployed, this is up to 500 minutes per run. You can run a LOT of PowerShell in 500 minutes!

So Azure Automation is an extremely cheap compute

You can search for Azure Automation from the search box at the top of the Azure Portal, and from there you can see all of your existing accounts and create new ones.


The key piece of functionality we are interested in within the Automation Accounts are the Runbooks. These are your PowerShell scripts which are going to do all the work. Runbooks behave in the same way as you would expect a PowerShell script to run i.e. I can request parameters to be passed into the script for it to then execute some logic.

You can edit the PowerShell directly within the browser, or you can bring the code in from outside of the browser e.g. in Visual Studio.

The key thing to remember is that before you can use your Runbooks within Flow, you must publish them, otherwise, they will not be visible to the Azure Automation actions.


With Azure Automation, you have the ability to import and use any of the PowerShell modules which are present within the PowerShell gallery without having to install them yourself. This means that you can easily import the SharePoint Online modules, the PnP modules, Teams modules and the list goes on.

So as soon as you have created your Runbook, you should come and install your PowerShell Modules by selecting the one that you want to use and then selecting import. The import process will take a few seconds to complete, but once it has those PowerShell commandlets are then available to use within your Runbooks.


The other key area to be aware of with Azure Automation is the credential manager where I can securely store usernames and passwords which I’m going to use to connect back to my Office 365 tenancy.


We can declare and manage variables within the Automation Account which can then be consumed by our Runbooks. You can even encrypt your variables, so, for example, I use an App ID and Client Secret to connect to my environment, rather than a username and password. Therefore, I would encrypt the client secret as that is something that needs to be protected in the same way you would a password. The use of App ID and Client Secrets is purely a personal preference and the method for authenticating your scripts is entirely up to you.

Using my Runbook in Flow

Within Flow, I have the ability to use the Azure Automation connector to present the Azure Automation actions. You will see that we have three options here:

  1. Create Job – this will create a new instance of the job within the Azure Automation account It will be queued to run, and then the Runbook will pick the request up from the queue.
  2. Get job output – this will get any outputs that we are returning from the Azure Automation job
  3. Get status of job – this will return the existing state of the job

The two actions we are going to use within our examples are “Create job” and “Get job output”.

Create job can be thought of as “Start my PowerShell” so therefore that is the first action I need to use. The action configuration is fairly straightforward as it will integrate with your Azure subscription and allow you to select the various elements based on what you have access to. Therefore, you will only ever see the subscriptions, resource groups etc that you can access.

All we need to do then is select the Subscription, Resource Group, Automation Account and the Runbook. They are all dependent on each other, so start at the top and work your way down. The “Wait for Job” field is very important if you have actions later in your Flow that is dependent on your PowerShell. By selecting No, the Flow will trigger the job and then continue processing, effectively running in parallel with the PowerShell scripts. Most of the time we would say “Yes” which will mean that Flow will wait until it receives a completed signal back from the Azure Automation, at which point Flow will continue with any subsequent actions.

The second action I am going to use is the Get job output action. I can configure this in the same way, however this time I need to supply it with a Job Id. This is a piece of dynamic content that is made available from the Create job action, therefore I can select this from the toolbox.

So now if I run a Runbook which is just going to return the string “Hello World”, I can run this Flow, which will start the PowerShell script, and then wait for the script to return a value. Then when I look at the output, I will see that I have my “Hello World” string returned.

The thing to be aware of is that if you output an error message from your script, it will be picked up as the output from the script. Therefore, unless you handle the error, Flow will then continue to run as though it has a legitimate response.

If your Runbook requires you to pass parameters into it, the Create job action will be able to detect that those parameters exist. What it won’t do, however, is validate the type of data that is being placed into the parameter field. Therefore, you need to ensure that you are familiar with your script and that you are passing the correct type of data to your job.

Provisioning Offce 365 Sites, Groups and Teams

So now that we have looked at the basics of how to use Azure Automation with Microsoft Flow, we are now going to look at a real-life example. This relies on a process starting with our users interacting with assets in SharePoint.


We have a “Groups and Teams Provisioning“ List within SharePoint which contains various pieces of information including Access Type, aliases, Teams memberships, and even an expiry. There are a number of additional fields which you may wish to capture based on your own information storage requirements.

One of the key things which I am doing within my provisioning process is appending a unique number to the end of all of my sites to ensure that there are no conflicts with regards to site URLs. I, therefore, have a second list created which simply stores “SiteNumber” which is incremented each time a new site is created.

The other aspect which I have done within this solution is to create a security group within Azure AD which means that only certain people can create sites, everyone else would have to go through this process of creating an item in the list, which means they have to provide a lot more information before they get their site.

Requesting a Site

When my users are requesting a site, I have created a PowerApp to replace the out-of-the-box SharePoint form which collects all of the key information from the standard site creation form, but we are now requesting additional information such as whether we need end date, Teams creation, external emails etc.


If we now look at what is going to happen behind the scenes after the site has been requested, we need to go to Flow.

The first thing is the trigger. This Flow is configured to run when a new item is created within the “Groups and Teams Provisioning” list which means that all of the metadata which has been entered by the user can now be used within my provisioning process.

The second thing I am doing is to start an approval process which could go to an administrator, or to the line manager of the requestor. Those approvals will be sent to the approver, and they can approve or reject in several different ways:

  • From within the Flow Approval Center
  • Directly from the Email
  • From the Flow Mobile App

We then need to handle the output of the approval process by including a Condition that will check the outcome. If it has been approved, then we can start to process the site creation. In order to build the site, the first thing I am going to get the site number from the list within SharePoint by using the Get Item action.

The next thing I am doing is using the Site type from the request to determine what the path of the site is going to be i.e. if it is going to be /Teams or /Sites. In this case, I selected a Team so my condition will set the site prefix to “Teams”

Now that I have the prefix, and the next unique site number, I can build the URL, combining all of the constituent parts, and store that in a variable.

Once I have got the URL I can Start the job which is going to create my site. Due to the amount of data that I need to create my site, there are a lot more parameters needed by my Runbook, all of which are based on the inputs from the user when they requested the site.

This is called a Runbook in Azure Automation which is then going to use a combination of different modules to provide all the relevant assets e.g.

  • Create a Team or an O365 Group
  • Set security details

Once the job has run, and the provisioning process does take a few minutes, then we can then handle the rest of the process which includes notifying the users, updating the group number list to the next available number, and finally updating the SharePoint list to mark the site as being created.

Stale Groups

This is a Flow that runs on a schedule, once per day at 4 AM, and it will process each item in the Site Request list to check if any of those sites have gone past their end date. If it has gone past the end date then it will email the person who requested the site and send them a message on Teams, to see if the site is still needed or if it needs to be deleted.


Governance is one of the key aspects for driving the adoption of Office 365 whilst maintaining control over its growth. The built-in tools for O365 allow you to achieve a lot, but this can be massively improved by using Microsoft Flow.

We have looked at what we can govern by building our own solutions such as the ability to control the creation of SharePoint Sites and Teams, we can build review processes to allow us to close down sites once they are no longer needed. We discussed elements of governing Azure AD such as creating users, monitoring security groups, or even reacting to threats that have been flagged by threat management.

There are a large number of connectors that can be used to build out our governance solutions, some of which have triggers associated with them, others that only have actions. We can, however, use recurring Flows to help to monitor certain areas of both Office 365 and Azure to ensure that if an action is needed, or someone needs to be alerted, then we can do that in a prompt manner.

We then put all of these items into practice by using Flow and then combining it with the power of Azure Automation to be able to build out a fully functioning provisioning solution that maintains governance and helps to build site lifecycle management to ensure that stale content is removed from the tenancy.

Microsoft Flow, when used in this manner, helps you to maintain your awareness of what is going on within your tenancy, and ultimately reduces the management overhead allowing you to spend your day working on something more productive.

0000-00-00 00:00:00

Leave a Reply

Your email address will not be published. Required fields are marked

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}