Evincia

The legacy .NET and SQL Server triage checklist

What to inventory before you scope a modernization -- grouped by the four dimensions that decide how hard it will be.

Most modernization conversations start in the wrong place. The question on the table is usually "should we move to .NET 10, and what will it cost," and the honest answer is "we can't tell you yet, because nobody has written down what's actually running." A triage fixes that. It's the inventory you do before you scope the work -- not the work itself, and not a score.

This checklist is organized into four groups, and the groups are not arbitrary. They are the four Modernization Readiness dimensions Evincia scores in a full assessment: platform obsolescence, architectural coupling, dependency risk, and change safety. Here we don't score anything. We tell you what to inventory and where in a .NET and SQL Server estate to actually find it.

The most useful thing this checklist produces is not a clean inventory. It's a list of the things you couldn't answer. Unknowns are findings. Every blank is a cost assumption and a timeline assumption nobody has measured, and the count of blanks is a better risk signal than any single answer.

1 · Platform obsolescence -- what you're standing on

The versions and lifecycles underneath the system. This maps to the Platform Obsolescence dimension. The point isn't to judge old software for being old. It's to find the things that are out of support (past the date the vendor stops shipping security patches), because those become the lead item in every audit, cyber-insurance, and due-diligence conversation whether or not they're the hardest part of the migration.

  • The .NET runtime or framework version of each application. Where to look: each project's .csproj (<TargetFramework> or, on older projects, <TargetFrameworkVersion>), the web.config <httpRuntime targetFramework>, and the CLR version set on the IIS application pool. A .NET Framework 4.8 app and a .NET 8 app are entirely different modernization problems; a mixed estate hides both.
  • The SQL Server version and edition of each instance. Where to look: SELECT @@VERSION, the instance properties in SQL Server Management Studio, and SQL Server Configuration Manager. SQL Server 2012 and 2014 are past end of support, and 2016's extended-support deadline is July 14, 2026; edition (Express, Standard, Enterprise) decides which features you can even use.
  • The compatibility level of each database. Where to look: sys.databases.compatibility_level, or the database's properties. A modern instance running a database at an old compatibility level behaves like the older version in ways that surface during migration testing, not planning.
  • The operating system versions hosting the apps and SQL Server. Where to look: the servers themselves (winver), your CMDB if one exists. An out-of-support Windows Server is its own finding and frequently gates the .NET and SQL upgrades behind it.
  • Third-party runtimes and frameworks with their own lifecycles. Where to look: installed programs, app dependencies, and the things that aren't .NET at all -- a bundled Java runtime, a reporting engine, an IIS module. These reach end of life on their own schedule and block the move independently.

Unknown = finding. If no one can state the version of a production system without logging in to check, that gap is the first finding. Systems whose versions are unknown are usually the ones nobody is allowed to touch.

2 · Architectural coupling -- how tightly it's wired together

How the pieces depend on each other. This maps to the Architectural Coupling dimension. Coupling is what turns "modernize one app" into "modernize four apps and a database," and it's the part a version number tells you nothing about.

  • The application types in the estate. Where to look: the solution and project structure. .aspx/.ascx files mean Web Forms; controllers plus Razor views mean MVC; ApiController/ControllerBase mean Web API; .svc files and a system.serviceModel section mean WCF (the older Microsoft technology for connecting applications to each other); System.Windows.Forms means WinForms; XAML and PresentationFramework mean WPF; a service host or a Main with no UI means a Windows Service or console/batch job. This matters because Web Forms and WCF server-side hosting don't exist in modern .NET -- Web Forms is a rewrite, and WCF moves to the Microsoft-supported CoreWCF port or gets rebuilt as REST or gRPC -- while MVC and Web API port far more cleanly. The application-type guide covers what breaks by application type; the migration risk guide covers what breaks by version.
  • The deployable units and how they're split. Where to look: the solution file, the build outputs, and what actually ships together. A "monolith" that deploys as a single unit constrains how incrementally you can modernize anything inside it.
  • Databases shared across applications. Where to look: connection strings across every app, and which applications write to which databases. Two apps writing the same tables means you cannot modernize one without accounting for the other.
  • Business logic living in T-SQL. Where to look: sys.sql_modules and sys.procedures for stored procedures (business rules written inside the database itself, not in the application code), plus triggers and views that contain logic rather than just shape. If the rules live in stored procedures, a code-only modernization quietly leaves them behind. SQL Server depth gets its own treatment in the SQL Server modernization risk guide.
  • The integration topology between systems. Where to look: WCF/SOAP endpoints, message queues (MSMQ, RabbitMQ, Azure Service Bus), file and SFTP feeds, and linked servers (sys.servers). Integrations decide the order you're allowed to cut over in.

Unknown = finding. An integration nobody can draw on a whiteboard is a coupling you'll discover during cutover instead of during planning. The ones that aren't documented are rarely the ones that don't matter.

3 · Dependency risk -- what it relies on that you don't control

The external and third-party things the system needs to run. This maps to the Dependency Risk dimension. These are the items that don't show up when you only read the application code, and they're where "we'll just port it" estimates tend to come apart.

  • Third-party libraries and packages. Where to look: packages.config on older projects or <PackageReference> entries in the .csproj, plus the bin folder for DLLs that were dropped in by hand. An abandoned package, or one with no modern-.NET version, is a blocker, not a line item.
  • COM and native interop. Where to look: <COMReference> entries in projects, regsvr32 registrations, interop assemblies, and P/Invoke declarations. COM (an older Windows way for separate programs to call each other) dependencies often have no modern equivalent and are registered on the server through an undocumented manual step somebody did once.
  • Vendor SDKs and licensed components. Where to look: references to commercial control suites and reporting engines (Telerik, DevExpress, Crystal Reports), and the license files that go with them. Licensing terms and modern-.NET support vary widely; some are dead ends.
  • SQL Agent jobs and other scheduled work. Where to look: SQL Server Agent → Jobs in SSMS, or msdb.dbo.sysjobs; also Windows Task Scheduler. Batch work that runs outside the application is invisible to a code-only review and is frequently load-bearing.
  • Reporting dependencies. Where to look: SSRS (the Report Server and its ReportServer database), and any Excel or Power BI workbook reading production tables directly. Reports that read the schema directly break the moment the schema moves.
  • External feeds and APIs. Where to look: SFTP and file drops, vendor API clients, and hard-coded endpoints or IP addresses buried in config. The external systems that supply or consume your data have to be part of the plan, and they rarely know they are.

Unknown = finding. Every dependency you can't name is one that will name itself eventually, usually on a cutover weekend. The job here is to make that introduction happen on a Tuesday in planning instead.

4 · Change safety -- whether you can change it without breaking it

Whether the team can change the system safely as modernization proceeds. This maps to the Change Safety dimension. It's the quietest of the four and the one that most often decides whether a modernization is a project or an ordeal.

  • Automated test coverage. Where to look: test projects (MSTest, xUnit, NUnit), whether anything runs them on a schedule, and any coverage report at all. Old systems often have little to none, and rebuilding tests is work to be scoped, not overhead to be assumed away.
  • The deployment process. Where to look: CI/CD configuration (azure-pipelines.yml, a GitHub Actions workflow, Octopus) versus a person with a checklist and an RDP session. A manual deployment is a manual rollback.
  • The rollback path. Where to look: ask the question directly -- "if this release fails, what exactly happens next?" Look for a documented rollback, reversible database migrations, and backups that have actually been restored. A backup that has never been restored is a theory with a timestamp.
  • Source control and what's really in production. Where to look: the repository (or repositories), and whether production matches a known commit. Code running in production with no matching source is one of the more expensive findings to discover late.
  • Environments and parity. Where to look: dev, test, and staging versus production, and whether anyone tests against production-like data and volume. "Works in the demo" is not "works in production"; production always contains the exceptions.
  • Observability. Where to look: logging, monitoring, alerting, and who gets paged when something breaks. You cannot safely change what you cannot see.
  • Knowledge concentration. Where to look: who is the only person who understands each system. Where the answer is one name, that's a finding -- lost knowledge turns a modernization into a reverse-engineering project before it can be an engineering one.

Unknown = finding. If the honest answer to "can we change this safely" is "we avoid changing it," then the avoidance is the finding. Systems that are too risky to touch don't get safer by being left alone.

What a triage is, and what comes next

A triage is not a Modernization Readiness Score, and it isn't a fix. It's the inventory that makes the next conversation honest. The four groups above are the same four dimensions a full assessment scores, but scoring without the inventory is just a confident guess. Do the inventory first.

Reading this as a leader

You do not need every line filled in. You need to know how many are blank. The count of "we don't know" answers is the risk signal -- it's a direct measure of how much of your modernization plan would rest on assumptions nobody has checked. A system with ten blanks is not ready to be estimated. It's ready to be looked at.

Reading this as an engineer

The artifacts named above are where the truth lives. The .csproj knows the target framework even when the wiki doesn't. sys.servers knows about the linked server the architecture diagram forgot. Where the artifact and the institutional memory disagree, trust the artifact, write down the disagreement, and treat that disagreement as a line item.

When the blanks are mapped, the work has a starting order: the unknowns get investigated first, because they carry the assumptions; the out-of-support platforms get a defensible plan, because they drive the external pressure; and the whole picture rolls up into the four Modernization Readiness dimensions so the conversation can move from "should we modernize" to "in what order, and what has to be true first."

Turn the blanks into a map of where to look first.

Modernization Shield turns the inventory into evidence: unsupported platforms, hidden dependencies, database logic, migration blockers, weak test coverage, and unsafe deployment paths. Unknowns remain visible instead of being treated as low risk.

The SocialGoal sample Modernization Risk Report shows the finished version of this triage: scored, evidenced, and put in order.

About this page

Last updated: .

This checklist reflects patterns observed across the legacy .NET and SQL Server systems we assess. The artifacts and locations are the ones that hold the truth in real Microsoft-stack environments; where your environment differs, the questions still apply. If a "where to look" on this page is wrong for your setup, we'd rather hear about it than ship something inaccurate. Email info@evincia.co.

Companion pages: the methodology for how the four dimensions are scored, the SQL Server modernization risk guide for the database half, the .NET Framework migration risk guide for what breaks by version, and Microsoft platform end-of-support dates for the lifecycle calendar.