Duplicate App Name Detection Report
Scheduled flow queries the canvas app inventory in Dataverse, groups apps by normalized name similarity using string distance logic, flags clusters of apps with near-identical names across environments, and exports a duplicate-candidate report to Excel with an email to the COE lead.
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
A scheduled Power Automate cloud flow that runs every Monday at 8:00 AM UTC, reads the full canvas app inventory from Dataverse, normalizes each app's display name, flags apps whose normalized names collide, appends a snapshot row to an Excel workbook in SharePoint, and emails the COE lead an HTML report of the flagged duplicates. Ships Off — only connection authorization and a few environment variable values are required to enable it in a new tenant.
Use Case
App sprawl is a silent tax on any Power Platform COE. When makers copy apps between environments, rename things inconsistently (Time-Off Tracker, timeoff tracker, Time Off Tracker), or stand up near-identical apps in parallel, the COE ends up with clusters that should be consolidated but nobody notices. This flow gives the COE lead a weekly, automatically generated list of collision candidates so they can have the conversation before the clusters grow.
Flow Architecture
Weekly_Monday_8AM
RecurrenceFrequency `Week`, interval `1`, schedule `Monday @ 08:00 UTC`.
Init varTargetEnvironment
Initialize variableString bound to `flowlibs_TargetEnvironmentName` (logged in the email for operator context).
Init varCOELeadEmail
Initialize variableString bound to `flowlibs_COELeadEmail` (single recipient of the report).
Init varExcelSiteUrl
Initialize variableString bound to `flowlibs_DuplicateAppExcelSiteUrl` (SharePoint site URL).
Init varExcelDriveId
Initialize variableString bound to `flowlibs_DuplicateAppExcelDriveId` (Graph drive identifier).
Init varExcelFile
Initialize variableString bound to `flowlibs_DuplicateAppExcelFile` (server-relative workbook path).
Init varExcelTable
Initialize variableString bound to `flowlibs_DuplicateAppExcelTable` (named Excel table).
Init varReportDate
Initialize variableString (empty — set downstream).
Init varDuplicateApps
Initialize variableArray (empty — accumulator for flagged apps).
Set Report Date
Set variable`formatDateTime(utcNow(), 'yyyy-MM-dd')` into `varReportDate`.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_TargetEnvironmentName | String | <your-tenant-id> | Environment ID (for logging in the report; canvas apps are queried via Dataverse, which is implicitly the current env). Replace with your Power Platform environment ID. |
| flowlibs_COELeadEmail | String | you@yourcompany.com | Recipient of the weekly duplicate report email. Set to the distribution list or person who owns app governance. |
| flowlibs_DuplicateAppExcelSiteUrl | String | https://your-tenant.sharepoint.com/sites/FlowLibs | SharePoint site URL hosting the Excel workbook. |
| flowlibs_DuplicateAppExcelDriveId | String | <configure> | Graph drive identifier for the document library that contains the workbook. Find it via the Excel Online connector's picker or `GET https://graph.microsoft.com/v1.0/sites/{siteId}/drives`. |
| flowlibs_DuplicateAppExcelFile | String | /Shared Documents/FlowLibs - Duplicate App Report.xlsx | Server-relative path of the Excel workbook. |
| flowlibs_DuplicateAppExcelTable | String | DuplicateAppReport | Named Excel table that receives the weekly snapshot row. Columns: ReportDate, TotalApps, DuplicateAppCount, Environment. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Microsoft Dataverse | shared_commondataserviceforapps | ListRecords (lists canvasapps) |
| Excel Online (Business) | shared_excelonlinebusiness | AddRowV2 (appends weekly snapshot row) |
| Office 365 Outlook | shared_office365 | SendEmailV2 (sends report to COE lead) |
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.
- Authorize all three connections
- On first open, authorize Dataverse, Excel Online (Business), and Office 365 Outlook. The designer will prompt; click Add new connection for each.
- Create the target Excel workbook
- Provision a workbook in the SharePoint site configured by flowlibs_DuplicateAppExcelSiteUrl. The workbook should live at the path in flowlibs_DuplicateAppExcelFile and contain a table whose name matches flowlibs_DuplicateAppExcelTable. Required columns: ReportDate, TotalApps, DuplicateAppCount, Environment.
- Update flowlibs_DuplicateAppExcelDriveId
- Replace the <configure> placeholder with the real Graph drive ID for that library. You can find it via the Excel Online connector's picker in the designer or via GET https://graph.microsoft.com/v1.0/sites/{siteId}/drives.
- Update flowlibs_COELeadEmail
- Set the env var to the real distribution list or person who owns app governance.
- Tighten the normalization rule (optional)
- Inside Select Normalized Apps, the default strips spaces and hyphens. You can extend it to strip underscores, perform plural stripping, or apply Soundex-style encoding depending on how aggressive you want duplicate detection to be.
- Turn the flow On
- Once env vars and connections are wired up, turn the flow on from the solution page — it ships in the Stopped state.
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.01Report date
Computes the report date string used in the email subject and the Excel snapshot row.
EXPR.02Normalized app name (inside Select)
Lower-cases the display name and strips spaces and hyphens so variants like `Time-Off Tracker`, `timeoff tracker`, and `Time Off Tracker` collapse to a single key.
EXPR.03Outer-loop reference inside the nested Filter array
Inside `Filter_Apps_With_Same_Normalized_Name`, `item()` is the filter's current element while `items('Apply_To_Each_App_For_Duplicate_Check')` reaches back to the outer Apply-to-each's current element. This lets a Filter array operate against the outer loop's pivot without a nested Apply-to-each.
EXPR.04Duplicate check condition
Inside the loop's Condition: flags the current app when more than one entry shares its normalized name.
EXPR.05Email subject
Builds the subject line by appending the report date.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.