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-ID: 647663

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

Ausgedruckt am: 21.11.2024 um 18:11 Uhr

SlainteMhath
SlainteMhath 03.02.2021 um 09:33:11 Uhr
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
NordicMike
NordicMike 03.02.2021 um 10:19:30 Uhr
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.
TK1987
TK1987 03.02.2021 aktualisiert um 10:26:21 Uhr
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
147323
147323 03.02.2021 aktualisiert um 10:27:10 Uhr
Goto Top
Kam hier vor kurzem schon mal
Powershell Copy-Item Script schneller machen
chkdsk
chkdsk 03.02.2021 aktualisiert um 11:24:03 Uhr
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
}
}
NetzwerkDude
NetzwerkDude 03.02.2021 aktualisiert um 11:30:45 Uhr
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. ...
NordicMike
NordicMike 03.02.2021 aktualisiert um 12:00:11 Uhr
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.
147323
147323 03.02.2021 aktualisiert um 12:16:09 Uhr
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.
chkdsk
chkdsk 03.02.2021 um 12:40:25 Uhr
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
chkdsk
chkdsk 03.02.2021 um 12:41:56 Uhr
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.