Arbeit mit Ordnern: Finden, Kopieren, Umbenennen Fortgeschrittenes Windows-Dateimanagement mit PowerShell

Autor / Redakteur: Christa Anderson / Ulrich Roderer

Im folgenden soll anhand eines periodisch auszuführenden Powershell-Skripts die Möglichkeiten der Arbeit mit Ordnern gezeigt werden.

Anbieter zum Thema

Folgende Aufgabe: Per Script sollen Ordner in einem temporären Verzeichnis erzeugt werden, die von einem Share im Netzwerk aus befüllt werden. Diese befüllten Ordner sollen dann auf anderen Shares gesichert werden. Um dieses Skript mehrmals ausführen zu können, müssen die Ordner im temporären Verzeichnis jedes Mal umbenannt werden. Diesen Prozess manuell auszuführen ist wirklich mühsam.

Um diese Aufgabe zu programmieren sind folgende Schritte notwendig:

  • Alle Ordner im temporären Verzeichnis finden
  • Die Ordner entsprechend ihrem Inhalt umbenennen
  • Sie auf das Ziellaufwerk kopieren

Das Finden der Ordner

Leider ist es nicht möglich, den Inhalt eines Ordners mit dem Kommando „get-childitem“ zu sortieren und dann zu verändern. Denn der Parameter „itemtype” wird bei “get-item” nicht unterstützt.

Der Unterschied zwischen Ordnern und Dateien besteht darin, dass Ordner Objekte beinhalten, Dateien nicht. Deshalb liegt die Lösung des Problems darin, eine Frage zu stellen, die nur Container als Ergebnis bringt, die dann auf eine Variable gespeichert werden können und damit manipulierbar sind. Die Lösung bringt in diesem Fall „get-member“.

“Get-Member” zeigt die Eigenschaften und Methoden von Objekten. Sind die Eigenschaften eines Ordners bekannt, lassen sich Fragen formulieren, die nur Ordner als Ergebnis bringen. Damit ist es möglich, die Ordner dort anzulegen, wo die temporären Dateien gespeichert sind. Zuvor wird dieser Ort auf eine Variable gespeichert, so dass später leichter dorthin zurückgesprungen werden kann. Damit ergibt sich folgendes Programm:

$junkchild = get-childitem c:junk$junkchild | get-member

“get-member” erzeugt eine Liste von Eigenschaften, Methoden und Noteproperties (PowerShell-spezifische Felder). Unter der Liste der Noteproperties findet sich psIsContainer. Diese Eigenschaft beschreibt, ob es sich um einen Conntainer handelt oder nicht.

Damit ist man in der Lage, eine Variable zu definieren, die alle Ordner in dem temporären Verzeichnis findet. Die Syntax ist einfach, es ist aber darauf zu achten, dass die Bedingungen für den Operator „where“ in geschweifte Klammern gesetzt sind:

$junkall=get-childitem c:junk | where {$_.psIsContainer -eq $true}

Nutzt man “get-member”, um die Eigenschaften eines Objekts zu bekommen, um sie auf andere Objekte anzuwenden, sollte man darauf achten, dass beide Objekte wirklich vergleichbar sind. Sonst passiert es, dass die benötigten Eigenschaften nicht gefunden werden oder dass das Skript nicht funktioniert, weil das Ziel die benötigten Eigenschaften nicht unterstützt.

Ordner umbenennen

In unserem Szenario soll das Skript zum Kopieren von Dateien viermal ausgeführt werden, um Daten von unterschiedlichen Teilen des Shares zu holen. Nach dem ersten Durchgang müssen die Zielordner umbenannt werden und zwar mit den ihren Inhalten entsprechenden Namen.

Um das zu tun kann man „rename-item“ verwenden. Allerdings mit einer Einschränkung. Die Dateien sollen ihren ursprünglichren Namen behalten modifiziert mit einer speziellen Kennzeichnung. „get-member“ liefert über die Eigenschaft .FullName den Pfad, der an den originalen Namen angehängt wird:

$junkall | foreach-object -process {rename-item -path $_.fullname -newname „x86$_“}

“foreach-object” führt für jedes Objekt (beispielsweise Registry Key mit Subkeys oder Verzeichnisse mit Unterverzeichnissen), dass in die Anweisung eingefügt ist, eine bestimmte Operation aus. Die auszuführende Anweisung wird in geschweifte Klammern nach dem Parameter –process angegeben.

Ordner auf ein Netzshare kopieren

“move-item” soll in diesem Beispiel nicht mit einem fest angegebenen Pfad verwendet werden, sondern der Quellpfad wird aus den Eigenschaften von „get-member“ genommen (in diesem fall .FullName).

Eine Warnung: Damit das folgende Skript funktionieren kann, muss der Inhalt von $junkall die neuen Namen enthalten. Ansonsten erzeugt das Cmdlet einen Fehler, weil die in der Variable gespeicherten Ordner nicht mehr existieren.

$junkall | foreach-object -process {move-item -path $_.FullName -destination c:destjunk}Nun das gesamte Skript: $junkall=get-childitem c:junk | where {$_.psIsContainer -eq $true}$junkall | foreach-object -process {rename-item -path $_.fullname -newname „x86$_“}$junkall=get-childitem c:junk | where {$_.psIsContainer -eq $true}$junkall | foreach-object -process {move-item -path $_.FullName -destination c:destjunk}

(ID:2011450)