Auf einem File Server sammeln sich mitunter viele Dateien und Ordner, die sehr verzweigt sind. Dort die übersicht über alte und neue Daten zu halten ist mitunter schwierig. Das folgende Powershell Skript durchsucht rekursiv jeden Share auf dem Fileserver. Anschließend zeigt es mittels der Eigenschaft „LastWriteTime“ den jeweils neuesten Ordner an.

So ist es möglich eine Liste der Shares zu erhalten, sortiert nach Zugriffszeiten um das weitere Vorgehen zum Ordnen und gegebenenfalls löschen der Daten anzugehen. Im folgenden werde ich auf die einzelnen Bestandteile des Scripts eingehen, da es einige Besonderheiten gibt, auch im Bezug auf die Powershell.

Ein Problem, mit welchem ich zu kämpfen hatte war, dass sich der FileServer noch auf Windows Server 2003 befindet, und dort ledglich Powershell 1.0 vorhanden ist. Diverse Befehle, sowie sinnvolle Erweiterungen aus den Powershells nach Version 1.0 standen somit nicht zur Verfügung. Bald fidnet eine Migration auf Microsofts Windows Server 2012 statt, sodass dort mit der neuen Powershell gearbeitet werden kann.

Benötigte Variablen definieren und Ausgabe Ordner erstellen

Liste aller Shares ausgeben

Die Where-Bedingung schließt die Administrativen Laufwerk Shares wie C$, D$ etc. aus. Ebenso werden sämtliche Shares auf C:\ und das IPC$ Share ausgeschlossen. Die Anzahl der Shares wird schließlich noch gezählt, um nachher einen Fortschrittsbalken anzeigen zu können.

Definieren von Variablen für pro Sharedurchlauf

Jetzt wird es etwas kompliziert. Für jeden Share werden die Variablen vordefiniert. $newest_date ist in diesem Fall das maximal älteste Datum. Das genaue Datum spielt dabei keine Rolle, ich habe mich für das Jahr 2000 entschieden, 14 Jahre in der Vergangenheit. Dieses Datum wird als Standarddatum für jedes Objekt gesetzt.

Erstellung eines Fortschrittsbalken

Da das rekursive durchsuchen mitunter sehr lange dauert, habe ich einen Fortschrittsbalken eingbaut. Dieser zeigt die momentane Position der Suche an.

Die eigentliche Suche

Die Suche beginnt mit der Suche nach dem neuesten Ordner. Die Pipe zu ?{$_.PSIsContainer} sorgt dafür, dass nur Ordnerobjekte, und keine Dateien gelistet werden. Dies musste geschehen, da sonst die Speicherbelastung extrem hochgefahren wurde. So verbraucht das Script nach kurzer Zeit über 900MB Arbeitsspeicher auf dem Fileserver. Nachdem nurnoch Ordnern verwendet wurden, erreichte das Script eine maximale Auslastung von 100MB. Jedes Ordnerobjekt wird nun mit dem momentanen Inhalt von $newest_date verglichen. Ist das Datum neuer, so erhält $newest_date das neuere Datum und der Pfad des Ordners wird eingetragen.

Suche nach Dateien

Hat ein Share keine Unterordner, so würde das Script keine Daten eintragen. Daher werden, falls keine Unterordner im Share vorhanden sind, die Dateien im Share durchsucht. Für die Dateien wird dann derselbe Prozess durchlaufen, wie vorher für die Ordner.

Daten für ein leeres Share finden

Unter Umständen gibt es weder Dateien noch Unterordner in einem Share. Der Gedanke, dass dieser Share einfach gelöscht werden kann ist allerdings trügerisch. Schreibt beispielsweise ein Programm seine temporären Dateien in den Share und räumt diese zeitnah wieder auf, so ist der Share trotzdem notwendig und hat vor allem ein neues „LastWriteTime“ Datum. Daher findet auch hier eine Überprüfung auf dem Share-Root-Ordner statt.

Speichern der Daten

Nach jedem Share werden nun der Name des aktuellen Shares, der Pfad zur neuesten Datei bzw. Ordner und das letzte Schreibdatum in einem Objekt gespeichert.

Fehlerbehandlung

Bei der Funktionsweise dieses Scriptes können 2 verschiedene Fehler auftreten. Zum einen werden keine Daten geliefert, wenn die Berechtigungen nicht ausreichen den Pfad zu durchsuchen. Bei einem Access Denied bleibt die Spalte mit der LastWriteTime leer. Zum anderen kann Powershell nicht mehr als 260 Zeichen im Dateinamen verarbeiten. Diese „Path too long Exceptions“ werden ebenfalls im Errorlog abgespeichert. Der Durchlauf des Scripts wird dadurch nicht behindert, höchstens für den jeweiligen Share ein wenig ungenauer. Im Zweifelsfall muss man durch genau diese Ordner manuell überprüfen.

Ausgabe der Daten

Das Script gibt nun die Daten der Suche und das Error-Log aus. Die Daten sind dabei im (deutschen) csv Format hinterlegt, mit „;“ als Trennzeichen und nicht mit „,“. Der Parameter „-Encoding UTF8“ erlaubt die Anzeige von Umlauten im Dateinamen oder Pfad. Desweiteren werden die doppelten Anführungszeichen der Elemente entfernt.

Ausgabe von Laufzeitinformationen

Zum Schluss gibt das Script in der Powershell Console noch Informationen zur Laufzeit des Scripts aus. So wird die insgesamt verbrauchte Zeit sowie die maximale Arbeitsspeichernutzung in MB ausgegeben. Die CPU habe ich nicht mit ausgegeben, da sie maximal einen Kern verwendet. Bei einem aktuellen 4-Kern-System also nicht mehr als 25%

Hier nochmal das komplette Script mit Kommentaren:

banner