Orphaned App Detection & Cleanup Approval
Power Apps for Admins surfaces apps with no sessions in 90+ days and no recent modification. Sends an Approvals adaptive card to the owner. On timeout or rejection, flags the app for admin action in Planner.
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
FlowLibs - Orphaned App Detection & Cleanup Approval is a scheduled Power Automate cloud flow that uses the Power Apps for Admins connector to identify canvas apps that have had no user sessions for 90+ days and have not been modified recently. For each candidate, the flow sends the owner an Approvals adaptive card via Teams asking whether the app is still needed. Owner approvals are logged to Dataverse; rejections or timeouts produce a Planner task in the IT admin board so the platform team can reassign, archive, or delete the app.
The pattern keeps cleanup decisions with the people closest to the work while still giving the CoE / IT admin team a managed backlog of items that need follow-up.
Use Case
Canvas-app sprawl is one of the most common governance pain points in maturing Power Platform tenants. Apps get published as quick prototypes, never re-used, and quietly stay in Production for years — racking up premium-license assignments, increasing data-loss-prevention surface area, and showing up in every export the security team runs.
This flow puts an automated, low-friction cleanup loop in place: every week the platform team gets only the apps that owners have either rejected or ignored, with full attribution and a one-click Planner task per app. Owners stay in the driver's seat for apps they recognize, and the IT admin team only has to triage the genuine orphans.
The flow is ideal for teams that:
- IT admin and Center of Excellence teams running governance on a tenant with hundreds of canvas apps
- Organizations that need a defensible, owner-attributed audit trail before deleting or archiving apps
- Platform teams that already use Planner for IT backlog and want orphaned-app work to land in the same board
Flow Architecture
Recurrence Weekly Monday 7am
RecurrenceFires every Monday at 07:00 in the configured time zone — the report lands in the admin's queue before the workweek starts.
Initialize varInactivityDays
Initialize Variable (Integer)Loads flowlibs_InactivityThresholdDays — the number of days with no sessions and no modifications that makes an app a candidate (default 90).
Initialize varAdminEmail
Initialize Variable (String)Loads flowlibs_AdminEmail — recipient for digest notifications and fallback owner when an app's creator is missing.
Initialize varPlannerPlanId
Initialize Variable (String)Loads flowlibs_PlannerPlanId — the Planner plan that receives orphaned-app cleanup tasks when an owner rejects or times out.
Initialize varPlannerBucketId
Initialize Variable (String)Loads flowlibs_PlannerBucketId — the bucket within the plan where new orphan tasks are filed.
Compute Cutoff Date
ComposeBuilds the cutoff timestamp used to filter apps: addDays(utcNow(), mul(variables('varInactivityDays'), -1)). Anything modified or last-used after this point is excluded.
Get Apps As Admin
Power Apps for Admins — Get-AdminAppsLists every canvas app in the tenant with owner, last-modified, and usage metadata. The flow filters the result set against the cutoff to find inactivity candidates.
Filter Inactive Apps
Filter arrayKeeps only apps whose lastModifiedTime is older than the cutoff AND whose telemetry shows no sessions in the inactivity window. Apps modified recently are excluded even if usage is low.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_InactivityThresholdDays | Number | 90 | How many days an app must go without sessions and without modifications before it counts as a candidate. 90 is a common starting point; tighten to 60 for stricter governance. |
| flowlibs_ApprovalTimeoutHours | Number | 168 | How long the owner has to respond to the adaptive card before the flow treats silence as 'no longer needed' and routes to Planner. 168 hours = one week. |
| flowlibs_AdminEmail | String | alerts@yourcompany.com | Mailbox or distro list that receives the weekly run-summary email and serves as the fallback owner when an app's creator can't be resolved. |
| flowlibs_PlannerPlanId | String | <configure> | GUID of the Planner plan that should receive cleanup tasks. Find it in the Planner web URL: /Home/Planner#/plantaskboard?planId=<this-value>. |
| flowlibs_PlannerBucketId | String | <configure> | GUID of the bucket inside the plan where cleanup tasks should be created. Typically a dedicated 'Orphaned Apps' bucket. |
| flowlibs_AdminTeamsChannelId | String | <configure> | Teams channel ID for the IT admin notifications when a cleanup task is created. Format: 19:<id>@thread.tacv2. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Power Apps for Admins | shared_powerappsforadmins | Get-AdminApps (lists every canvas app in the tenant with owner and usage metadata) |
| Approvals | shared_approvals | StartAndWait (posts an Approve/Reject adaptive card to the app owner and waits for the response or timeout) |
| Microsoft Teams | shared_teams | PostMessageToConversation (ephemeral confirmation back to the owner after a keep-in-use response) PostMessageToChannel (summary post to the IT admin channel when a cleanup task is created) |
| Microsoft Dataverse | shared_commondataserviceforapps | AddNewRow (writes one FlowLibs Orphan App Reviews row per owner decision for audit) |
| Planner | shared_planner | CreateTaskV3 (files a cleanup task in the IT admin Planner bucket on reject or timeout) |
| Office 365 Outlook |
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.
- Authorize the admin-scoped connections
- Power Apps for Admins and Approvals must be authorized with an account that has Power Platform Admin or Global Admin rights — only admin-scoped accounts can list canvas apps owned by other users. Use a dedicated service account where possible.
- Create the Dataverse table
- The flow expects a custom table named 'FlowLibs Orphan App Reviews' with columns: AppId (text), AppDisplayName (text), Owner (text), Decision (choice: KeepInUse / NeedsCleanup), Responder (text), Comment (multiline text), ReviewDate (date/time). Add the table to your governance solution before importing.
- Set the Planner targets
- Populate flowlibs_PlannerPlanId and flowlibs_PlannerBucketId with the GUIDs of the plan + bucket that should receive cleanup tasks. The simplest setup is a single 'IT Governance' plan with an 'Orphaned Apps' bucket.
- Tune the inactivity window
- flowlibs_InactivityThresholdDays defaults to 90. Drop to 60 for stricter cleanup or raise to 180 if a quarter-end cycle suits your team better. flowlibs_ApprovalTimeoutHours defaults to 168 (one week) — increase if owners frequently travel.
- Adapt the adaptive card
- The Approvals card text lives inline in the StartAndWait action. Add tenant-specific instructions ('Reply within one week or this app will be queued for admin cleanup') or branding directly in the card body.
- Turn the flow on
- The flow ships in the Stopped (Off) state. Toggle it to On once all six environment variables are populated, the Dataverse table exists, and connections are authorized.
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.01Compute the inactivity cutoff date
Used in Compose Cutoff Date and in the Filter Inactive Apps condition.
EXPR.02Filter inactive apps
Filter array condition — keeps apps that are both stale to edit and stale in usage.
EXPR.03Detect owner approval
Drives the If Owner Approved condition. Reject and Timeout both fall through to the reject branch.
EXPR.04Planner task title
Used on Create Planner Cleanup Task — title.
EXPR.05Planner due date (two weeks out)
Used on Create Planner Cleanup Task — dueDateTime. Gives the platform team a SLA on each item.
EXPR.06Owner identifier with fallback
Used on StartAndWait — assignedTo. Falls back to the admin mailbox when an app has no resolvable owner.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.