Business Context
The application was delivered through Azure Virtual Desktop and used a proven Windows storage model. Shared business files were held on a file share hosted by an Azure virtual machine, user settings were stored in isolated storage within each person’s Windows profile, and application code accessed local and UNC paths directly through System.IO.
That model became a constraint when Microsoft Entra External ID enabled users who did not have equivalent Windows domain accounts or profiles. The work therefore had two goals: give those users appropriately authorised access to shared files in Azure Files, and move their settings into application-owned Blob Storage without requiring a single high-risk cutover.
Goal
Support Azure storage without binding business code to it
The goal was to support users authenticated through Entra External ID while moving the application’s storage responsibilities to Azure-managed services.
Shared files needed to move from the Azure VM file share to Azure Files. Per-user settings needed to move from isolated storage to Azure Blob Storage. Access to the Azure file share needed to use the authenticated user and Azure RBAC applied through Entra ID groups.
Method
Introduce switchable file access and a separate settings library
Direct file access was refactored behind new Storage.IO static facades. Those facades supported two filesystem implementations:
- A backwards-compatible
System.IOimplementation for supported local and UNC paths. - An Azure Files implementation selected by a new
azure://URI scheme.
A feature switch initially kept the refactored application on the System.IO implementation. This allowed local and UNC file behaviour behind the new facades to be tested thoroughly before the switch enabled the Azure Files implementation. That implementation authenticated as the user, with Azure RBAC file-share access assigned through Entra ID groups.
The like-for-like façade gave developers a familiar, drop-in route from existing file operations to Azure Files. Calling classes did not each need to learn Azure service APIs or implement authentication, which made the transition easier to adopt consistently across the application.
User settings followed a separate path. The existing isolated-storage access code was refactored into a dedicated settings library, which continued to read existing settings and migrated them transparently in the background to application-owned Azure Blob Storage. No hard cut-off or all-users-at-once migration was required, and the settings library did not use the same authentication mechanism as Azure Files.
Technical Challenges
Storage behaviour included identity and application assumptions
Replacing a file path was not enough. Existing code expected System.IO semantics, user settings were tied to isolated storage, and shared-file access inherited identity from the Windows environment. Each assumption had to be made explicit before it could be moved safely.
External users changed the authorisation model. Because they did not require Windows domain accounts, access could no longer rely on the identity of the desktop session or process. The storage integration needed to acquire and use the authenticated user context, while RBAC and Entra ID groups became part of the end-to-end access path.
The two data types had different ownership, access and authentication requirements. Shared files remained user-authorised resources accessed through the switchable filesystem facades, while user settings became application-owned data managed through their own library and stored in Blob Storage.
Outcomes
Testable file substitution and application-owned settings
The application gained a controlled route from local and UNC paths to Azure Files without requiring each user to have a Windows domain identity. The feature switch allowed the refactored System.IO behaviour to be verified before azure:// locations activated the user-authenticated Azure Files implementation.
The dedicated settings library migrated existing isolated-storage settings transparently in the background to application-owned Blob Storage. File-share access could be governed through Entra ID groups and Azure RBAC, while settings moved away from Windows profiles without a single migration cut-off.
Business benefits
Enable external identity and reduce infrastructure coupling
- Support for Entra External ID users without equivalent Windows accounts.
- Existing local and UNC behaviour tested behind the new
Storage.IOfacades before cutover. - A like-for-like, drop-in abstraction that reduced the Azure service and authentication knowledge required in calling classes.
- A feature switch providing controlled, reversible selection of the Azure Files implementation.
- Shared files moved away from an Azure VM-hosted share to Azure Files.
- User settings migrated transparently in the background from isolated storage to application-owned Blob Storage.
- File access governed through Entra ID groups and Azure RBAC.
- File access and user-settings ownership treated as separate architectural concerns.
Architecture value
Architecture reduced delivery and adoption risk
Storage affected application code, user identity, data ownership and operational migration. Architecture separated those concerns behind stable boundaries, allowing developers to use a familiar contract, shared files to move through a controlled feature switch, and user settings to migrate transparently in the background.
Discuss your project
Modernising application storage?
If direct filesystem dependencies, Windows identity or virtual-machine file shares are constraining your application, contact me to discuss a controlled route to identity-aware Azure storage.
Contact me about a modernisation project