How to use Power Automate to manage Ownerless Teams (& Groups)

A Microsoft Team or Group without an owner is ungoverned and unmanaged. It is like a school classroom full of children without a teacher. You know it will end up in chaos.

So do you have an effective process to manage your ownerless teams?

Read on to find out how you can to mitigate the issue by using Power Automate to automatically transfer ownership to another user.

1. What is an ownerless Team?

An ownerless Team has

  • No assigned owner
  • Still be used by its members
  • Activities are limited
  • No membership management
  • No guest management

Ownerless Teams causes several issues:

  • The Team has no accountability
  • Membership requests to join private Groups and Teams stay unapproved because no owner exists to process requests.
  • No governance for external guest users.
  • If the Azure AD Access reviews or Expiration reviews are enforced then there is no owner to either review the membership of the Group or confirm whether the Group is still needed. The fallback process for this is to send the notifications to an Admin email for manual follow up.

2. Why do ownerless Team occur?

Ownerless Teams occurs when a person leave the organization and they were the only owner of a Team.

If the admin closes the user’s account without reassigning ownership of the Team then the Team becomes ownerless.

If the admin blocks access to the account then the user is still shown as a Team owner however the owner has no access to the Team. So effective becomes an ownerless Team.

3. Is this just a Teams problem?

No. When you create a Team, a Microsoft 365 Group is created to manage Team membership. The Group’s related services, such as a SharePoint site, Power BI workspace, etc. are created at the same time.

Microsoft 365 Groups manage the member of all Teams, Yammer and Exchange based Groups created through Outlook, Planner, Power BI, Stream and SharePoint.

Therefore, all types of Microsoft 365 Groups can end up ownerless.

❗ It is important to include all Microsoft 365 Groups in your processes and not just Teams. Therefore, the rest of the guide describes how to manage all Microsoft 365 Group types and not just Teams.

4. But doesn’t Microsoft have controls to stop the last owner of the Group being removed?

Surely Microsoft has controls in place to stop the last owner being removed?

Yes but they don’t cover all scenarios.
For example, when an admin tries to remove the last owner through one of the Admin centers they are blocked from doing so and a warning message is displayed. The admin must promote another member as Group owner before the first owner is removed.
See examples from the Teams Admin center, Microsoft 365 Admin Center and Azure AD Admin center.

Likewise, if the sole Group owner tries to leave the Group or swap to become a member they are blocked. Again a warning message is displayed and the owner must promote another member as owner before they can either change to a member or leave the Group.
See example warning messages when trying to leave a Team and an Outlook Group.

5. So why do ownerless Groups occur?

Ownerless Groups arise from your leavers process.
The issue arises when you delete a user account. In this scenario the user is removed from all the Groups by system processes so there are no warning messages. If that user happened to be a sole owner of a Group, then that Group becomes ownerless.
In addition, if the user account is blocked rather than deleted then the user’s Group membership is not impacted. Yet, this still causes an issue as the Group now has an owner with no access. So effectively ownerless.

6. Can I check their Group ownership before I delete/ block their account?

6.1 Admin centers

Not directly from any of the Admin centers. The admin can view the user’s profile and see all Microsoft 365 Groups and Security Groups they belong to. However, this does not show whether the user is a member or owner of the Group. The only way to check is to view each Group in turn to see if the user is a Group owner.
The admin then needs to decide who to add as the new owner if removing the user will make the Group ownerless. This may require the admin having to send messages to the user or the users ‘manager to finds out who should take over ownership or the admin just promotes an existing member as owner.
As this is a time-consuming process it is often overlooked. So this is why ownerless Groups and Teams occur.

6.2 PowerShell or Graph API scripts

PowerShell or Graph API scripts can be used, but this requires the admin user has the relevant access permissions and also be familiar with the commands.

6.3 Power Automate

The simplest way to find which Groups a user is an owner of is to build a Power Automate flow.
The two key benefits are:

  • No technical skills required.
  • No admin permissions required to run the flow if you use an automated trigger for example completion of a Form or entry in a SharePoint List or file saved in folder etc.

Plus, you can then extend the flow to:

  • automatically add a nominated user or manager as owner to all the Groups that the user is an owner of.
  • notify the nominated user or manager why they have been added as Group owner and that it is now their responsible for reassigning ownership if needed.

This flow can then be further customized to align with your specific business processes. For example

  • Capture replacement owner details
  • Add an approval step.
  • Update ticket status.
  • Extend to the movers process as well as the leaver process.

7. Lets build the Power Automate Flow

The Power Automate steps detailed below show you how to create a basic process to reassign Group ownership to the users manager.

You can customize the flow to suit your specific business processes.


This Power Automate uses Office 365 Groups Send HTTP Requests (Preview) to run Graph API as the standard actions do not provide the functionality required. Note this is still in Preview.

The flow will cover the following functionality

Full flow steps..

7.1 Trigger

This is a basic flow that is being manually triggered where the user running the flow enters in the email address of the user that is moving or leaving.
In this scenario the user running for the Flow must have the following Administrator permissions:

  • GroupMember.ReadWrite.All
  • Group.ReadWrite.All
  • Directory.Read.All
  • Group.ReadWrite.All
  • Directory.ReadWrite.All
  • Directory.AccessAsUser.All

Note if an automated flow is used then the user triggering the flow (for example by submitting a Form) only needs user permissions.
Trigger = Manually Trigger a flow
Add an input to capture the leavers email address.

7.2 Initialize variables

Create two variables
The first variable is of type array. This will be used later in the flow to store the list of Groups that the leaver is owner of.
Action = Initialize Variable
Type = Array


The second variable is of type integer. This will be used later in the flow to hold the count of the Groups the leaver was owner of.
Action = Initialize Variable
Type = Integer

7.3 Get the user’s profile

Action = Get user
User Id or principle name = Add in the dynamic content for the email address that was captured as part of the instant trigger.

7.4 Get list of all Microsoft 365 Groups that the user belongs to

It is not possible to directly return a list of all Groups a user is owner of. So this process needs to be managed in a number of steps.
The first is to get a list of all Groups the user is a member of.
Graph API is used in the Office 35 Group HTTP Request (Preview) action to list all the Groups the user belongs to. Note this returns all Azure AD Groups which includes Security Groups. The request is filtered to return just Unified Groups (Microsoft 365 Groups).
Action= Office 35 Group HTTP Request
URI = https://graph.microsoft.com/v1.0/users/⁠I⁠/memberOf/$/microsoft.graph.Group?$filter=GroupTypes/any(a:a eq ‘unified’)
Method = GET

7.5 Parse response to get its component parts

The body of the response must be parsed so that the information is turned in dynamic content. This will allow the next steps to read the unique id of each Group.


Action = Parse JSON
Schema =

{
“type”: “object”,
“properties”: {
“@@odata.context”: {
“type”: “string”
},
“value”: {
“type”: “array”,
“items”: {
“type”: “object”,
“properties”: {
“id”: {
“type”: “string”
},
“createdDateTime”: {},
“displayName”: {
“type”: “string”
}
}
}
}
}
}

7.6 For each Group the user is a member of apply the following steps

The following steps must be under the Apply to each step.

7.6.1 For each Group that the user is a member list the owners

For each Group the user is a member get a list of owners for each Group.
Action = Office 35 Group HTTP Request (Preview)
URI = https://graph.microsoft.com/v1.0/Groups//owners
Method = GET
As the list of Groups can have multiple responses an Apply to each action is automatically added if it has not already been added.

7.6.2 Parse response to get its component parts

The body of the response must be parsed so that the information is turned in dynamic content. This will allow the next steps to read the owner ids.

Action = Parse JSON
Content = Body from previous step
Schema =
{
“type”: “object”,
“properties”: {
“@@odata.context”: {
“type”: “string”
},
“value”: {
“type”: “array”,
“items”: {
“type”: “object”,
“properties”: {
“@@odata.type”: {
“type”: “string”
},
“id”: {
“type”: “string”
},
“displayName”: {
“type”: “string”
},
“userPrincipalName”: {
“type”: “string”
}
}
}
}
}
}


7.6.3 Filter the output to only Groups where the user is a Group owner

This step filters the Groups to only show Groups where the user is an owner.
Important. This action is still under the Apply to each action.
Action = Filter Array
From = select the Value returned from the previous step that lists all the owners in the Group.
Filter =
User Principal Name from JSON response is equal to the user’s email address entered in the trigger step.

7.6.4 For each Group where the user is owner add to an array

Action = Append to Array
From = Body from the previous step that filtered the Group and append Group Id & Display Name to an array of Groups.
An Apply to each step is automatically added as there may be multiple Groups in the list.
Name = Select the array variable set up
Value =
{
“DisplayName”: ,
“ID”: id
}

7.7 Create an HTML table of the Groups that the user is owner of

Note. This action is outside of the Apply to each step.
Action = Create HTML table
From = Select the array variable
Columns = Automatic

7.8 Create a count of how many Groups and Teams where user is owner


Count how many Groups the user is an owner of. This is calculated by counting the number of rows in the array variable which has stored all the Groups the user is owner of.
Action = Set Variable
Name = Integer variable
Value = This is an Expression
Expression = length(variables(”))

7.9 Check if the user a Group owner

It is possible that the user may not be an owner of any Groups. The previous step set the integer variable with the number of Groups the user is owner of.
Action = Condition
Condition = Integer variable is greater than zero

7.10 User is not a Groups owner

A chat message is posted to the user who triggered the flow to state that the user entered is not an owner in any Groups.
Action = Post message in a chat
Post as = select bot
Recipient = user email of the user who triggered the flow

Flow ends.

7.11 User is an owner of one or more Groups

If user is Groups and Teams owner.

7.12 Look up user’s manager

Action = Get Manager
User = Id from the Get user action

7.13 Error Handling step if the user has no manager assigned

If the user does not have a manager assigned in their Azure AD profile then the Flow fails with a 404 error.
An error handling step is added after the Get Manager action.
The error handling posts a Teams chat message to User running the Flow stating no manager and to follow the manual process to assign the Group ownership to someone else.
Action = Post message in chat or channel
Recipient = user who triggered the flow
Message = add appropriate text and include the email address of the user.

Then select the three dots in the right of the header and select Configure Run after
Tick has Failed
Untick is successful and Done

The line above the action changes to a dashed red line to denote it is only followed if the flow has failed.

7.14 If user has manager

Add a new step under Get Manager to allow for the alternative flow when the user has a manager.
Select the + under the Get Manager to add a additional step.

The next steps will be applied if the user has a manager.

7.15 Get Group Id

The Group Id needs to be extracted from the array variable that holds the list of Groups that the user is owner of.
This automatically adds the Apply to each step as there may be one or more Groups in the array.
Action = Compose
Input = Add an Expression
Expression = item()?[‘ID’]

7.16 Add manager as Group member

The manager needs to be added as a member of each Group. Note: If the manager is already a member of the Group then the Action errors. This is expected behaviour so the flow continues.
Action = Add member to Group
Group id = Output from the Compose step
User Principal Name = User Principal Name from the Get Manager step

7.17 Add manager as Group owner

Add the manager as owner of the Group. There is no standard action for this so Graph API is used via a HTTP action.
If the manager is already an owner of the Group then the Action errors. This is expected behaviour so the flow continues.
Action = Office 35 Group Send HTTP Request (Preview)
URI = https://graph.microsoft.com/v1.0/Groups//owners/$ref
Method = POST
Body
{
“@odata.id”: “https://graph.microsoft.com/v1.0/directoryObjects/”
}

Note both add member and add owner steps must be included as if you just add owner then they are not shown as member of the Group.

7.18 Post message in Teams Chat to the person who triggered the flow


Important this step must be outside of the Apply to Each step so that the manager only receives on chat message with a summary rather than a message for each Group they have been added to.
See example below.

Send a Teams Chat message to the User running the Flow to notify them that flow completed OK.
Action = Post Message in a chat
Recipient = User email of user who triggered flow
Message =
Add your wording.
Add in the count of Groups they have been added
Add Output of the HTML table

7.19 Post message in Teams Chat to Manager


Send a Teams chat to Manager notifying them that they have been added as owner to one or more Groups and it is their responsibility to reassign ownership if needed.
Action = Post Message in a chat
Recipient = User email of Manager
Message =
Add your wording.
Add in the count of Groups they have been added
Add Output of the HTML table

Power Automate Flow ends

Link to Power Automate flow

If you want to try this out then download the flow from github Public/Ownerlessgroups_20220215191358.zip at main · nikki-c/Public · GitHub

Keep Reading

PreviousNext