chkdsk
Goto Top

Powershell: copy-item beschleunigen

Moin Moin Zusammen,

ich habe 2 Fragen zu meinem folgenden Skript.
Ich muss auf ca. 200 Clients einen Ordner kopieren (ca 100mb groß) und auf diesen Ordner der lokalen Gruppe Users Vollzugriff geben.
GPOs kommen leider nicht in Frage. Muss händisch passieren.

Folgendes ist vorhanden
param([switch]$Elevated)

function Test-Admin {
    $currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
    $currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}

if ((Test-Admin) -eq $false)  {
    if ($elevated) {
        # tried to elevate, did not work, aborting
    } else {
        Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))  
    }
    exit
}

'running with full privileges'  
write-host
write-host

$file = get-content -path "C:\temp\pc.txt"  
foreach($pc in $file) {
try {
copy-item -path "\\server1\folder1" -Destination "\\$pc\C$\temp\" -recurse  

foreach($pc in $file) {
$acl = get-acl -path "\\$pc\c$\temp\folder1"   
$new = "users","full","ContainerInherit,ObjectInherit","None","Allow"   
$accessRule = new-object System.Security.AccessControl.FileSystemAccessRule $new 
$acl.SetAccessRule($accessRule) 
$acl | Set-Acl "\\$pc\c$\temp\folder1"  
}

Write-Output $([string](get-date) + "`t $pc failed") | out-file -append -filepath "C:\temp\failed.log"  
}
catch {Write-Output $([string](get-date) + "`t $pc success") | out-file -append -filepath "C:\temp\success.log"  
}
write-host
write-host "see Log" -foreground "green"  
write-host
}

1. Gibt es eine Möglichkeit das kopieren zu beschleunigen, evtl. den Ordner auf mehrere PCs gleichzeitig zu kopieren?
2. Die Log Datei nach erfolgreichen/nicht erfolgreichen Kopieren/Berechtigungen zu sortieren. Aktuell haut er mir beides in jeweils eine Datei. Ich weiß daher nicht was bspw. falsch lief...Kopiervorgang oder Berechtigung setzen.

Content-Key: 647663

Url: https://administrator.de/contentid/647663

Printed on: May 9, 2024 at 07:05 o'clock

Member: SlainteMhath
SlainteMhath Feb 03, 2021 at 08:33:11 (UTC)
Goto Top
Moin,

zu 1)
Den Ordner als Archiv ausliefern und dann am client entpacken?

zu 2)
Dazu brauchst du pro Vorgang ein try...catch konstrukt das im fehlerfall entsprechende Logeinträge erzeugt.

lg,
Slainte
Member: NordicMike
NordicMike Feb 03, 2021 at 09:19:30 (UTC)
Goto Top
Und wenn ein Client nicht online ist oder hängt?

Evtl mehrere Tasks (gleichzeitig) dafür laufen lassen...

... oder die Clients selbst den Task starten lassen (die es ebenfalls fast gleichzeitig ausführen würden) - was dann wieder einer GPO Methode gleich kommen würde.
Member: TK1987
TK1987 Feb 03, 2021 updated at 09:26:21 (UTC)
Goto Top
Moin,

Zitat von @chkdsk:
1. Gibt es eine Möglichkeit das kopieren zu beschleunigen, evtl. den Ordner auf mehrere PCs gleichzeitig zu kopieren?
Sicher geht das, Multithreading mittels Runspacepool.
2. Die Log Datei nach erfolgreichen/nicht erfolgreichen Kopieren/Berechtigungen zu sortieren. Aktuell haut er mir beides in jeweils eine Datei. Ich weiß daher nicht was bspw. falsch lief...Kopiervorgang oder Berechtigung setzen.
Wie @SlainteMhath bereits erwähnt hat, über Try-Catch, siehe hier.

Gruß Thomas
Mitglied: 147323
147323 Feb 03, 2021 updated at 09:27:10 (UTC)
Goto Top
Kam hier vor kurzem schon mal
Powershell Copy-Item Script schneller machen
Member: chkdsk
chkdsk Feb 03, 2021 updated at 10:24:03 (UTC)
Goto Top
@SlainteMhath
Als Archiv ist leider nicht möglich, es sollte einfach nur der Ordner sein

@NordicMike
das hat, auch wenn es merkwürdig klingt, tatsächlich keine so große Prio. Sollte der PC aus sein, wird er ja übersprungen

@147323
das hatte ich tatsächlich schon gesehen, aber wie bspw. in der Lösung angesprochen, pipe ich nicht auf das object

Gibt es übrigens eine "einfache" Methode um den Fortschritt anzeigen zu lassen?

Was mich jetzt nur wundert, nachdem ich für das set-acl ein weiteres try-catch eingebaut habe, zeigt er mir ab dem zweiten PC einen Fehler an, dass die Berechtigungen nicht geschrieben werden konnten, obwohl er das tut. Die Berechtigungen wurden angepasst.
$file = get-content -path "C:\temp\pc.txt"  
foreach($pc in $file) {
try {
copy-item -path "\\server1\folder1" -Destination "\\$pc\C$\temp\" -force -recurse -verbose  

Write-Output $([string](get-date) + "`t $pc success") | out-file -append -filepath "C:\temp\sucess.log"  
}
catch {Write-Output $([string](get-date) + "`t $pc failed") | out-file -append -filepath "C:\temp\failed.log"  
}


foreach($pc in $file) {
try {
$acl = get-acl -path "\\$pc\c$\temp\folder1"  
$new = "users","full","ContainerInherit,ObjectInherit","None","Allow"   
$accessRule = new-object System.Security.AccessControl.FileSystemAccessRule $new 
$acl.SetAccessRule($accessRule) 
$acl | Set-Acl "\\$pc\c$\temp\folder1"  
Write-Output $([string](get-date) + "`t $pc success") | out-file -append -filepath "C:\temp\acl_sucess.log"  
}
catch {Write-Output $([string](get-date) + "`t $pc failed") | out-file -append -filepath "C:\temp\acl_failed.log"  
}


write-host
write-host "see Log" -foreground "green"  
write-host
}
}
Member: NetzwerkDude
NetzwerkDude Feb 03, 2021 updated at 10:30:45 (UTC)
Goto Top
Die wohl einfachste Methode wäre Powershell 7.x zu nutzen, dort hat foreach-object einen -parallel schalter:
https://devblogs.microsoft.com/powershell/powershell-foreach-object-para ...

Oder wie im verlinkten Thread von Uwe selbstgemacht über Runspaces / Threads

Über klassiche Jobs sollte es aber auch gehen, da es "wenig" dafür aber "große" aufgaben sind (relativ gesehen)
https://devblogs.microsoft.com/scripting/parallel-processing-with-jobs-i ...

Edit:
Für fortschrittsbalken gibts das builtin cmdlet Write-Progress
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell. ...
Member: NordicMike
NordicMike Feb 03, 2021 updated at 11:00:11 (UTC)
Goto Top
Sollte der PC aus sein, wird er ja übersprungen
Denke daran, der Copy Job hängt dann erst einmal, bis es einen Timeout erzeugt. Auch musst du dann später überlegen, wer es schon kopiert bekommen hat oder wer es noch nicht hat und notfalls es allen noch einmal pushen, bis es auch der letzte endlich erhalten hat - oder die letzten einzeln raus suchen und es ihnen noch einmal antriggern.
Mitglied: 147323
147323 Feb 03, 2021 updated at 11:16:09 (UTC)
Goto Top
Zitat von @chkdsk:
@147323
das hatte ich tatsächlich schon gesehen, aber wie bspw. in der Lösung angesprochen, pipe ich nicht auf das object
Na und wo ist das Problem?? Musst du ja nicht ... Verstand benuten face-wink.
Member: chkdsk
chkdsk Feb 03, 2021 at 11:40:25 (UTC)
Goto Top
Zitat von @NordicMike:

Sollte der PC aus sein, wird er ja übersprungen
Denke daran, der Copy Job hängt dann erst einmal, bis es einen Timeout erzeugt. Auch musst du dann später überlegen, wer es schon kopiert bekommen hat oder wer es noch nicht hat und notfalls es allen noch einmal pushen, bis es auch der letzte endlich erhalten hat - oder die letzten einzeln raus suchen und es ihnen noch einmal antriggern.
Deswegen lasse ich mir im Log ja ausgeben, auf welchen PC erfolgreich kopiert wurde und auf welchen nicht face-smile
Member: chkdsk
chkdsk Feb 03, 2021 at 11:41:56 (UTC)
Goto Top
Zitat von @147323:

Zitat von @chkdsk:
@147323
das hatte ich tatsächlich schon gesehen, aber wie bspw. in der Lösung angesprochen, pipe ich nicht auf das object
Na und wo ist das Problem?? Musst du ja nicht ... Verstand benuten face-wink.
Sorry aber so brauchst du mir nicht kommen face-smile ich hatte lediglich gefragt ob es eine Möglichkeit gibt und du hast mich auf diesen Thread verwiesen. Ich habe dir nur mitgeteilt das ich diesen bereits gesehen habe.