I have lots of live and disaster recovery servers, which should have the same files and folders. I searched on the web but could not find a Powershell script which has all of the functionality on the same script. So I have created one in the below function.
Please do not use it in Production without fully testing it!!!!!
This script replicates / synchronizes files and folders recursively from source location to destination location with the sync
switch.
If you use -Sync $True
then the script will remove all of the files and folders on destination location which do not exist in the source location.
Usage:
Sync-Files -SourceRoot "C:\Test" -DestinationRoot "\\Server\Test"
Sync-Files "C:\Test" "\\Server\Test"
Sync-Files -SourceRoot "C:\Test" -DestinationRoot "\\Server\Test" -Sync $true
Source:
<#
.Synopsis
synchronies files between two location
.DESCRIPTION
This function is synchronising all files from source location to destination location.
Script has ability to fully sync files by deleting the destination files if not exists in the source directory.
if -Sync is set $true script will delete files which exists in the destination directory only.
Please do not run this script before test in test/dev environment.
.EXAMPLE
Sync-Files C:\Test \\SERVER\Test
.EXAMPLE
Sync-Files -SourceRoot "C:\Source" -Destination "\\SERVER\DestinationDirectory\
.EXAMPLE
Sync-Files -SourceRoot "C:\Source" -Destination "\\SERVER\DestinationDirectory\ -Sync $True
#>
function Sync-Files
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
$SourceRoot,
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
$DestinationRoot,
[Parameter(
ValueFromPipelineByPropertyName=$true,
Position=3)]
[bool]$Sync
)
Begin
{
$SourceRootFiles = Get-ChildItem $SourceRoot -Recurse
$DestinationRootFiles = Get-ChildItem $DestinationRoot -Recurse
$CompareObjects = Compare-Object -ReferenceObject $SourceRootFiles -DifferenceObject $DestinationRootFiles -ErrorAction SilentlyContinue -IncludeEqual
}
Process
{
ForEach($CompareObject in $CompareObjects){
$FinalPath = Join-Path $DestinationRoot $CompareObject.InputObject.FullName.Substring($SourceRoot.length)
if($CompareObject.SideIndicator -eq "<="){
if($CompareObject.InputObject.PSIsContainer){
Copy-Item -Path $CompareObject.InputObject.FullName -Destination $FinalPath -Force
}
Elseif(!(Test-Path $FinalPath)){
Copy-Item -Path $CompareObject.InputObject.FullName -Destination $FinalPath -Force
}
}
if($CompareObject.SideIndicator -eq "=="){
if((Get-FileHash $CompareObject.InputObject.FullName).Hash -ne (Get-FileHash $FinalPath).Hash){
Copy-Item $CompareObject.InputObject.FullName $FinalPath -Force
}
}
if($CompareObject.SideIndicator -eq "=>"){
if($Sync -eq $true){
if(Test-Path $CompareObject.InputObject.FullName){
Remove-Item $CompareObject.InputObject.FullName -Force -Recurse -Verbose
}
}
}
}
}
End
{
}
}
Sync-Files -SourceRoot "C:\Test" -DestinationRoot "\\Server\Test" -Sync $true