diff --git a/properBackup.ps1 b/properBackup.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..ea7756cfc8840cd924d889acc18a80b5dee796e3 --- /dev/null +++ b/properBackup.ps1 @@ -0,0 +1,142 @@ +param ($systemFolder="C:\Users\Administrator\Desktop\filer", $backupLocation="C:\Users\Administrator\Desktop\backupfolder", [switch]$backup, [switch]$restore, $incrementalsToApply, $excludedFiles) + +$backupName = "Backup_$(Get-Date -Format "yyyy-MM-dd--HHmm")" +$backupFolderLocation = Join-Path -Path $backupLocation -ChildPath $backupName + +function doBackup { + $newestBackupzip = Get-ChildItem $backupLocation | Where-Object {$_.Name -match "Backup_"} | Where-Object {$_.Extension -match "zip"} | Select-Object -First 1 #Finner nyeste backup zip. + if ($newestBackupzip.name.length -ne 0) { #Dobbeltsjekker at det har blitt gjort en backup tidligere. + Write-Output "Found backup: "$newestBackupzip.Name + Expand-Archive $newestBackupzip (Join-Path -Path $newestBackupzip.Directory -ChildPath $newestBackupzip.BaseName) + $newestBackup = Get-ChildItem $backupLocation | Where-Object {$_.Name -match "Backup_"} | Where-Object {$_.Name -notmatch "-Increment"} | Select-Object -First 1 #Finner nyeste backup unzippet. + $innholdBackup = @(Get-ChildItem -Path $newestBackup -Recurse) + $innholdSystem = @(Get-ChildItem -Path $systemFolder -Recurse -Exclude $excludedFiles) + $differences = Compare-Object -ReferenceObject $innholdBackup -DifferenceObject $innholdSystem -Property Name, LastWriteTime -PassThru + if ($differences.count -gt 0) { + New-Item -Path $backupLocation -Name "tempnameChanges" -ItemType "directory" + $incBackupFolderLocation = Join-Path -Path $backupLocation -ChildPath "tempnameChanges" + New-Item -Path $incBackupFolderLocation -Name "inSystem" -ItemType "directory" + New-Item -Path $incBackupFolderLocation -Name "inBackup" -ItemType "directory" + $differences | Where-Object {$_.SideIndicator -eq "<="} | ForEach-Object { #Venstrepil betyr at filen bare er i backup. Fjerner først filer. Mapper kopieres over i incremental. + $relativePathFromSourceFolder = $_.Fullname.split($newestBackup.FullName)[1]; + Write-Output "wwww"$_.Fullname.split($newestBackup.FullName)[1] + $fullPathAtIncBackupLocation = Join-Path -Path $incBackupFolderLocation -ChildPath "inBackup" $relativePathFromSourceFolder + Copy-Item $_.FullName -Destination $fullPathAtIncBackupLocation -Force + Write-Output $_.FullName + Write-Output "was moved to" + Write-Output $fullPathAtIncBackupLocation + if ($_.Attributes -ne "Directory") { + Write-Output "Removing $_" + Remove-Item $_ + } + } + $differences | Where-Object {$_.SideIndicator -eq "<="} | Where-Object {$_.Attributes -eq "Directory"} | Select-Object { #Så fjernes mappene som er igjen. + Write-Output "Removing $_" + Remove-Item $_ -Recurse + } + $differences | Where-Object {$_.SideIndicator -eq "=>"} | ForEach-Object { #Høyrepil betyr at filen ikke finnes i backup med samme writetime. + $relativePathFromSourceFolder = $_.Fullname.split($systemFolder)[1]; + $fullPathAtBackupLocation = Join-Path -Path $backupLocation -ChildPath $newestBackup.Name $relativePathFromSourceFolder #Tar den relative pathen fra linja over å legger den inn i $backupLocation. Dermed opprettholdes mappestruktur. + if(Test-Path -Path $fullPathAtBackupLocation) { + Write-Output "Found identical file in backup. Comparing LastAccesTime..." + if($_.LastWriteTime -ge (Select-Object $fullPathAtBackupLocation).LastWriteTime) { + $fullPathAtIncBackupLocation = Join-Path -Path $incBackupFolderLocation -ChildPath "inBoth" $relativePathFromSourceFolder + Write-Output "Systemfile is more recent, replacing backupfile..." + Write-Output "Saving old backupfile to incremental backup..." + Copy-Item -Path $fullPathAtBackupLocation -Destination $fullPathAtIncBackupLocation -Force + Copy-Item $_ -Destination $fullPathAtBackupLocation -Force + } + else { + Write-Output "Error: Backupfile is more recent than systemfile. How do you want to proceed?" + getResponse + } + } + else { + $fullPathAtIncBackupLocation = Join-Path -Path $incBackupFolderLocation -ChildPath "inSystem" $relativePathFromSourceFolder + Write-Output "File not found in backup. Adding to backup..." + Copy-Item $_ -Destination $fullPathAtBackupLocation -Force + Copy-Item $_ -Destination $fullPathAtIncBackupLocation -Force + } + } + + $previousBackupName = $newestBackup.BaseName + Compress-Archive -Path (Join-Path -Path $newestBackup -ChildPath \*) -Force -DestinationPath $newestBackupzip + Remove-Item $newestBackup -Recurse + Rename-Item $newestBackupzip $backupName".zip" + + Rename-Item $incBackupFolderLocation ($previousBackupName+"-Increment") + } + else { + Write-Output "No differences found between system and backup. " + Compress-Archive -Path (Join-Path -Path $newestBackup -ChildPath \*) -Update -DestinationPath $newestBackupzip + Remove-Item $newestBackup -Recurse + } + } + else { + Write-Output "No backup found. Creating one..." + Copy-Item -Path $systemFolder -Destination $backupFolderLocation -Recurse -Exclude $excludedFiles + Compress-Archive -Path (Join-Path -Path $backupFolderLocation -ChildPath \*) -DestinationPath $backupFolderLocation + Remove-Item -Path $backupFolderLocation -Recurse -Force + } + Write-Output "Done!" +} + +function getResponse { + $response = 'Enter "A" to abort, "B" to replace systemfile with backupfile, "I" to ignore file or "S" to replace backupfile with systemfile.' + switch(Read-Host ($args[0]+$response)) { + "A"{Remove-Item $newestBackup -Recurse; Remove-item $incBackupFolderLocation; Exit} + "B"{Copy-Item $fullPathAtBackupLocation -Destination $_ -Force} + "I"{return} + "S"{Copy-Item -Path $fullPathAtBackupLocation -Destination $fullPathAtIncBackupLocation -Force; Copy-Item $_ -Destination $fullPathAtBackupLocation -Force} + Default {getResponse "Invalid entry."} + } +} + +function doRestore { + $newestBackupzip = Get-ChildItem $backupLocation | Where-Object {$_.Name -match "Backup_"} | Where-Object {$_.Extension -match "zip"} | Select-Object -First 1 #Finner nyeste backup zip. + Expand-Archive $newestBackupzip (Join-Path -Path $newestBackupzip.Directory -ChildPath $newestBackupzip.BaseName) + $newestBackup = Get-ChildItem $backupLocation | Where-Object {$_.Name -match "Backup_"} | Where-Object {$_.Name -notmatch "-Increment"} | Select-Object -First 1 + Write-Output ($incrementalsToApply -is [int]) + if ($incrementalsToApply -is [int]) { + $incrementalBackups = Get-ChildItem $backupLocation | Where-Object {$_.Name -match "-Increment"} | Select-Object -First $incrementalsToApply + $incrementalBackups | ForEach-Object { + $currentIncFolder = $_ + Get-ChildItem (Join-Path -Path $_ -ChildPath "inSystem") -Recurse | ForEach-Object { + $relativePathFromSourceFolder = $_.Fullname.split((Join-Path -Path $currentIncFolder -ChildPath "inSystem"))[1]; + $fullPathAtBackupLocation = Join-Path -Path $backupLocation -ChildPath $newestBackup.Name $relativePathFromSourceFolder + Copy-Item $_ -Destination $fullPathAtBackupLocation -Force + } + Get-ChildItem (Join-Path -Path $_ -ChildPath "inBackup") | ForEach-Object { + $relativePathFromSourceFolder = $_.Fullname.split((Join-Path -Path $currentIncFolder -ChildPath "inBackup"))[1]; + $fullPathAtBackupLocation = Join-Path -Path $backupLocation -ChildPath $newestBackup.Name $relativePathFromSourceFolder + Remove-item $fullPathAtBackupLocation -Recurse -Force + } + } + } + $innholdBackup = @(Get-ChildItem -Path $newestBackup -Recurse) + $innholdSystem = @(Get-ChildItem -Path $systemFolder -Recurse -Exclude $excludedFiles) + $differences = Compare-Object -ReferenceObject $innholdBackup -DifferenceObject $innholdSystem -Property Name -PassThru + if ($differences.count -gt 0) { + $differences | Where-Object {$_.SideIndicator -eq "<="} | ForEach-Object { #Venstrepil betyr at filen bare er i backup. Fjerner først filer. Mapper kopieres over i incremental. + $relativePathFromSourceFolder = $_.Fullname.split($newestBackup.FullName)[1]; + $fullPathAtSystemFolder = Join-Path -Path $systemFolder -ChildPath $relativePathFromSourceFolder + Copy-Item $_ -Destination $fullPathAtSystemFolder -Force + Write-Output $_.FullName + Write-Output "was moved to" + Write-Output $fullPathAtSystemFolder + } + $differences | Where-Object {$_.SideIndicator -eq "=>"} | ForEach-Object { #Fjerner filene i systemet som ikke finnes i backup. + Remove-Item $_ + } + } + else { + Write-Output "No differences found between system and backup. " + } + Remove-Item $newestBackup -Recurse +} +if ($backup) { + doBackup +} +elseif ($restore) { + doRestore +}