Incremental backups copies only the files that are modified since the last backup. Here is a PowerShell script to take incremental backups of your files. You run the script by passing three parameters - the source location, destination location and number of days (n). The script scans the files recursively in the source location and sub-folders and gets the list files that were modified in the last N number of days and copies them over to the destination folder. All the three parameters are mandatory.
The Get-ChildItem and where-object cmdlets are piped together to filter out files in the source location whose LastWriteTime attribute is in the last N days. The value of N is passed to the script as a parameter.
After obtaining the list of files to be copied, we use a Foreach loop to iterate through each of them and check if the directory structure exist in the destination. If the directory doesn't exists, we create that directory using New-Item cmdlet. Split-path cmdlet extracts just the parent directory path from the full file path.
Once the directory structure is put in place, the files are copied from source to the destination path. To construct the destination file path we replace the source path string with the destination path string. The replace function is case sensitive, which is the reason why we convert all file paths to lowercase first.
FileBackup.ps1
<#
.SYNOPSIS
Powershell script to backup files older than N days.
.DESCRIPTION
This PowerShell script is for taking incremental backups of files modified in the last N days from the specified source to destination folder.
.PARAMETER <source>
Source location where the files should be copied from.
.PARAMETER <destination>
Target location where the files should be copied to.
.PARAMETER <N days>
Only files modified in the last N days will be copied.
.NOTES
Version: 1.0
Author: Open Tech Guides
Creation Date: 11-Jan-2017
.LINK
www.opentechguides.com
.EXAMPLE
FileBackup c:\source-folder d:\dest-folder 30
#>
Param(
[Parameter(Mandatory=$true, position=0)][string]$source,
[Parameter(Mandatory=$true, position=1)][string]$destination,
[Parameter(Mandatory=$true, position=2)][Int]$days
)
$src = $source.toLower()
$dest = $destination.toLower()
Write-Host "File backup started."
Write-Host "Source: " $src
Write-Host "Destination: " $dest
Write-Host "Policy: Files older than" $days "days"
Write-Host "Scanning files ..."
$FilesToCopy = Get-ChildItem $src -force -recurse| where-object {($_.LastWriteTime -gt (Get-Date).AddDays(-$days)) -and ($_.PSIsContainer -ne $True)}
Write-Host "Scanning completed."
Write-Host "Copying files..."
$count = 0
Foreach($File in $FilesToCopy)
{
$src_file = $File.Fullname.tolower()
$dst_file = $File.Fullname.tolower().replace($src, $dest)
$dst_dir = Split-path -path $dst_file
if (!(Test-Path -path $dst_dir) ) {
Write-Host "`t Create directory " $dst_dir
New-Item -path $dst_dir -type Directory | out-null
}
Copy-Item $src_file -Destination $dst_file
$count++
}
Write-Host "File copy completed."
Write-Host $count "file(s) copied."
Write-Host "File backup completed."
Sample Output
PS C:\> .\FileBackup.ps1 C:\mysrcfolder C:\mydestfolder 30 File backup started. Source: c:\mysrcfolder Destination: c:\mydestfolder Policy: Files older than 30 days Scanning files ... Scanning completed. Copying files... Create directory c:\mydestfolder\opt Create directory c:\mydestfolder\sys File copy completed. 5 file(s) copied. File backup completed. PS C:\>
Note: This script does not copy empty directories in source location as it only checks the modification timestamps of files and not directories.