none
Dateirechte mit Powershell schnell ändern RRS feed

  • Frage

  • Hallo, ich habe folgendes Problem:

    Ich muss von einem Share eine Kopie erstellen.

    In dem Share liegt ein Ordner Bilder. Dieser Ordner hat pro Jahr einen Unterordner - also 2010, 2011

    Damit sieht die Dateieben so aus:

    Bilder - 2010

    Bilder - 2011

    Pro Bilderordner liegen etwa 2-3 Millionen Files in weiteren Unterordnern.

    Insgesamt komme ich so auf 25 Millionen Files mit etwa 15 TB an Daten.

    Der Share liegt auf einem Netapp Share und wird per Snapshotcopy geclont.

    Damit ist die Kopie innerhalb von wenigen Sekunden vorhanden.

    Allerdings gehört der Ordner Bilder dem User Kunde_A. Die Kopie soll nun dem User Kunde_B gehören.

    Kunde_A darf auf den Ordner von Kunde_B nicht zugreifen und umgekehrt. Also gehen wir bislang über die Explorer-Gui, und setzen die Dateoownerschaft vom Kunden_A auf den Kunden_B beim Klon, und in den Dateirechten entfernen wir Kunde_A, und setzen Kunde_B mit Vollzugriff.

    Wegen der Datenmenge dauert das aber mehrere Tage. Wie kann ich das mit einem Powershellscript schneller machen?

    Meine Idee wäre:

    Ich setze die Rechte Nur auf den Ordner Bilder. Danach wird über eine Loop-Schleife für jeden Unterordner ein Prozess gestartet, der dann die Änderungen rekursiv durchfräst.

    Würde so etwas gehen, und wenn ja: wie?

    Wir setzen Windows Server 2016 x64 ein.

    Freitag, 3. Dezember 2021 10:40

Antworten

  • Moin,

    eine andere Idee als PowerShell zu parallelisieren, wäre SetACL von Helge Klein zu benutzen, welches deutlich performanter ist als PowerShell oder Windows Explorer.

    Und jetzt lese ich noch in Deinem OP, was da unter der Haube passiert. Du sparst Dir also praktisch die Zeit fürs Kopieren der Datenbestände am Anfang durch die Snapshot Copy. Dann fängst Du aber an die Kopie zu verändern, und in diesem Moment wird die Kopie - zumindest vom Eintrag in der Zurodnungstabelle, wo die ACLs gespeichert sind - ja erst wirklich angelegt. Das macht den Vorgang natürlich auch nicht performanter ;-)


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Samstag, 4. Dezember 2021 08:35
  • Moin,

    parallelisieren in PowerShell: Jobs, Runspaces oder Foreach-Object -Parallel in PowerShell 7.1 und höher. Für den Fall sind die Jobs vermutlich am besten geeignet.

    Die lange Laufzeit ist eine Eigenart von NTFS und nicht von PowerShell.


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Freitag, 3. Dezember 2021 11:19

Alle Antworten

  • Du kannst per Set-ACL in Powershell einen Ordner incl. Vererbung in einem Befehl setzen:
    https://blog.netwrix.de/2020/01/31/verwalten-von-dateisystem-acls-mit-powershell-skripts/

    Wenn die Vererbung bereits eingestellt sein sollte, geht das sehr schnell.
    U.U. muss man die ACL des Zielordners bereits vor dem Copy korrekt setzten, da dann die Vererbung ggf. übernommen wird.

    Freitag, 3. Dezember 2021 10:48
  • Ja, die Vererbung klappt ja. Leider scheint das Powershell in *einem* Prozess zu machen, das dauert aktuell 6 Tage.

    Darum die Frage: Kann man das auch anders machen, dass also nur im Hauptordner etwas ohne Vererbung geändert wird, und danach ziehen die Subfolder die Änderungen vom Hauptordner. Das könnt eman ja parallelisieren, oder?

    Ich suche einfach eine Möglichkeit, den Change Ownership zu beschleunigen.

    Freitag, 3. Dezember 2021 11:00
  • Moin,

    parallelisieren in PowerShell: Jobs, Runspaces oder Foreach-Object -Parallel in PowerShell 7.1 und höher. Für den Fall sind die Jobs vermutlich am besten geeignet.

    Die lange Laufzeit ist eine Eigenart von NTFS und nicht von PowerShell.


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Freitag, 3. Dezember 2021 11:19
  • Nun ja, bei Millionen von Dateien muss ja die ACL komplett ersetzt werden.
    Bei 15 Mio Dateien und 86400 Sekunden * 6 macht das knapp 30 Änderungen/Sekunde;-).
    Das Ändern der ACL ist ein aufwändiger Vorgang.
    Beschleunigen kannst du das nur dann, wenn du die Vererbung eine Ebene tiefer ansetzt und dies je Verzeichnis in einem Job regelst.
    Allerdings bringt mehr Jobs als du vCPU's hast fast nichts.
    Also bei 6 Jobs und 6 Unterverzeichnissen brauchst du 1 Tag.

    Deswegen, wenn die Quelle bereits vererbte Rechte hätte, ginge nach dem Copy das Ändern erheblich schneller, da du ja nur den Besitzer und nicht die Vererbung ändern musst.


    Freitag, 3. Dezember 2021 12:11
  • Moin,

    eine andere Idee als PowerShell zu parallelisieren, wäre SetACL von Helge Klein zu benutzen, welches deutlich performanter ist als PowerShell oder Windows Explorer.

    Und jetzt lese ich noch in Deinem OP, was da unter der Haube passiert. Du sparst Dir also praktisch die Zeit fürs Kopieren der Datenbestände am Anfang durch die Snapshot Copy. Dann fängst Du aber an die Kopie zu verändern, und in diesem Moment wird die Kopie - zumindest vom Eintrag in der Zurodnungstabelle, wo die ACLs gespeichert sind - ja erst wirklich angelegt. Das macht den Vorgang natürlich auch nicht performanter ;-)


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Samstag, 4. Dezember 2021 08:35
  • bei der Anzahl von Dateien und solcher Laufzeit würde ich auch andere Varianten testen. Könnte man nicht mit 2 Platten arbeiten und nur den Share berechtigen und die Files darunter gar nicht mit Berechtigungen angreifen? Und/Oder event. nur die geänderten Dateien ergänzen.

    Samstag, 4. Dezember 2021 12:27
  • Hallo, ich habe jetzt mal folgendes Script gebaut, was eigentlich tut, was es soll, aber halt sehr lange läuft:

    	$Mainfolder = "\\servername\share"
    	$folders = Get-ChildItem $Mainfolder
    	$OldAccount = "domain\usera"
    	$NewAccount = "domain\userb"
    	
    	Try
    	{
    		$Processes = @()
    	
    		Write-Host `t  Set New File Owner to $NewAccount -ForegroundColor Green
    		$Processes += Start-Process icacls -WindowStyle Hidden -ArgumentList "$Mainfolder /setowner $NewAccount /T /C" -PassThru
    	
    		Write-Host `t  Give new Admin owner $NewAccount Full Access to new files and folders and remove old Adminowner $OldAccount -ForegroundColor Green
    		$Processes += Start-Process icacls -WindowStyle Hidden -ArgumentList "$Mainfolder /grant ${NewAccount}:(OI)(CI)F /remove:g $OldAccount /C" -PassThru
    		
    		#Now that all processes/jobs have been started, let's wait for them (first check if there was any subfile/subfolder)
    		#Wait for $Job
    		
    				Wait-Process -Id $Processes.Id -ErrorAction SilentlyContinue
    			
    		
    		Write-Host "The script has completed resetting permissions under $($Mainfolder)."
    	}
    	
    	Catch
    	{
    		$ErrorMessage = $_.Exception.Message
    		Throw "There was an error during the script: $($ErrorMessage)"
    	}
    Könnte man das noch irgendwie parallelisieren?

    Mittwoch, 18. Mai 2022 06:45
  • Viel mehr geht ja nicht. Die Aktualisierung der ACL bremst dich aus, da dies nur synchron erfolgt.
    Wenn dies also mehrere Prozesse machen, kann eine Parallelisierung u.U. nur (wie oben gesagt) über mehrere physisch getrennte Platten funktionieren. Die ACL bemüht auch Abfragen im AD wenn es sich nicht um lokale Profile handelt und das dauert eben seine Zeit.

    Versuche dies mal trotzdem über Gruppen zu lösen, denn das Ändern einer Gruppe passiert ja im AD und nicht im Dateisystem.

    Mittwoch, 18. Mai 2022 07:54