I needed a simple PowerShell script that would keep a bunch of folders in sync. So I wrote this reusable script.
Parameters are defined in the script itself, and it takes source and destination information from an input CSV file.
# =========================================================================================
# Reusable Robocopy script that takes folder source and destination pairs from a CSV file
# Adjust CSV file, flags, options, log file and folder exclusions to suit your requirements
# Encrypted files (EFS) are excluded; include with /EFSRAW but remove the /MT flag
# Script checks if the import CSV file exists, and also checks source/dest folder pairs
# Harish Karayadath, 05 February 2018
# =========================================================================================
$logfile = "C:\Scripts\Robocopy\CopyLog_$(Get-Date -Format yyyyMMdd-HHmm).log"
$flags = @{R=1;W=1;MT=64;XA="E";'LOG+'=$logfile}
# "What If" mode. Set the below to "Yes" if you would like Robocopy to list only (no copy/delete)
$whatifmode = "No"
if($whatifmode -eq "Yes") {
$options = @("/MIR","/B","/COPYALL","/NP","/NFL","/NDL","/NC","/NS","/L")
}
else {
$options = @("/MIR","/B","/COPYALL","/NP","/NFL","/NDL","/NC","/NS")
}
# Folder exclusions. Special characters must be escaped properly.
$exclude = @("DfsrPrivate","`$RECYCLE.BIN","System Volume Information")
# Specify import file. CSV must be in the below format.
# Name,Enabled,Source,Destination
# Folder1,TRUE,C:\Source1,C:\Dest1
# Folder2,FALSE,C:\Source2,C:\Dest2
$importfile = "C:\Scripts\Robocopy\folderlist.csv"
if(Test-Path $importfile) {
$folders = Import-Csv $importfile
}
else {
Add-Content $logfile -Value "======================================================="
Add-Content $logfile -Value "The import CSV file does not exist. Script terminating."
Add-Content $logfile -Value "Import CSV: $($importfile)"
Add-Content $logfile -Value "======================================================="
exit
}
foreach($folder in $folders) {
if ($folder.Enabled -eq "TRUE") {
if((Test-Path $folder.Source) -and (Test-Path $folder.Destination)) {
# Write-Host "Source and Destination folders exist. Invoking robocopy."
Add-Content $logfile -Value "========================================================"
Add-Content $logfile -Value "Source and Destination folders exist. Invoking robocopy."
Add-Content $logfile -Value "Source: $($folder.Source)"
Add-Content $logfile -Value "Destination: $($folder.Destination)"
Add-Content $logfile -Value "========================================================"
& robocopy.exe $folder.Source $folder.Destination @flags @options /XD @exclude
}
else {
Add-Content $logfile -Value "=============================================================="
Add-Content $logfile -Value "One or both folders do not exist. Skipping the copy operation."
Add-Content $logfile -Value "Source: $($folder.Source)"
Add-Content $logfile -Value "Destination: $($folder.Destination)"
Add-Content $logfile -Value "=============================================================="
}
}
else {
Add-Content $logfile -Value "=============================================================="
Add-Content $logfile -Value "Skipping. Copy of the below folders disabled in the input file"
Add-Content $logfile -Value "Source: $($folder.Source)"
Add-Content $logfile -Value "Destination: $($folder.Destination)"
Add-Content $logfile -Value "=============================================================="
}
}
Add-Content $logfile -Value "================================================"
Add-Content $logfile -Value "Script execution finished at $(Get-Date -Format "dd/MM/yyyy HH:mm:ss")"
Add-Content $logfile -Value "================================================"
It expects an input CSV file called folderlist.csv
in this format:
Name,Enabled,Source,Destination
DeptData1,TRUE,D:\Source1,\\remote1\e$\Dest1
DeptData2,TRUE,\\remote2\f$\Source2,H:\Dest2
DeptData3,TRUE,\\remote3\g$\Source3,G:\Dest3
Set column 2 to FALSE
if you want the script to skip that row.