[AF 6] Migrating the File Server: ACLs, SIDs, and Sequencing

File server migrations fail on permissions and sequencing, not on copying bytes. What actually survives the move, which SIDs go dead on arrival, and the order of operations that makes cutover boring.


Copying files is the easy half of a file server migration and the only half most plans budget for. The hard half is permissions, and the reason it is hard is arithmetic: every ACL you copy is a list of SIDs, and whether each SID means anything on the other side depends on identity decisions made years before anyone approved this project. Get the sequencing right and cutover is a quiet weekend. Get it wrong and Monday is a permissions archaeology dig.

What survives the move and what does not

The data model survives almost intact. NTFS DACLs, timestamps, and attributes copy faithfully with the right tooling, and the share enforces them exactly as the server did. What does not survive deserves a written inventory before anyone commits a date. Audit ACLs, the SACLs behind your file-access auditing, cannot be written to Azure Files at all; if file-level audit trails are a compliance requirement, the destination posture must include a server in the path, which usually means the File Sync cache from the last two articles. Alternate data streams, hard links, and reparse points do not exist on the other side; they are rare in departmental data and endemic in application data, which is one of several reasons application shares migrate last or not at all. Access-based enumeration stops working on direct mounts, so users will see the names of folders they cannot open, and that is a communications item, not a configuration item. Quota and file-screening behavior from FSRM has no equivalent; the share’s provisioned size is the only quota. None of these is disqualifying. All of them are better discovered in the design review than in the pilot’s first support ticket.

The SID question decides the identity path

Here is the mechanism that decides whether your copied permissions work: when a user authenticates to the share, their Kerberos ticket carries SIDs, and the share compares those SIDs against the ACL entries you copied over. An ACE matches only if the same SID shows up in a ticket. On the hybrid path, users synced from AD carry their on-prem SIDs, so ACLs referencing synced users and groups keep working untouched; that is the migration-friendly property that makes hybrid identity sync so valuable during a transition, and it is why I check the sync scope of every security group named in the ACL tree before quoting a timeline. Everything else goes dead on arrival: SIDs of unsynced groups, of accounts from a domain you decommissioned in 2019, of local server groups, and of any principal that exists only in Entra ID under the old AD-joined model. Dead ACEs do not error; they are stored and silently never enforced, which is the worst possible failure mode because the share appears to work while enforcing a different policy than the one on paper.

The Entra-only GA changed the destination but not the history: cloud-only groups can now hold permissions, and a cloud-native org can build a clean ACL tree from scratch, but nothing translates your old AD SIDs into Entra SIDs retroactively. So the honest fork is this. Estates keeping hybrid sync migrate ACLs as-is and enjoy continuity. Estates going cloud-only treat the migration as a permissions rebuild: copy the data, then re-ACL deliberately onto cloud groups, which is more work and, in every environment I have done it, overdue hygiene disguised as a chore, because the old tree was carrying fifteen years of exceptions nobody could explain.

A dead ACE does not fail. It sits in the ACL looking authoritative and enforcing nothing, which is why migrated permissions must be validated by testing access, never by reading the security tab.

Tools, chosen by estate

Three tools cover every migration I run, and the selection logic is short. RoboCopy remains the precision instrument: full-fidelity copies including DACLs and owners, restartable, resumable, scriptable, and honest in its logs; it is my default for anything a single operator can supervise, and its exact flags, including the reason /COPYALL is a trap here, live in the build sheet. Azure Storage Mover is Microsoft’s managed service for the same job at fleet scale, an agent appliance near the source, migrations defined and monitored in Azure, full fidelity for SMB sources; it earns its place when there are forty servers rather than four shares, or when the operator running RoboCopy would be you, forever. Azure File Sync is the third path and the gentlest: stand up the sync topology from the previous articles, let it upload the namespace over days while users keep working, and the “migration” reduces to a DFS-N cutover at the end; for estates keeping cached servers anyway, migration and destination are literally the same build. Offline transfer via Data Box exists for the multi-terabyte-over-DSL corner case, seeded first and reconciled online after. What I do not use for file server migration is AzCopy, whose fidelity for this job is partial, or anything that copies data without permissions, because a migration that drops ACLs is a data leak with a project plan.

The sequence that makes cutover boring

Every successful run follows the same skeleton. Inventory first: shares, sizes, the feature exceptions above, and the ACL principal list with each principal’s sync status, because that list is the project’s real risk register. Destination second: accounts, shares, identity source, and network path built and validated before a byte moves, which this series has already done for you in order. Root ACLs third, set on the empty share before bulk data lands, because ACL propagation across millions of copied files is slow and disruptive when done in the wrong order. Then the copy pattern that removes all drama from the deadline: a full initial pass while users keep working, incremental passes on the following nights shrinking the delta, a write freeze measured in hours, one final incremental against the frozen source, and cutover. Cutover itself should be the smallest step of the project: repoint the DFS-N folder target if you followed the namespace rule, or swap the drive mappings if you did not, then validate as users, not as admins, with a test account per major permission group proving both the allows and the denies. Keep the source server intact but read-only for a defined parole period, thirty days in my practice, because the question you cannot answer from backups in month two is “what exactly did the old ACL on this one folder say.”

Two build sheets follow. [AF 6.1] runs this sequence at enterprise scale with RoboCopy and Storage Mover against a DFS namespace. [AF 6.2] is the same story told for the small shop: one server, one weekend, and drive letters mapped the old-fashioned way, because most of the businesses actually asking the file server question have never had a DFS namespace and do not need one to leave their server behind.


Azure Files
‹ Previous: [AF 5.1] Build Sheet: File Sync with DFS-N, End to End
Next: [AF 6.1] Build Sheet: The Migration Run