Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #
- # Samba, Auto-Backup Script
- # Useage: Auto-Backup.ps1 -Source "\\SourceServer" -Destination D:\Backups -RetentionPolicy 5 -Incremental $true
- # Switches;
- # -Source, Specify the source SMB server where all accessible shares will be backed up.
- # -Destination, Specify the path to store backups. A folder Named "Auto-Backup" will be created here.
- # -RetentionPolicy, Specify a number of days to keep backups for. The default is 3.
- # -Incremental, When $true - only changed and new files will be backed up. A full back will be taken every three days.
- # -SingleBackupPerDay, when $false - the script will be allowed to run multiple times in one day.
- #
- # Default script parameters.
- $Incremental = $true
- $RetentionPolicy = 3
- $SingleBackupPerDay = $true
- # Set script parameters.
- Param(
- [string]$Source,
- [string]$Destination,
- [int]$RetentionPolicy,
- [switch]$Incremental,
- [switch]$SingleBackupPerDay
- )
- # Set global variables
- $ScriptStart = Get-Date
- # Error Count, Counted throughout the script for a clean exit
- $Errors = 0
- if (!(Test-Path -Path $Destination)) {
- try {
- New-Item -ItemType Directory -Path $Destination"\Auto-Backup"
- }
- catch {
- scriptLog("Unable to create / access backup destination")
- $Errors++
- Exit 1
- }
- }
- # Notify if the source or destination has not been configured
- if (!($Source) -or !($Destination)) {
- scriptLog("You must specify a source and destination before this script can continue.")
- $Errors++
- Exit 1
- }
- # Test if a backup has already been taken today, stop if it has
- if (Test-Path -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))) -and $SingleBackupPerDay = $true) {
- scriptLog("A backup has already been taken today. The script will now terminate.")
- $Errors++
- Exit 1
- }
- # Get a list of remote shares
- $RemoteShares = (net view \\localhost) | % { if($_.IndexOf(' Disk ') -gt 0){ $_.Split(' ')[0] } }
- # If there are no shares, log and stop.
- if ($RemoteShares.Count -eq 0) {
- scriptLog("Found no shares on the server.")
- $Errors++
- Exit 1
- }
- # Otherwise, we've found shares - Log and continue.
- scriptLog("Found " + ($RemoteShares.Count) + " SMB Shares; " + ($RemoteShares -join ','))
- if (DoFullBackup) {
- # Full backup routine
- scriptLog("A full backup will be taken at this time")
- if (!(Test-Path -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))))) {
- New-Item -ItemType Directory -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd")))
- New-Item -ItemType File -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt")
- Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value ("Backup Started: " + $ScriptStart)
- Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value "Backup Type: Full"
- New-Item -ItemType File -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup.type")
- Set-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup.type") -Value "Full"
- }
- foreach ($Share in $RemoteShares) {
- if (!(Test-Path -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\"+$Share))) {
- New-Item -ItemType Directory -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\"+$Share)
- }
- scriptLog(("Backing up directory: "+$Share))
- robocopy ($Source+"\"+$Share) ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\"+$Share) /E | Out-File ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\"+$Share+"-RoboCopy.log")
- if ($LASTEXITCODE -eq 0 -or $LASTEXITCODE -eq 1) { Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value ("Backup of shared folder completed. Folder name: " + $Share) }
- else {
- $Errors++
- Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value ("There was an error during the robocopy of the shared folder. Examine the Robocopy log. Shared Folder: " + $Share + $LASTEXITCODE)
- scriptLog(("There was an error during the robocopy of the shared folder. Examine the Robocopy log. Shared Folder: " + $Share + $LASTEXITCODE))
- }
- }
- scriptLog("Full Backup has finished")
- Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value ("Backup Ended: " + (Get-Date))
- Set-Content -Path $Destination"\Auto-Backup\Integ.bk" -Value (Get-Date)
- }
- else {
- # Incremental routine
- $FullBackupLocation = LastFullBackup
- # Stop the backup if a full backup cannot be found.
- if ($FullBackupLocation -eq $null) {
- scriptLog("A full backup could not be found.")
- $Errors++
- Exit 1
- }
- # Create Backup Location
- if (!(Test-Path -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))))) {
- New-Item -ItemType Directory -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd")))
- New-Item -ItemType File -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt")
- Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value ("Backup Started: " + $ScriptStart)
- Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value "Backup Type: Incremental"
- New-Item -ItemType File -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup.type")
- Set-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup.type") -Value "Incremental"
- }
- scriptLog("An incremental backup will be taken at this time")
- scriptLog(("Last Full Backup Location: " + $FullBackupLocation))
- foreach ($Share in $RemoteShares) {
- foreach ($Item in Get-ChildItem ($Source+"\"+$Share) -Recurse) {
- $FullItem = ($FullBackupLocation+"\"+($Item.FullName).Remove(0,($Source).Length))
- if (!(Test-Path -Path $FullItem) -or $Item.LastWriteTime -gt (Get-Item -Path $FullItem).LastWriteTime -or $Item.Length -ne (Get-Item -Path $FullItem).Length) {
- try {
- New-Item -ItemType File -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\"+($Item.FullName).Remove(0,($Source).Length)) -Force
- Copy-Item -Path $Item.FullName -Destination ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\"+($Item.FullName).Remove(0,($Source).Length))
- scriptLog(("[Copied] " + $Item.FullName + " (" + ($Destination+"\Auto-Backup"+(($ScriptStart).ToString("yyyyMMdd"))+"\"+($Item.FullName).Remove(0,($Source).Length)) + ")"))
- }
- catch {
- $Errors++
- scriptLog(("[Failed] " + $Item.FullName))
- }
- }
- }
- }
- scriptLog("Incremental Backup has finished")
- Add-Content -Path ($Destination+"\Auto-Backup\"+(($ScriptStart).ToString("yyyyMMdd"))+"\Backup Configuration.txt") -Value ("Backup Ended: " + (Get-Date))
- }
- # Retention Policy Routine
- foreach($Backup in Get-ChildItem -Path ($Destination+"\Auto-Backup\")) {
- if ($Backup.GetType().ToString() -eq "System.IO.DirectoryInfo") {
- try {
- $CreateDate = ([datetime]::ParseExact($Backup.Name,"yyyyMMdd",$null))
- }
- catch {
- $CreateDate = $Backup.CreationTime
- }
- if ($CreateDate -lt $ScriptStart.AddDays(-$RetentionPolicy)) {
- scriptLog("The backup for " + $CreateDate + " has expired due to the retention policy. This will be deleted.")
- Remove-Item $Backup.FullName -Force -Recurse
- }
- }
- }
- # Script Exit
- if ($Errors -eq 0) { scriptLog("Backup finished with no errors.") }
- if ($Errors -gt 0) { scriptLog("Errors were found while running the backup.") }
- Write-Host $Errors
- Exit $Errors
- # Global Script for logging.
- function scriptLog([string]$LogMessage) {
- if (!(Test-Path $Destination"\Auto-Backup\Auto-Backup.log")) { New-Item -ItemType File -Path $Destination"\Auto-Backup\Auto-Backup.log" }
- $Today = Get-Date
- Add-Content -Path $Destination"\Auto-Backup\Auto-Backup.log" -Value ([String]$Today+": "+$LogMessage)
- Write-Host $Today": " $LogMessage
- }
- # Should we run a full, or file change backup?
- function DoFullBackup {
- if (!(Test-Path -Path $Destination"\Auto-Backup\Integ.bk")) {
- New-Item -Path $Destination"\Auto-Backup\Integ.bk"
- return $true
- }
- if ($Incremental -eq $false) { return $true }
- $AllowedDate = (Get-Date).AddDays(-$RetentionPolicy)
- $IntegContent = Get-Content -Path $Destination"\Auto-Backup\Integ.bk"
- if (([datetime]$IntegContent) -lt $AllowedDate) {
- return $true
- }
- return $false
- }
- # Function to find last full backup
- function LastFullBackup {
- $Latest = $null
- $TimeCheck = (Get-Date).AddDays(-360)
- foreach($Backup in Get-ChildItem -Path ($Destination+"\Auto-Backup\")) {
- if ($Backup.GetType().ToString() -eq "System.IO.DirectoryInfo") {
- if (Test-Path -Path ($Backup.FullName+"\Backup.type")) {
- if ((Get-Content -Path ($Backup.FullName+"\Backup.type")) -eq "Full") {
- if (([datetime]::ParseExact($Backup.Name,"yyyyMMdd",$null)) -gt $TimeCheck) {
- $TimeCheck = ([datetime]::ParseExact($Backup.Name,"yyyyMMdd",$null))
- $Latest = $Backup.FullName
- }
- }
- }
- }
- }
- return $Latest
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement