none
Fortschrittsbalken Kopiervorgang RRS feed

  • Frage

  • Hallo zusammen,

    ich bin noch recht neu in der Powershell-Welt und habe nun meine ersten Gehversuche hierbei.

    Folgendes Vorhaben:

    Ich habe einen Quellordner E:\Programm, in diesem liegt die aktuellste Version eines Programmes welche ich als Update Quelle verwenden möchte.

    Nun habe ich unter C:\Programme sehr viele Kundenordner. In diesen befinden sich jeweils Order für Dokumente und ein oder mehrere Ordner mit dem festen Namensschema: "Release" "Kundenname"

    Nun war ich schon einmal so weit und habe es geschafft, dass mir alle Ordner, welche das Wort "Release" beinhalten, mit den jeweiligen Pfaden herausgefiltert werden und vom Quellpfad hinein kopiert wird:

    (Get-ChildItem -Path C:\Programm -Filter "*Release*" -Recurse -Directory).Fullname | Foreach-Object { Copy-Item -Path "E:\Programm*" -dest $_ }

    Auf dem RDS befinden sich ca. 100 Kunden mit durchschnittlich 3 dieser sogenannten Release-Ordner. 

    Aus diesem Grund wollte ich einen Fortschrittsbalken mit einbauen. Hier fing dann das Chaos an:

    [int]$i=0
    $Verzeichnisse = (Get-ChildItem -Path C:\Programm -Filter "*Release*" -Recurse -Directory).Fullname
    Foreach-Object (Copy-Item -Path "E:\Programm\*" -dest $Verzeichnisse) {
    $i++
    Write-Progress -Activity "Kopiere aktuellste Version in Kundenordner" -PercentComplete (($i*100)/$Verzeichnisse.count)
    }
    $i=0

    Leider bekomme ich als Ergebnis folgendes:

     
    Copy-Item : "System.Object[]" kann nicht in den Typ "System.String" konvertiert werden, der für den Parameter "Destination" erforderlich ist. Die angegebene Methode wird nicht unterstützt.
    In Zeile:7 Zeichen:76
    + ... Item -Path "C:\Programm\*" -dest $Verzeichnisse )
    +                                                          ~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidArgument: (:) [Copy-Item], ParameterBindingException
        + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.CopyItemCommand
    
    
    $i++
    Write-Progress -Activity "Kopiere aktuellste Version in Kundenordner" -PercentComplete (($i*100)/$Verzeichnisse.count)


    Ich bin für jeden Tipp dankbar!

    Gruß

    Stefan



    • Bearbeitet wolf25078 Montag, 7. Dezember 2020 11:25 Falsches Verzeichnis angegeben
    Montag, 7. Dezember 2020 00:53

Antworten

  • Hallo Stefan und erstmal Willkommen im Deutschen Microsoft Powershell Forum.

    Bevor wir irgendwie weitermachen - formatierst Du bitte Deinen Code als Code? Sonst ist er auf Grund von ungewollt eingefügten Zeilenumbrüchen quasi nicht vernünftig zu lesen. How to Use the Code Feature in a TechNet Forum Post  (Bitte Deinen obigen Beitrag nochmal bearbeiten - keinen neuen anlegen.) Das Gleiche gilt übrigens auch für Fehlermeldungen, Konsolen-Ausgaben oder Beispiel-Daten.

    Danke schon mal im Voraus.

    Jetzt zu Deiner Frage. Die Variable $Verzeichnisse enthält ein Array von Verzeichnissen. Das ist für das cmdlet Copy-Item nicht erlaubt. Du musst ein einzelnes Verzeichnis angeben. Die von Dir benutze Schleife (Foreach-Object) ist auch falsch - es sei denn Du hast uns beim hier Reinkopieren des Codes etwas unterschlagen. ;-)  ... das sollte eher eine Foreach - Schleife sein. Am Besten, Du schaust Dir die Hilfe für die cmdlets mal komplett an - inklusive der Beispiele, dann wird hoffentlich klar, was die Unterschiede sind.

    Vielleicht noch ein Tipp: Die Powershell ist nicht gerade flott, wenn es um Datei-Operationen geht. Vielleicht würde die Benutzung von robocopy Dein Script ausreichend beschleunigen, um eine Fortschrittsanzeige überflüssig zu machen. Sowas macht man normalerweise nur, um "Enduser" bei der Stange zu halten, wenn die gerade gestartete Aktion ein paar Sekunden länger dauert.  ;-) 

    Wenn das Ganze aber auch für Dich zum Lernen sein soll, ist allerdings wieder alles erlaubt. ;-)  Dann würde es vermutlich helfen, wenn Du uns den ganzen Code zeigtest.


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Montag, 7. Dezember 2020 02:03

Alle Antworten

  • Hallo Stefan und erstmal Willkommen im Deutschen Microsoft Powershell Forum.

    Bevor wir irgendwie weitermachen - formatierst Du bitte Deinen Code als Code? Sonst ist er auf Grund von ungewollt eingefügten Zeilenumbrüchen quasi nicht vernünftig zu lesen. How to Use the Code Feature in a TechNet Forum Post  (Bitte Deinen obigen Beitrag nochmal bearbeiten - keinen neuen anlegen.) Das Gleiche gilt übrigens auch für Fehlermeldungen, Konsolen-Ausgaben oder Beispiel-Daten.

    Danke schon mal im Voraus.

    Jetzt zu Deiner Frage. Die Variable $Verzeichnisse enthält ein Array von Verzeichnissen. Das ist für das cmdlet Copy-Item nicht erlaubt. Du musst ein einzelnes Verzeichnis angeben. Die von Dir benutze Schleife (Foreach-Object) ist auch falsch - es sei denn Du hast uns beim hier Reinkopieren des Codes etwas unterschlagen. ;-)  ... das sollte eher eine Foreach - Schleife sein. Am Besten, Du schaust Dir die Hilfe für die cmdlets mal komplett an - inklusive der Beispiele, dann wird hoffentlich klar, was die Unterschiede sind.

    Vielleicht noch ein Tipp: Die Powershell ist nicht gerade flott, wenn es um Datei-Operationen geht. Vielleicht würde die Benutzung von robocopy Dein Script ausreichend beschleunigen, um eine Fortschrittsanzeige überflüssig zu machen. Sowas macht man normalerweise nur, um "Enduser" bei der Stange zu halten, wenn die gerade gestartete Aktion ein paar Sekunden länger dauert.  ;-) 

    Wenn das Ganze aber auch für Dich zum Lernen sein soll, ist allerdings wieder alles erlaubt. ;-)  Dann würde es vermutlich helfen, wenn Du uns den ganzen Code zeigtest.


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Montag, 7. Dezember 2020 02:03
  • Hallo, 

    und erst einmal vielen Dank für die Antwort!

    "Die Variable $Verzeichnisse enthält ein Array von Verzeichnissen. Das ist für das cmdlet Copy-Item nicht erlaubt."

    Nur zum Verständnis: In meinem ersten Code, den ich oben eingefügt habe, da nutze ich doch $_ auch als Array von Verzeichnissen, oder etwa nicht? Denn hierbei funktioniert es ja, dass ich jedes einzelne Verzeichnis aktualisieren lasse.

    "Wenn das Ganze aber auch für Dich zum Lernen sein soll, ist allerdings wieder alles erlaubt. ;-)"

    Vollkommen richtig der Lernfaktor soll hierbei eine große Rolle spielen. Jetzt wird es endlich mal Zeit mir Powershell anzueignen.

    Ich habe den Code mal entsprechend formatiert, wie von dir gewünscht :-)

    Und jetzt setze ich mich mal ein wenig mit Foreach außeinander.

    Gruß

    Stefan

    Montag, 7. Dezember 2020 11:24
  • Hey,

    das mit Foreach war ein guter Tipp, ich bin gerade sehr weit voran gekommen mit dieser Überarbeitung hier:

    [int]$i=0
    
    $Verzeichnisse = (Get-ChildItem -Path C:/Test -Filter "*Release*" -Recurse -Directory).Fullname
    
    ForEach ($Verzeichnis in $Verzeichnisse)
    {
    Copy-Item -Path "E:\Programm\*" -dest $Verzeichnis
    $i++
    Write-Progress -Activity "Kopiere aktuellste Version in Kundenordner" -PercentComplete (($i*100)/$Verzeichnisse.count)} 
    $i=0 

    Es scheint so als tut er erstamal das was ich von ihm möchte.

    Jetzt muss ich vor allem das Verhalten noch ein wenig anpassen. Teilweise gibt es Ordner, die schon komplett aktuell sind. Hierbei würde er mir dann fehler auswerfen, dass ja alles schon vorhanden sei. Aber das sind denke ich alles parameter, die ich dann bei robocopy angeben müsste.

    Was wäre denn grundsätzlich an meinem Code hier noch zu Verbessern oder effizienter zu schreiben? Ich gehe mal von sehr viel aus.

    Gruß

    Stefan

    Montag, 7. Dezember 2020 11:37
  • Es scheint so als tut er erstamal das was ich von ihm möchte.

    "Es scheint ...." ??? Bist Du Dir nicht sicher? ;-)

    Jetzt muss ich vor allem das Verhalten noch ein wenig anpassen. Teilweise gibt es Ordner, die schon komplett aktuell sind. Hierbei würde er mir dann fehler auswerfen, dass ja alles schon vorhanden sei. Aber das sind denke ich alles parameter, die ich dann bei robocopy angeben müsste.

    robocopy kopiert in der Voreinstellung nur Dateien die neuer oder noch nicht vorhanden sind, ohne die bereits existierenden als Fehler zu melden. ;-) 

    Mit purem Powershell könntest Du die Fehler entweder "behandeln" oder "unterdrücken" - je nach dem, was nach Deiner Einschätzung das Zielführendste ist.

    Was wäre denn grundsätzlich an meinem Code hier noch zu Verbessern oder effizienter zu schreiben? Ich gehe mal von sehr viel aus.

    Hmmm ... das ist immer eine schwierige/problematische Frage. Und ich weiß nicht, was Du mit "effizienter zu schreiben" meinst. Effizienter beim Kopieren wäre robocopy. Wenn Du die "Code-Qualität" meinst, steht das wieder auf einem ganz anderen Blatt. Du verwendest z.B. eine Variable $i, deren Sinn sich mir nicht erschließt. Wenn Du nicht noch Code in der Schleife hast, den Du hier nicht gepostet hast, dann ist $i überflüssig. Ein allgemeiner Tipp wäre, den Code so leicht lesbar und ausführlich zu schreiben, wie möglich. Eine gute Lektüre dazu wäre The PowerShell Best Practices and Style Guide.


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Montag, 7. Dezember 2020 12:45