Ich hab mal wieder ein Script geschrieben welches mir meine Daten auf dem Notebook auf eine externe HDD sichert.
Ich war letztens 2 Wochen beruflich in China unterwegs und hatte etwas Zeit über mein Backup nachzudenken. Auch wenn ich alle Daten in der Cloud, also Skydrive oder Dropbox speichere, wollte ich dennoch ein offline Backup haben.
Aktuell muss ich nur 2 Verzeichnisse sichern, meinen Benutzerordner und ein Programm, welches ich nicht so konfigurieren konnte das es die Daten in meinem Profil speichert.
Was würde also besser passen als ein PowerShell Script zu erstellen welches mir diese Daten sichert.
Das Script
Zu Beginn natürlich wieder die Variablen, die konfiguriert werden können.
$Destination ist das Ziel für euer Backup
$Versions gibt die Zahl der Backups an die behalten werden, alles was diese Zahl überschreitet wird im Ordner $Destination gelöscht
$Backupdirs gibt die Verzeichnisse an die gesichert werden soll, hier können auch mehr als 1 Verzeichnis angegeben werden
$Destination="F:\_Backup" #Copy the Files to this Location $Versions="10" #How many of the ölast Backups you want to keep $BackupDirs="C:\Users\Michael\AppData\Roaming\TaskUnifier","C:\Users\Michael" #What Folders you want to backup
Danach kommen unsere Einstellungen, in denen wir den Namen für unser Backupdir suchen und ein paar Variablen definieren
$Backupdir=$Destination +"\Backup-"+ (Get-Date -format yyyy-MM-dd)+"-"+(Get-Random -Maximum 100000)+"\" $Items=0 $Count=0
Danach folgt der Code, zuerst überprüfen wir ob alle Verzeichnisse auch existieren, danach erstellen wir das Backup Verzeichnis, sollte es hier zu Fehlern kommen wir das Script gestoppt.
Jedoch wenn alles funktioniert wird mit der Sicherung begonnen und euch wir ein Statusbalken angezeigt.
#Function #Create Backupdir Function Create-Backupdir { Write-Host "Create Backupdir" $Backupdir New-Item -Path $Backupdir -ItemType Directory | Out-Null } #Delete Backupdir Function Delete-Backupdir { Write-Host "Delete old Backup" $Delete=$Count-$Versions+1 Get-ChildItem $Destination -Directory | Sort-Object -Property $_.LastWriteTime -Descending | Select-Object -First $Delete | Remove-Item -Recurse -Force } #Check if Backupdirs and Destination is available function Check-Dir { if (!(Test-Path $BackupDirs)) { return $false } if (!(Test-Path $Destination)) { return $false } } #Save all the Files Function Make-Backup { $Files=@() $SumItem=0 foreach ($Backup in $BackupDirs) { $colItems = (Get-ChildItem $Backup -recurse | Measure-Object -property length -sum) #"{0:N2}" -f ($colItems.sum / 1MB) + " MB of Files" $Items=0 $FilesCount += Get-ChildItem $Backup -Recurse | Where-Object {$_.mode -notmatch "h"} Copy-Item -Path $Backup -Destination $Backupdir -Force -ErrorAction SilentlyContinue $SumItem+=$colItems.Sum.ToString() $SumItems+=$colItems.Count } $TotalMB="{0:N2}" -f ($SumItem / 1MB) + " MB of Files" Write-Host "There will be"$TotalMB "copied and there are"$filesCount.Count "files to copy" foreach ($Backup in $BackupDirs) { $Index=$Backup.LastIndexOf("\") $SplitBackup=$Backup.substring(0,$Index) $Files = Get-ChildItem $Backup -Recurse | Where-Object {$_.mode -notmatch "h"} foreach ($File in $Files) { $restpath = $file.fullname.replace($SplitBackup,"") Copy-Item $file.fullname $($Backupdir+$restpath) -Force -ErrorAction SilentlyContinue |Out-Null $Items += (Get-item $file.fullname).Length $status = "Copy file {0} of {1} and copied {3} MB of {4} MB: {2}" -f $count,$filesCount.Count,$file.Name,("{0:N2}" -f ($Items / 1MB)).ToString(),("{0:N2}" -f ($SumItem / 1MB)).ToString() $Text="Copy data Location {0} of {1}" -f $BackupDirs.Rank ,$BackupDirs.Count Write-Progress -Activity $Text $status -PercentComplete ($Items / $SumItem*100) $count++ } } $SumCount+=$Count Write-Host "Copied" $SumCount "files with" ("{0:N2}" -f ($Items / 1MB)).ToString()"of MB" } #Check if Backupdir needs to be cleaned and create Backupdir $Count=(Get-ChildItem $Destination -Directory).count if ($count -lt $Versions) { Create-Backupdir } else { Delete-Backupdir Create-Backupdir } #Check if all Dir are existing and do the Backup $CheckDir=Check-Dir if ($CheckDir -eq $false) { Write-Host "One of the Directory are not available, Script has stopped" } else { Make-Backup } Write-Host "Press any key to close ..." $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Download auf der TechNet Gallery: http://gallery.technet.microsoft.com/PowerShell-Backup-Script-956f312c
Solltet ihr Fragen, Wünsche oder Probleme mit dem Script haben, schreibt mir ein Kommentar.
Alle meine TechNet Gallery Downloads findet ihr hier: 1jrYQoA
BITTE BEWERTE MEINE DOWNLOADS IN DER TECHNET GALLERY UND SAGT MIR WAS IHR EUCH VON DER NÄCHSTEN VERSION WÜNSCHT.
Michael Seidl aka Techguy
Hallo Michael,
zunächst vielen Dank für das Script 😉 Sehr hilfreich.
Mir sind jedoch 2 Fehler aufgefallen:
1. Zählen der Verzeichnissen im Backup-Ziel funktioniert nicht (PowerShell Fehlermledung)
Falsch:
$Count=(Get-ChildItem $Destination -Directory).count
Richtig:
$Count=(Get-ChildItem $Destination | where {$_.Attributes -eq ‘Directory’}).count
Den Parameter -Directory gibt es nicht. Demnach muss im gesamten Script
–> Get-ChildItem $Destination -Directory
durch
–> Get-ChildItem $Destination | where {$_.Attributes -eq ‘Directory’}
ersetzt werden.
2. Beim Löschen der Backups wird immer das jüngste Backup gelöscht und nicht das älteste
Falsch:
Get-ChildItem $Destination -Directory | Sort-Object -Property $_.LastWriteTime -Descending | Select-Object -First $Delete | Remove-Item -Recurse -Force
Richtig:
Get-ChildItem $Destination | where {$_.Attributes -eq ‘Directory’} | Sort-Object -Property @{Expression={$_.LastWriteTime};Ascending=$true} | Select-Object -First $Delete | Remove-Item -Recurse -Force
Die Sortierung, so wie du sie geschrieben hast, funktioniert nicht (es wird, warum auch immer, nicht nach LastWriteTime, sondern nach Ordnernamen sortiert.
Es muss also
–> Sort-Object -Property $_.LastWriteTime -Descending
durch
–> Sort-Object -Property @{Expression={$_.LastWriteTime};Ascending=$true}
ersetzt werden.
Gruß
deparcus
Hallo,
danke für die Info.
Zu Punkt 2, das wurde bereits in der aktuellen Version behoben, https://www.techguy.at/tag/backupscript/
Zu Punkt 1, welche PowerShell Version nutzt du?
Michael Seidl
Hallo,
ich nutze Version 2.0. Könnte eventuell daran liegen.
Habe nicht gesehen, dass es eine neue Version deines Scripts gibt 😉 Danke, werde mir sie mal anschauen.
Gruß
deparcus
Hallo,
habe mir dein Script in Version 1.1 mal angeschaut und getestet.
Die von mir beschriebenen Fehler sind dort auch drin.
Fehler 1 mag an meiner PowerShell-Version liegen (wobei ich eine Lösung die nahezu unabhängig von der Version ist eleganter finde), aber Fehler 2 offenbar nicht, da hier die Sortierung nicht wie gewollt funktioniert.
Gruß
deparcus
Hi,
super Sache mit dem Backup-Script; habe versucht das auf meine Anforderungen anzupassen; grds. läuft es schon. Probs habe ich mit speziellen Verzeichnissen: z. B. user\appdata\roaming; es werden da Dateien ausgelassen. Weisst Du warum?
VG
Jens
Hallo,
das Script is so gebaut, das Verzeichnisse welche keinen Zugriff gewähren, ausgelassen werden.
ich denke das der ausführende User kein Recht hat, auf das Verzeichnis zuzugreifen.
Hi,
aber beim manuellen Kopieren unter Windows werden alle Dateien kopiert; es muss also einen Unterschied geben, entweder hins. der Berechtigung bei der Ausführung des Scripts oder im Copy-Befehl selbst.
Danke für die Hilfe!
Gruß
Jens
Ergänzung: es liegt an Dateien mit Sonderzeichen (bei mir eckige Klammern); leider kann man ja nie ausschließen, dass solche Dateien im Sicherungsbestand sind; die werden dann stillschweigend übergangen. Hab noch keine Lösung gefunden.
VG
jens
Hallo, ja Fehler werden ignoriert
Kann man ein Batch-Skript zu einem PowerShell-Skript umschreiben?
REM Datum
set jahr=%date:~-4%
set monat=%date:~-7,2%
set tag=%date:~-10,2%
set mytime=%time%
set stunde=%mytime:~0,2%
if “%stunde:~0,1%”==” ” set stunde=0%stunde:~1,1%
set minute=%time:~3,2%
set datum=%jahr%-%monat%-%tag%-%stunde%-%minute%
“C:\Program Files (x86)\Snapshot\snapshot64.exe” HD1:* Z:\Server01-Backup\%datum%\$computername$HD.SNA -R -L1490 -W –AllWriters –logfile:C:\Snapshot\logfile.txt –createdir
copy C:\Snapshot\logfile.txt Z:\Server01-Backup\Backup-Logs
Wie macht man das mit dem Erstellen eines Ordners in PowerShell?
Gruß Daniel
Hallo,
natürlich, New-Item oder New-ChildItem dann kommst du sicher weiter.
Hallo,
super Lösung, vielen Dank.
Die einzige Änderung, die notwendig ist: Bei Verwendung von 7zip ist die Dateiendung nicht “.zip”, sondern “.7z”.
Die Aktionen des Scripts habe sogar ich als Powershell-Laie verstanden, die notwendigen Anpassungen der Verzeichnisse waren einfach.
Seit der Erstellung des Scripts hat sich allerdings bei der Festplattengeschwindigkeit einiges getan, vor allem die Verwendung von SSD’s als Festplatte.
Es könnte daher schneller sein, zuerst die Komprimierung von den Orginaldateien vorzunehmen, und danach nur noch das zip-file zu verschieben.
Optimierung: Übernahme der Verzeichnisse (BackupDirs, Destination,Exclude) als Parameter mit param()
Nochmals vielen Dank und viel Erfolg,
Rudolf Fiedler
Thank you for your script, Michael. Everything works fine, except there are no files copied only the folders. Your script detect the right number of files and size, but copies only the dirs. What am I doing wrong?
27.01.2021-05:46:10 – INFO: ———————-
27.01.2021-05:46:10 – INFO: Start the Script
27.01.2021-05:46:10 – INFO: Check if there are more than 5 Directories in the Backupdir
27.01.2021-05:46:10 – INFO: Check if there are more than 5 Zip in the Backupdir
27.01.2021-05:46:10 – INFO: Check if BackupDir and Destination exists
27.01.2021-05:46:10 – INFO: Started the Backup
27.01.2021-05:46:10 – INFO: Count all files and create the Top Level Directories
27.01.2021-05:46:10 – INFO: There are 18 Files with 4,77 MB of Files to copy
27.01.2021-05:46:11 – INFO: ———————-
27.01.2021-05:46:11 – INFO: Copied 4 files with 0,00 MB of Files
27.01.2021-05:46:11 – INFO: 0 Files could not be copied
27.01.2021-05:46:11 – INFO: Backupduration 0 Minutes and 6 Seconds
27.01.2021-05:46:11 – INFO: ———————-
27.01.2021-05:46:11 – INFO: ———————-
See you using the latest version?
A) warum ist der Download in irgendeinem Microsoft Technet und nicht (wie bei jedem anderen normalen Menschen, der Sourcecode fuer die Oeffentlichkeit bereitstellen will) auf Github?
B) Gerade weil bei Microsoft oft Sachen deprecaten, ist das wohl der schlechteste Ort um downloads oder contentpages zu verlinken.
C) Das ist naemlich jetzt genau der Fall. Dein link ist broken.
D) Wenn du deinen Code postest und Leute daran Fehler finden, solltest du nicht nur das File updaten sondern selbstredend den source hier auch.
E) Mache doch mal ein tool, dass den source der geposted ist mit dem abgleicht den du in irgendeinem File irgendwo bereitstellst und dann sollte in regelmaessigen intervallen der posted source auch updates (automatisiert) erfahren.
Ich hoffe di hast morgen einen besseren Tag, und in der Zwischenzeit einfach mal hier schauen; https://www.techguy.at/powershell-backupscript-version-2-0-released/
Gern geschehen