Maker Offboarding Resource Transfer
Triggered when an Azure AD user account is disabled. Queries Dataverse inventory for all apps and flows owned by the departing user. Sends an Approvals request to their manager to designate a new owner for each resource. On approval, logs the transfer in Dataverse and posts a Teams confirmation.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
This scheduled cloud flow automates the reassignment of Power Platform resources (apps, flows, chatbots, and other assets tracked in a maker inventory) when a maker leaves the organization or is disabled in Entra ID. It discovers every resource still owned by the departing user in the Dataverse maker inventory table, requests manager approval to reassign ownership, records the transfer, and posts a confirmation in Teams so the governance channel has a clear audit trail.
The flow ships in Off state and is intended to run daily on a recurrence trigger. Swapping the recurrence trigger for an Entra ID "When a user is created, updated, or deleted" trigger is a supported customization — the core logic (discover → approve → update → notify) remains unchanged.
Use Case
When a maker is disabled or offboarded, any Power Platform resources they own must be reassigned before access controls lock them out entirely. Orphaned resources create compliance risk, break downstream automations, and prevent the app/flow from being edited. This flow removes the manual toil from IT admins by driving a per-resource approval to the departing user's manager, letting the manager either take ownership themselves or reject and nominate someone else.
Flow Architecture
Recurrence_Daily
Recurrence (Schedule)Scheduled daily trigger. Hydrate phase begins after the trigger fires. Supported customization: replace with the Entra ID 'When a user is updated' trigger gated on accountEnabled flipping from true to false.
Hydrate variables
InitializeVariable (x6)Six InitializeVariable actions pull every environment-scoped identifier into local variables: disabled user UPN, Teams group ID, Teams channel ID, approval deadline days, Dataverse inventory entity set name, and Graph endpoint. This keeps the rest of the flow free of inline @parameters() references and makes expression editing safe.
Get_Departing_User_Profile
Office 365 Users — UserProfile_V2Loads the departing maker's display name (parameter 'id', not the deprecated 'userId' from v1) for use in human-readable approval copy.
Get_Manager
Office 365 Users — Manager_V2Resolves the manager of the departing user (parameter 'id'). The manager becomes the approver for each resource transfer.
List_Owned_Resources
Dataverse — ListRecordsQueries the flowlibs_makerresourceinventory table filtered to rows where flowlibs_ownerupn equals the disabled user and flowlibs_transferstatus equals 'Pending'.
Apply_To_Each_Owned_Resource
Apply to each (foreach)For each resource returned from List_Owned_Resources: runs the per-resource approval, then conditionally updates the inventory row and posts a Teams confirmation.
Start_Approval_For_New_Owner
Approvals — StartAndWaitForAnApproval (Basic)Sends a Basic approval to the manager's email. Title and details are composed from the resource metadata so the manager can judge each asset individually.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_DisabledUserUPN | String | jdoe@your-org.com | UPN of the maker being offboarded. In production, swap to an Entra trigger dynamic and remove the recurrence trigger. |
| flowlibs_TeamsGroupId | String | <configure> | Teams group (team) ID where the governance channel lives. |
| flowlibs_TeamsChannelId | String | <configure> | Channel ID inside the above team where confirmations post. |
| flowlibs_ApprovalDeadlineDays | String | 5 | Advisory deadline surfaced to the manager in the approval body. |
| flowlibs_InventoryEntityName | String | flowlibs_makerresourceinventories | Entity set (plural logical) name of the maker inventory table. |
| flowlibs_GraphApiEndpoint | String | https://graph.microsoft.com/v1.0 | Base URL for Microsoft Graph (reserved for extensions that call Graph for additional attributes). |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Office 365 Users | shared_office365users | UserProfile_V2 (Resolve departing user's display name) Manager_V2 (Resolve the manager approver) |
| Microsoft Dataverse | shared_commondataserviceforapps | ListRecords (Read maker inventory) UpdateRecord (Write transfer result) |
| Approvals | shared_approvals | StartAndWaitForAnApproval (Basic approval per resource (OpenApiConnectionWebhook)) |
| Microsoft Teams | shared_teams | PostMessageToConversation (Governance confirmation post) |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Swap the trigger
- Replace Recurrence_Daily with the Entra ID 'When a user is updated' trigger and gate it on accountEnabled flipping from true to false. Bind flowlibs_DisabledUserUPN to the trigger's userPrincipalName.
- Use a distribution list for approval
- Point Start_Approval_For_New_Owner's assignedTo at a governance DL instead of outputs('Get_Manager')?['body/mail'] if your org routes all offboarding decisions to a central team.
- Record rejection reasons
- Add a branch to the If_Approved action's else block that captures body/responses[0]/comments and writes it to a new column on the inventory row. Keep flowlibs_transferstatus = Pending so the next run re-opens the conversation.
- Harden against empty inventory
- Wrap Apply_To_Each_Owned_Resource in a Condition checking length(outputs('List_Owned_Resources')?['body/value']) > 0 to avoid posting a 'no resources found' notice every day once offboarding is complete.
- Integrate the Admin Center PowerShell
- For true app/flow ownership reassignment (beyond inventory bookkeeping), add an HTTP action calling a custom connector wrapping Set-AdminFlowOwnerRole / Set-AdminPowerAppOwner. Chain it after Update_Inventory_Record.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Dataverse filter (list owned, pending resources)
Composed dynamically from the variable to keep the UPN out of the hard-coded definition.
EXPR.02Approval details body
Concatenates user profile output, resource metadata, and the deadline variable for the approval body.
EXPR.03Teams HTML message body
HTML fragment posted as body/messageBody; the Flow bot renders it inline in the channel.
EXPR.04Update record payload (slash-path keys)
Dataverse UpdateRecord uses slash-path keys for column updates, not a nested body object.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.