Zum Inhaltsverzeichnis Das Filesystem

---------------------------------------------------------------------------------------

 

0 Einleitung

Zu den Objekten im Filesystem unter Windows gehören in erster Linie Dateien, Ordner, Freigaben, Pfade und Laufwerke. Mit deren cmdlets und .Net-Klassen werden wir uns in diesem Kapitel hauptsächlich beschäftigen.

Mittels Powershellskript kann man diese Objekte erstellen, deren Inhalte auslesen und verändern, umbenennen, verschieben, löschen, filtern, Eigenschaften wie Größe und Zugriffsberechtigungen bestimmen und viele andere Dinge mehr.

Im Powershellwerkzeugkasten liegen neben den cmdlets und vielen .Net-Klassen weitere Werkzeuge wie WMI-Klassen, dem COM-Objekt "Filesystemobjekt", sowie jahrelang bewährte Tools wie robocopy oder xcopy bereit.

Kombiniert man diese drei Komponenten (Objekttypen, Methoden und Eigenschaften, Werkzeuge) ,  so ergibt sich unter dem Kapitel "Filesystem" eine wiedermal riesengroße Vielfalt an Themen und Lösungsmöglichkeiten.
Dennoch will ich versuchen, einige aus meiner Sicht wichtige Themen anzugehen.


Ich stelle gleich zu Beginn einige Funktionen und Skripte vor, mit denen man auf einem Verzeichnis seiner Wahl Ordner und Dateien als Testumgebung erstellen kann. Die ersten beiden Beispiele sind etwas umfangreicher, die restlichen Beispiel dafür einfacher.


Beispiel 1: Erzeugen einer Ordnerstruktur mit leeren und zufällig gefüllten Dateien

Function get-alphanumericRandom{
   param($digits=8,[string]$flag='111', $SpaceFrequency=4,[boolean]$LineFeed=$false)
   $RandomPool=$null

   $flag=[Convert]::ToInt32($flag, 2)

   $min_lower=[int][char]'a' #97
   $max_lower=[int][char]'z' #122

   $min_upper=[int][char]'A'  #65
   $max_upper=[int][char]'Z'  #90

   $min_number=[int][char]'0' #48
   $max_number=[int][char]'9' #57

   $space =[int][char]' ' #32

   if($flag -band 1){
     $randompool=[char[]]($min_lower..$max_lower)
   }
 
   if($flag -band 2){
     $randompool+=[char[]]($min_upper..$max_upper)
   }
 
   if($flag -band 4){
     $randompool+=[char[]]($min_number..$max_Number)
     }

   if($flag -band 8){
     for($i=1;$i -le $spaceFrequency;$i++){
       $randompool +=" "
     } #for
   }
 
 
   #Benutzerdefinierte zusätzliche Zeichenketten
   for($i=1;$i -le 3;$i++){
       $randompool +="Karl"
   }
   for($i=1;$i -le 2;$i++){
       #if($linebreak){$randompool +="`n"} #Zeilenumbruch
       if($linefeed){$randompool +=[Environment]::NewLine}
     }

  $ofs = ''

  [string](get-random -input $randompool -count $digits)
}#function Ende

#durchnummerierte Filenamen

function leereFiles_mit_nummeriertenFilenamen{
param($filename="File",$extension="log",$number=2)
get-childitem $path | foreach {
   for ($i=1;$i -le $number;$i++){
   [string]$j="{0:000}" -f $i
   new-item -type "file" -path "$path\$_" -name "file$j.$extension" -force
   }
   }
}

function leereFiles_mit_zufaelligen_Filenamen{
  param($extension="log",$number=2)
  get-childitem $path | foreach {
     for ($i=1;$i -le $number;$i++){
       $filename=get-AlphanumericRandom -digits 6 -flag 0111 -SpaceFrequency 5
       new-item -type "file" -path "$path\$_" -name "$filename.$extension" -force
      } #for
   } #foreach
} #function

function FilesMitInhalt_zufaelligerFilename{
   param($extension="log",$NumberFiles=2,[int32]$NumberLines=5)
   get-childitem $path | foreach {
      for ($i=1;$i -le $numberFiles;$i++){
       $filename=get-AlphanumericRandom -digits 6 -flag 0111
       new-item -type "file" -path "$path\$_" -name "$filename.$extension" -force
       out-file -filepath "$path\$_\$filename.$extension" -append -inputobject $(get-date) -width 80
         for($j=1;$j -le $NumberLines; $j++){
            $text=get-AlphanumericRandom -digits 80 -flag 1111 -SpaceFrequency 7 -Linefeed $true
             out-file -filepath "$path\$_\$filename.$extension" -append -inputobject $text -width 80 -encoding unicode
         } #for j
      } #for i
   } #foreach
}

function FilesMitInhalt_zufaelligerFilename_einigeTageAlt{
   param($extension="log",$NumberFiles=2,[int32]$NumberLines=5,$AlterInTagen=31)
   get-childitem $path | foreach {
      for ($i=1;$i -le $numberFiles;$i++){
       $filename=get-AlphanumericRandom -digits 6 -flag 0111
       new-item -type "file" -path "$path\$_" -name "$filename.$extension" -force
       out-file -filepath "$path\$_\$filename.$extension" -append -inputobject $(get-date) -width 80
         for($j=1;$j -le $NumberLines; $j++){
            $text=get-AlphanumericRandom -digits 80 -flag 1111 -SpaceFrequency 7 -Linefeed $true
             out-file -filepath "$path\$_\$filename.$extension" -append -inputobject $text -width 80 -encoding unicode
         } #for j
        $(get-item "$path\$_\$filename.$extension").creationtime = ([datetime]::now).adddays(-$AlterInTagen)
        $(get-item "$path\$_\$filename.$extension").LastWriteTime = ([datetime]::now).adddays(-$AlterInTagen)
        $(get-item "$path\$_\$filename.$extension").LastAccessTime = ([datetime]::now).adddays(-$AlterInTagen)
     } #for i
   } #foreach
}

function CreateFolders{
  param($foldername="HomeUser", $number=5)
  for ($i=1;$i -le $number;$i++){
    [string]$j="{0:000}" -f $i
    new-item -type directory -path $path -name "$foldername$j" -force
  }
}

#### Ab hier kann das Skript über Funktionsparameter angepasst werden ####


$path="C:\temp\Homes" #wird -falls nicht vorhanden- automatisch angelegt
#unter diesem Pfad wird die Testumgebung angelegt

Createfolders -number 5  #number: Anzahl der Subfolder unter $path
leereFiles_mit_zufaelligen_Filenamen -number 2 -extension "nul"
leereFiles_mit_nummeriertenFilenamen -extension "ps1" -number 2
FilesMitInhalt_zufaelligerFilename -extension "txt" -NumberFiles 5 -NumberLines 30
FilesMitInhalt_zufaelligerFilename_einigeTageAlt -extension "txt" -NumberFiles 5 -NumberLines 3 -Alter 34
FilesMitInhalt_zufaelligerFilename_einigeTageAlt -extension "txt" -NumberFiles 5 -NumberLines 3 -Alter 733

Anleitung:
- Das Skript legt das Verzeichnis "C:\temp\homes" an und darunter 10 Unterordner. In diese Unterordner werden einige leere und gefüllte Textdateien mit verschiedenen Dateinamen, sowie teils mit Creation- und LastWritetimes älter als 33 Tagen und 732 Tagen geschrieben. Im unteren Teil des Skripts -nach den Funktionen- kann man das gewünschte Ergebnis recht einfach anpassen.

Erklärung:
- Die aufwändigste Funktion des Skripts ist "Function get-alphanumericRandom". Diese habe ich aus dem Kapitel Die Variablen -> 1.1.2 explizite Typzuweisung -> Beispiel 3 entnommen und dort auch erklärt. Die übrigen Funktionen sind nicht besonders spannend, daher spare ich mir deren Erklärung.


Beispiel 2: Erzeugung großer Textdateien

Function get-alphanumericRandom{
   param($digits=8,[string]$flag='111', $SpaceFrequency=4,[boolean]$LineFeed=$false)
   $RandomPool=$null

   $flag=[Convert]::ToInt32($flag, 2)

   $min_lower=[int][char]'a' #97
   $max_lower=[int][char]'z' #122

   $min_upper=[int][char]'A'  #65
   $max_upper=[int][char]'Z'  #90

   $min_number=[int][char]'0' #48
   $max_number=[int][char]'9' #57

   $space =[int][char]' ' #32

   if($flag -band 1){
     $randompool=[char[]]($min_lower..$max_lower)
   }
 
   if($flag -band 2){
     $randompool+=[char[]]($min_upper..$max_upper)
   }
 
   if($flag -band 4){
     $randompool+=[char[]]($min_number..$max_Number)
     }

   if($flag -band 8){
     for($i=1;$i -le $spaceFrequency;$i++){
       $randompool +=" "
     } #for
   }
 
 
   #Benutzerdefinierte zusätzliche Zeichenketten
   for($i=1;$i -le 1;$i++){
       $randompool +=" ErrorID:220 "
       $randompool +=" ErrorID:225 "
       $randompool +=" ErrorID:250 "
   }
   for($i=1;$i -le 2;$i++){
       #if($linebreak){$randompool +="`n"} #Zeilenumbruch
       if($linefeed){$randompool +=[Environment]::NewLine}
     }

  $ofs = ''

  [string](get-random -input $randompool -count $digits)
}#function Ende


function BigFile{
   param($extension="txt",$NumberFiles=1,[int32]$NumberLines=150,$filename="Big")
       new-item -type "file" -path "$path" -name "$filename.$extension" -force
       out-file -filepath "$path\$filename.$extension" -append -inputobject $(get-date) -width 80
         for($j=1;$j -le $NumberLines; $j++){
            $text=get-AlphanumericRandom -digits 80 -flag 1111 -SpaceFrequency 7 -Linefeed $false
            $text=$(get-date -format g)+ "   "+$text
             out-file -filepath "$path\$filename.$extension" -append -inputobject $text -width 80 -encoding unicode
       } #for j
     }
 
 $path="C:\temp"
 
 bigfile -numberLines 150 -Filename Big150        #ca. 25  Kb - Datei
 #bigfile -numberLines 1500 -Filename Big1500      #ca. 255 Kb - Datei
 #bigfile -numberLines 15000 -Filename Big15000    #ca. 2,5 Mb - Datei
 #bigfile -numberLines 150000 -Filename Big150000  #ca. 25  Mb - Datei , die Erzeugung dauert ein paar Minuten


 Anleitung:
Das Skript legt unter "C:\temp" Textdateien mit einer angegebenen Zahl von Zeilen an. Der Inhalt der Zeilen ist zufällig. Pfad und Anzahl der Zeilen können einfach im unteren Teil des Skripts -nach den Funktionen- angepasst werden.

Erklärung:
- Die aufwändigste Funktion des Skripts ist die Function "get-alphanumericRandom". Diese habe ich aus dem Kapitel Die Variablen -> 1.1.2 explizite Typzuweisung -> Beispiel 3 entnommen und dort auch erklärt. Die übrigen Funktionen sind nicht besonders spannend, daher spare ich mir deren Erklärung.


Oft genügen aber auch einfachere Strukturen, um Skripte ausprobieren zu können, wie in den Beispiel 3 und 4 gezeigt.

Beispiel 3: Erstellen von Übungsverzeichnissen

for ($i=1;$i -le 10;$i++){
   [string]$j="{0:000}" -f $i
   new-item -type directory -path c:\temp\homes -name "home$j"
   }

#Ausgabe gekürzt

    Directory: C:\temp\homes

Mode                LastWriteTime     Length Name      
----                -------------     ------ ----      
d----        14.09.2011     15:58            home001   
d----        14.09.2011     15:58            home002  


Beispiel 4: Erstellen von Übungsdateien

for ($i=1;$i -le 10;$i++){
   [string]$j="{0:000}" -f $i
   new-item -type "File" -path c:\temp\homes\home001 -name "file$j.txt" -value "This is a text string."
   }

#Ausgabe gekürzt  

         Directory: C:\temp\homes\home001

Mode                LastWriteTime     Length Name
----                -------------     ------ ----    
-a---        14.09.2011     15:39         22 file001.txt
-a---        14.09.2011     15:39         22 file002.txt