Synchronize file date time on multiple IIS servers and fix ETag discrepency





0/5 (0 vote)
Files with different date time get different ETag generated by IIS. As a result, on a web server farm, each webserver sends different ETag for the same file as the files are copied to those servers at different date time. Here's a script that can set date time of same file across multiple servers to
When you deploy the same website on multiple webservers, you end up having each file getting different last modified date. As a result, each IIS produces different ETag for the static files. If user is hitting different servers for the same file (due to load balancing), each IIS is responding with different ETag and thus browser downloading the same file over and over again. if you have 3 servers, same user has most likely downloaded the same file thrice. This gives poor page load performance.
Moreover, if you want to mirror two or more locations using one location as a base, not only you need to copy the same files but you need to set the same Create Date and Last Modified Date on the files. Otherwise they aren’t true mirror. There are various use cases where you need a complete mirror not only at file content level but also at file date time level.
Here’s a powershell script that will do the job for you:
# Path of the base folder. File date times in this folder is used as the base. $SourceFolder = ".\Folder1" # Put all the other locations here. These locations must have the same folder structure as the base $DestFolders = @('.\Folder2', '.\Folder3') function sync($sourcePath, $destinationPath) { $sourceFiles = [System.IO.Directory]::GetFiles($sourcePath); foreach ($sourceFileName in $sourceFiles) { $sourceFile = Get-Item $sourceFileName $destFilePath = Join-Path -Path $destinationPath -ChildPath $sourceFile.Name $destFile = Get-Item $destFilePath if ($destFile.Length -eq $sourceFile.Length) { $destFile.LastWriteTime = $sourceFile.LastWriteTime; $destFile.CreationTime = $sourceFile.CreationTime; Write-Host ("SYNCED: " + $sourceFileName + " -> " + $destinationPath) } else { Write-Host ("SIZE DOES NOT MATCH: " + $sourceFileName + " -> " + $destinationPath) } } $childFolders = [System.IO.Directory]::GetDirectories($sourcePath); foreach ($childFolderName in $childFolders) { $childFolder = Get-Item $childFolderName $destFolderPath = Join-Path -Path $destinationPath -ChildPath $childFolder.Name $destFolder = Get-Item $destFolderPath sync $childFolder.FullName $destFolder.FullName } } $Source = Get-Item $SourceFolder foreach ($destFolderName in $DestFolders) { $destFolder = Get-Item $destFolderName sync $Source.FullName $destFolder.FullName }