Migrate a File Server While Retaining Share Permissions

In this guide, we’re migrating from virt-file-01 (Windows Server 2016) to virt-file-02 (Windows Server 2019). The source server has an RDM LUN attached, which we’ll be moving across once everything is prepped and verified on the destination side.

Discovery and Assessment Phase

The Discovery and Assessment phase is the foundation of any successful file server migration.Run a TreeSize or SpaceObserver report to get a true picture of what you’re dealing with: consumed capacity, file age, largest directories, and owner attribution.

https://www.jam-software.com/treesize/editions.shtml

A few sample power shell commands are here.

JavaScript
1. Get unique owners of a folder (up to 2 levels deep)

 Get-ChildItem -Path "Source Folder Path" -Recurse -Depth 2 -ErrorAction SilentlyContinue | ForEach-Object { try { (Get-Acl -LiteralPath $_.FullName).Owner } catch { } } | Sort-Object | Get-Unique

-or-
 Get-ChildItem -Path "Source Folder Path" -Recurse -Depth 2 -ErrorAction SilentlyContinue | ForEach-Object { (Get-Acl $_.FullName).Owner } | Sort-Object | Get-Unique

 Use: Find out who owns or has created files in a folder. Helps identify POCs.

 2. Get last write and last access time (top 30 most recent)

 Get-ChildItem -Path "Source Folder Path" -Recurse -Depth 1 -ErrorAction SilentlyContinue | Select-Object Name, LastWriteTime, LastAccessTime, Directory | Sort-Object LastAccessTime -Descending | Select-Object -First 30

 Use: See when files were last modified and last opened. Helps identify if a folder is active or abandoned. Good for spotting ROT.

 3. Get permissions on a specific folder

 Get-Acl -Path "Source Folder Path" | Select-Object -ExpandProperty Access | Select-Object IdentityReference, FileSystemRights, AccessControlType | Format-Table -AutoSize

 Use: See exactly who has access to a folder and what levelRead, Modify, Full Control etc. Useful for the permissions report.

 4. Count files in a folder

 (Get-ChildItem -Path "Source Folder Path" -Recurse -ErrorAction SilentlyContinue).Count

 Use: Quick file count for any folder. Useful when TreeSize report is not available.

 5. Find files with special characters in the name

 Get-ChildItem -Path "Source Folder Path" -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.Name -match '[#%&\*:\<>\?/\\\|\[\]]' } | Select-Object FullName

 Use: Find files that have characters SharePoint does not allow — [ ] # % & * : < > ? / \ |. These need to be renamed before migration.

 6. Find files over a certain size

 Get-ChildItem -Path "Source Folder Path" -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.Length -gt 1GB } | Select-Object FullName, @{Name="SizeGB";Expression={[math]::Round($_.Length/1GB,2)}}

 Use: Find files larger than 1GB. SharePoint has a 250GB file size limit but large files can slow migration. Adjust 1GB to any size you want.

 7. Find duplicate folder names across top level

 Get-ChildItem -Path "Source Folder Path" -Recurse -Depth 2 -Directory -ErrorAction SilentlyContinue | Group-Object Name | Where-Object { $_.Count -gt 1 } | Select-Object Name, Count

 Use: Find folder names that appear more than once across the drive. Helps identify potential duplicate content.

 8. Export folder list to CSV

 Get-ChildItem -Path "Source Folder Path" -Depth 1 -ErrorAction SilentlyContinue | Select-Object Name, LastWriteTime, LastAccessTime | Export-Csv -Path "H:\FOLDERNAME_list.csv" -NoTypeInformation

 Use: Export a folder listing to a CSV file you can open in Excel. Replace H:\ with wherever you want to save it.

How to do the migration ?

Step 1: Export Share Permissions from virt-file-01

Method 1: Using PowerShell

$SourceShare = "YourShareName" # Replace with actual share name
$ShareInfo = Get-SmbShare -Name $SourceShare | Select-Object -Property Name, Path, Description
$SharePermissions = Get-SmbShareAccess -Name $SourceShare
$ShareInfo | Export-Clixml "C:\Temp\ShareInfo.xml"
$SharePermissions | Export-Clixml "C:\Temp\SharePermissions.xml"

Method 2: Using Registry Export

  1. Open Regedit and navigate to: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Shares
  2. Right-click the Shares key and select Export.
  3. Save the file as C:\Temp\Shares.reg.

Step 2: Backup NTFS Permissions

icacls D:\ /save C:\Temp\NTFSPermissions.txt /t /c

Step 3: Export DNS and CNAME Settings

Using Command Line

nslookup virt-file-01

To list and document CNAME records:

dnscmd /enumrecords domain.com fileserver

Backup dynamic DNS settings:

dnscmd /zoneexport domain.com C:\Temp\dnsbackup.txt

Using GUI

  1. Open DNS Manager (dnsmgmt.msc).
  2. Navigate to Forward Lookup Zones > YourDomain.com.
  3. Locate and document A/CNAME records for virt-file-01.
  4. Right-click on the zone, choose Export List, and save it.

Step 4: Do the cutover is is via robocopy if folders are less and that is usually quicker

Or you can remove the existing disk from sever and attached to new VM.

Step 4: Remove the RDM LUN from virt-file-01

  1. Ensure all sessions are disconnected.
  2. Offline the disk in Disk Management.
  3. Remove the RDM mapping from the VM configuration.

Step 5: Attach the RDM LUN to virt-file-02

  1. Attach the LUN to the new VM as an RDM.
  2. Bring the disk online and ensure the same drive letter is assigned.
  3. Verify data integrity.

Step 6: Import Share Permissions to virt-file-02

Method 1: Using PowerShell

$NewShare = "YourShareName" # Replace with actual share name
$ShareInfo = Import-Clixml "C:\Temp\ShareInfo.xml"
$SharePermissions = Import-Clixml "C:\Temp\SharePermissions.xml"

New-SmbShare -Name $NewShare -Path $ShareInfo.Path -FullAccess Everyone # Modify permissions as needed

foreach ($perm in $SharePermissions) {
    Grant-SmbShareAccess -Name $NewShare -AccountName $perm.AccountName -AccessRight $perm.AccessRight -Force
}

Method 2: Using Registry Import

  1. Copy C:\Temp\Shares.reg to virt-file-02.
  2. Double-click the file to import it into the registry.
  3. Restart the Server service: net stop lanmanserver && net start lanmanserver

Step 7: Restore NTFS Permissions

icacls D:\ /restore C:\Temp\NTFSPermissions.txt

Step 8: Reconfigure DNS and CNAME on virt-file-02

Using Command Line

dnscmd /recordadd ash.local virt-file-02 A <New-IP>
dnscmd /recordadd ash.local fileserver CNAME virt-file-02.domain.com

Force dynamic DNS update:

ipconfig /registerdns

Step 9: Using same old server name

if we wish to re-use the original server name we can power of virt-file-01 and run the below powershell on virt-file-02

Rename-Computer -NewName virt-file-01 -Restart

Using GUI to adjust IP’s if required

By following this process, all share settings, security permissions, and DNS configurations are migrated smoothly, allowing a seamless transition to the new server.

(Visited 216 times, 1 visits today)

By C A Thomas

Chinchu A. Thomas is an Infrastructure Analyst specializing in Microsoft Azure, the Microsoft 365 suite, AWS, and Windows infrastructure management products.

Leave a Reply