Do you know what is hard-coded inside your fifty Power Apps?
Site URLs, SQL servers, Power BI links and environment ids get typed into formulas and never leave. No admin API reports them. Here is where they live and how to read them out at estate scale.

Ask a Power Platform administrator what a given app connects to and they can answer in about thirty seconds. The admin centre knows. SharePoint, SQL Server, Office 365 Outlook — the bindings are right there.
Now ask which SharePoint site. Which SQL server. Which Power BI report. Whether the thing the app opens when you press the button on screen four is in this tenant at all.
That question has no answer in the admin surfaces, and on an estate of fifty apps nobody has ever sat down and read fifty apps to find out. It is not a governance failure. It is a consequence of where the information lives.
Bindings are inventoried. Contents are not.
Everything Microsoft exposes about an app through the admin APIs describes the app’s relationships: which connectors it binds, which connections those resolve to, who owns it, who it is shared with, which environment holds it. That is a genuinely useful inventory and it is the thing most tools stop at.
What it cannot describe is what the app does with those relationships, because that is written in formulas inside the app, and formulas are not metadata. A canvas app is distributed as a .msapp package. The screens, the controls and every expression on them are in that package. The admin API never opens it.
So anything a maker typed rather than bound is invisible:
- A site URL typed into a
Patch()or a data source name, rather than picked from the connector. - A deep link to another app that carries the source environment’s id in the query string.
- A Power BI report or dashboard URL, either embedded in a tile or opened in a browser.
- A SQL server and database name, which the connection carries but the app’s own data sources name again.
- The hostname of the environment itself, written into a link so somebody could “just open the thing”.
Why these survive every review
Because they work. A hard-coded URL is not a broken URL — it is a URL that resolves perfectly, every day, for years, in the environment it was written in. It only becomes wrong the moment the app is somewhere else, or the thing it points at is gone.
That gives you two days on which it matters, and they are the two days you least want a surprise:
- A migration. The app imports cleanly into the new tenant. Every screen opens. The document library link on screen four still points at the old tenant, and will keep doing so until a user notices.
- A decommission. You retire a SharePoint site or a Power BI workspace, and three apps you had no reason to associate with it start throwing errors.
Neither failure shows up in testing, because testing checks that the app works, and the app does work.
Where to actually look
There are three different places, and they answer different questions.
1. The app package, for anything typed
The .msapp is the only place a typed string exists. Reading it means downloading the package for each app and searching the source inside it. That is entirely doable for one app. For fifty it is a weekend, and for a tenant with several hundred it is nobody’s job.
This is the search Power Insights runs for you, across every canvas app in a selection, with five prepared searches for the things that break a move — plus any literal string you want to type.

2. The app’s resolved data sources, for what it really points at
“It uses a SQL connection” is not an answer you can act on. The useful version names the server and the database, and distinguishes what came out of the package from what came out of the admin API — because those carry different levels of certainty and a single merged list quietly hides which is which.

3. The flow definition, for where each step writes
Flows have the same problem one level down. The connection carries an identity; the flow definition decides the destination. A flow whose connector list says “SQL Server” may be running a native query against a named production database, and only the definition will tell you that.

What the list is actually for
Finding the references is the easy half. Deciding what to do with each one is the work, and there are only three outcomes:
- Replace it with an environment variable. If the value legitimately differs between dev, UAT and production, that is what environment variables exist for. They travel inside the solution and get their value set per environment at import.
- Replace it with a proper binding. A site picked through the connector moves with the app. A site typed into a formula does not.
- Accept it and write it down. Some references are genuinely fixed — an external service, a public page. Those are fine, as long as they are on a list somebody will read before the next move.
What you cannot do is leave them undiscovered, because the cost is paid later and by somebody else. An app that imports cleanly and behaves wrongly is far more expensive than an app that fails loudly on import.
Do this before the migration, not during it
The reason to run the search early is that the answers change the plan. A dozen apps pointing at one SharePoint site is a different piece of work from a dozen apps pointing at a dozen sites. A Power BI report referenced by four apps is a dependency that has to be stood up in the target before any of them land.
None of that is knowable from a list of app names, and all of it is knowable from the app source in an afternoon.
Power Insights migration planning reads every canvas app package in a selection and exports the answers — and the same reader resolves each app’s real data sources and each flow step’s actual destination. Related reading: the three things that break every Power Platform migration.




