italianstallion 11 Geschrieben 30. Oktober 2014 Melden Teilen Geschrieben 30. Oktober 2014 Tach Skript Freunde, wollte heute mal ein neues Skript bauen, das mir diverse Verzeichnisse von bestimmten Dateien mit bestimmtem Alter löscht. Dazu habe ich immer erfolgreich forfiles eingesetzt. Das möchte ich auch weiterhin tun...da aber öfter mal Verzeichnisse hinzukommen, alte weg fallen usw. dachte ich an eine config Datei, die ungefähr so aussehen könnte: Pfad;DateiString;Alter %TMP%;*.TMP;15 E:\Backups;EigeneDateien;30 usw. ...um damit folgenden Befehl zu füllen: forfiles /P VARIABLE1 /s /m VARIABLE2 /d -VARIABLE3 /c “cmd /c del @file” Hab dabei an Powershell und vllt Get-Content gedacht? Bin aber überhaupt nicht sicher ob das der richtige Ansatz ist. Müsste dem Get-Content sagen er soll immer bis zum Semikolon lesen =VARIABLE1, bis zum nächsten Semikolon VARIABLE2, dann VARIABLE3. Nächste Zeile bedeutet nächster forfiles Befehl... Bin für jeden Hinweis dankbar... ItalianStallion Zitieren Link zu diesem Kommentar
Cybquest 36 Geschrieben 30. Oktober 2014 Melden Teilen Geschrieben 30. Oktober 2014 (bearbeitet) Hier'n PS-Ansatz: Import-Csv 'MeineConfig.csv' -delimiter ';' | ForEach-Object { # und hier nu die Variablen $_.Pfad, $_.DateiString und $_.Alter entspr. weiterverarbeiten... } ... allerdings würde ich das löschen dann auch gleich mit PS erledigen und nicht über forfiles und cmd... bearbeitet 30. Oktober 2014 von Cybquest Zitieren Link zu diesem Kommentar
italianstallion 11 Geschrieben 31. Oktober 2014 Autor Melden Teilen Geschrieben 31. Oktober 2014 Hi Frank, danke für den Ansatz. Da ich ForFiles direkt aus dem PS Skript aufrufen kann, konnte ich keinen Nachteil erkennen. Mit ForFiles wäre es in einer Zeile erledigt gewesen...ich versuch mein Glück. Was mir nicht klar ist an deinem Code Beispiel oben: - Muss ich das Löschen mit in die Schleife packen oder dort nur die Variablen füllen? und - Wie sage ich ihm, dass "$_.Pfad, $_.DateiString und $_.Alter" die Variablen genau so in genau dieser Reihenfolge zu verwenden sind? Wird das durch die Reihenfolge selbst vorgegeben? Bewege mich gerade das erste Mal jenseits von 1-5 zeiligen und einfachen Batches... Danke Zitieren Link zu diesem Kommentar
Cybquest 36 Geschrieben 31. Oktober 2014 Melden Teilen Geschrieben 31. Oktober 2014 Das Script liest die CSV-Datei ein und durchläuft diese Zeilenweise mittels foreach. Die erste Zeile wird dabei als Header hergenommen, d.h. so heissen dann auch die Variablen. Die baust Du dann einfach in Deinen forfiles-Befehl mit ein. Zur Frage: Ja, den Löschteil packst Du in die Schleife rein. Zitieren Link zu diesem Kommentar
italianstallion 11 Geschrieben 31. Oktober 2014 Autor Melden Teilen Geschrieben 31. Oktober 2014 Hi Frank, danke, das hatte ich mittlerweile aus diesem guten Artikel verstanden: http://www.admin-source.de/BlogDeu/963/import-csv-workshop Jetzt hab ich noch zwei Showstopper: 1. Innerhalb von ForFiles werden die Variablen nicht aufgelöst. Habe versucht sie mit '' oder "" zu maskieren, hilft aber nicht. forfiles /P $_.pfad /s /m $_.dateistring /d -$_.alter /c “cmd /c del @file” 2. Würd ich gern Systemvariablen verwenden, wie zB %TMP%...das bekomm ich auch nicht hin. Klar ist, dass ich in PS $env: verwenden muss. Ich würde ja auch in der config Datei schon was brauchbares eintragen wie $env:TMP oder $TMP...aber das wird alles nicht aufgelöst. Muss das speziell maskiert werden? Danke Zitieren Link zu diesem Kommentar
Dukel 455 Geschrieben 31. Oktober 2014 Melden Teilen Geschrieben 31. Oktober 2014 Versuche einmal: $($_.pfad) Ich würde trotzdem mit Powershell (das geht auch mit einem Einzeiler) die Dateien löschen. 1 Zitieren Link zu diesem Kommentar
italianstallion 11 Geschrieben 31. Oktober 2014 Autor Melden Teilen Geschrieben 31. Oktober 2014 Kinners...ich krich n Vogel gleich! Habs mit PS Mittel versucht...seit Stunden übrigens :confused: Mein Problem ist, dass Get-ChildItem $_.pfad -recurse $_.dateistring -force | where {$_.lastwritetime -lt (get-date).AddDays($_.alter)} | Remove-Item -Force ...immer alles löscht anstatt nur alles älter als $_.alter - In der ISE mit nem Breakpoint und Ausgabe der Variablen konnte ich sehen, dass alle drei Variablen korrekt geüllt sind - Der o.g. Befehl allein funktioniert auch ohne Variablen -> Ich denke mein Problem ist, dass $_.lastwritetime leer ist...aber warum?! Und weiter: Ich bekomm keinerlei Output aus der o.g. Zeile! Ist das normal? Weder Get-ChildItem noch Remove-Item erzeugt Ausgaben? Möchte später dann auch mal ein Log von meiner Löscherei... Habt ihr noch nen Tip? Oder gebt ihr auch gleich auf wie ich :cool: Gebs gleich an meinen Kollegen, der nen 5zeiler in Pearl draus machen soll... :D Dabei wollt ich das "winzige Ding" "mal eben kurz" in PS machen um den ersten Schritt weg von Pearl hin zu bekommen! :jau: Danke Zitieren Link zu diesem Kommentar
Cybquest 36 Geschrieben 31. Oktober 2014 Melden Teilen Geschrieben 31. Oktober 2014 (bearbeitet) Du meinst PERL, nicht Pearl, nehme ich an ;-) - Das $_ soll in der ForEach den aktüllen Datensatz repräsentieren. Wenn Du nun in das "where" reinpipest, repräsentiert das $_ dessen aktuellen Datensatz, d.h. "$_.alter" könnte hier'n Problem darstellen. Daher würde ich das vorher in ne andere Variable umspeichern - Das Alter muss bei AddDays als neg. Zahl angegeben werden - vor dem $_.DateiString fehlt m.E. das -filter Wenn Du das erste Mal mit PS scriptest und wg. so "Kleinigkeiten" gleich aufgeben willst, solltest Du es vermutlich wirklich "eben kurz" den Perl-Mann machen lassen ;-))) bearbeitet 31. Oktober 2014 von Cybquest Zitieren Link zu diesem Kommentar
italianstallion 11 Geschrieben 31. Oktober 2014 Autor Melden Teilen Geschrieben 31. Oktober 2014 (bearbeitet) 1. Natürlich Perl, nicht Pearl :p 2. Werde ich gleich noch testen 3. Das Alter negativ is klar 3. Never ever...der Perl-Mann soll in Rente gehn! :D - Keine Sorge, er steht neben mir und liest mit! :D Grüße Naja...so funktionierts erstmal: $datum = Get-Date -Format 'yyyyMMdd_HHmm' $log = "D:\SKRIPTE\LOGS\alte_daten_aufraeumen_$datum-$env:computername.log" Import-Csv 'D:\SKRIPTE\alte_daten_aufraeumen.cfg' -delimiter ';' | ForEach-Object { $_.pfad $_.dateistring $_.alter forfiles /P $($_.pfad) /s /m $($_.dateistring) /d -$($_.alter) /c “cmd /c del @file” } Ihr werdet mich vermutlich rügen, weil ichs nu doch mit forfiles gelöst hab, denn: Tataaaaaaaa...jetzt kann ich lein Log schreiben! :D Verdammt...mein Log bleibt leer wenn ich ein ">> $log 2>&1" anhänge egal ob ich es ins “cmd /c del @file” reinpacke oder dahinter schreibe... Grüße und eine schönes Wochenende! bearbeitet 31. Oktober 2014 von italianstallion Zitieren Link zu diesem Kommentar
Cybquest 36 Geschrieben 31. Oktober 2014 Melden Teilen Geschrieben 31. Oktober 2014 "von weitem" würde ich sagen, dass Du da ebenfalls $($log) verwenden müsstest... Zitieren Link zu diesem Kommentar
Dukel 455 Geschrieben 31. Oktober 2014 Melden Teilen Geschrieben 31. Oktober 2014 Ich würde im Foreach Block die Variablen extra deklarieren ($alter = $_.alter), dann kannst du diese Ohne Probleme (und ohne maskierung) nutzen Get-ChildItem $pfad -recurse $dateistring -force | where {$_.lastwritetime -lt (get-date).AddDays($alter)} | Remove-Item -Force 1 Zitieren Link zu diesem Kommentar
Cybquest 36 Geschrieben 31. Oktober 2014 Melden Teilen Geschrieben 31. Oktober 2014 Und wenn Du beim Remove-Item noch nen -Verbose hinhängst und in ne Logdatei schiebst..., :) Remove-Item -Force -Verbose 4>&1 | Out-File $log -append 1 Zitieren Link zu diesem Kommentar
italianstallion 11 Geschrieben 7. November 2014 Autor Melden Teilen Geschrieben 7. November 2014 Freunde! Ihr seid großartig! Da ich den Output mit ForFilesn icht hinbekommen hab, hab ichs mit den letzten Posts doch mit Powershell versucht und tatataaaaa...es läuft und tut was es soll! Inklusive sehr geilem Log! Musste nur ein -encoding ans out-file hängen! $datum = Get-Date -Format 'yyyyMMdd_HHmm' $logdatum = Get-Date -Format 'yyyy-MM-dd - HH:mm:ss' $log = "D:\SKRIPTE\LOGS\alte_daten_aufraeumen_$datum-$env:computername.log" $cfg = "D:\SKRIPTE\alte_daten_aufraeumen.cfg" write-LOG "Startzeit: $logdatum" write-LOG write-LOG "Config: $cfg" Import-Csv $cfg -delimiter ';' | ForEach-Object { $pfad = $_.pfad $dateistring = $_.dateistring $alter = $_.alter write-LOG "Zu durchsuchender Pfad: $pfad" write-LOG "Zu suchende Dateistrings: $dateistring" write-LOG "Dateien löschen, die älter sind als: $alter" Get-ChildItem $pfad -recurse $dateistring -force | where {$_.lastwritetime -lt (get-date).AddDays($alter)} | Remove-Item -Force -verbose 4>&1 | Out-File $log -encoding UTF8 -append } write-LOG write-LOG "Endzeit: $logdatum" ############################################################################### # Subroutinen # Sub Ausgabe in Logdatei Function write-LOG { Param ([string]$logstring) Add-content $log -value $logstring } ############################################################################### Jetzt wäre es noch wichtig Systemvariablen wie %TMP% in der Config verwenden zu können...das wird aber schwierig, oder? Das import-csv liest den String %TMP% nämlich als Text ein...ich müsste die CSV erst nach %***% durchsuchen und dann umsetzen á la $out3 = [System.Environment]::ExpandEnvironmentVariables("$line") Oder gibts nen einfacheren Tip? Für den Anfang auf jedenfall: SEHR SEHR GEIL! :jau: Danke an alle! 1 Zitieren Link zu diesem Kommentar
Cybquest 36 Geschrieben 7. November 2014 Melden Teilen Geschrieben 7. November 2014 Ne Möglichkeit wäre evtl. (ungetestet), im Script vorher alle möglichen Pfade in Variablen zu laden (z.B. $TempOrdner = [Environment]...) Und in die CSV-Datei dann statt %TMP%\Ordner $TempOrdner\Ordner schreiben. Zitieren Link zu diesem Kommentar
Empfohlene Beiträge
Schreibe einen Kommentar
Du kannst jetzt antworten und Dich später registrieren. Falls Du bereits ein Mitglied bist, logge Dich jetzt ein.