Powershell: Alle SMB Ordner löschen unter 1MB

xXFiskXx

Lieutenant
Registriert
Nov. 2016
Beiträge
514
Hi,

ich suche ein Powershell oder CMD Script, mit dem ich auf meinem Netzlaufwerk alle Ordner löschen kann die unter 1MB groß sind. Bei Google findet man nur Scripte um Dateien zu löschen, aber keine Ordner.
 
Wenn es nur um Ordner in einer Ebene geht:
PowerShell:
$pfad = 'C:\Test'
$minimum = 1000000

$ordnerListe = Get-ChildItem -Path $pfad -Directory
foreach ($ordner in $ordnerListe) {
    $size = 0
    foreach ($datei in (Get-ChildItem -Path $ordner.Fullname -File -Recurse)) {
        $size += $datei.Length
        if ($size -gt $minimum) { break }
    }
    if ($size -lt $minimum) {
        Write-Host "Loesche $($ordner.Name) [$size]"
        # Remove-Item -Path $ordner.FullName -Force
    }
}
Ich habe den Löschbefehl erstmal auskommentiert damit du testen kannst ob nur die richtigen Ordner gelöscht werden.
Ganz oben beim $pfad und $minimum die gewünschten Werte eintragen.

Edit: kleine Optimierung von @nkler eingefügt (wenn Minimum überschritten direkt zum nächsten Ordner weiter). Macht es ggf. etwas schneller.
 
Zuletzt bearbeitet:
Ordner besitzen selber keine Größe, der Datenverbauch wird nur duch die Datein erzeugt.

Rechne doch die Größe aller Datein in einem Ordner zusammen (bei größer 1 MB kannst du stoppen und Unterordner beachten). Und wenn 1 MB nicht erreicht wird, dann kannst du alle Dateien löschen.
Anschließend einfach alle leeren Ordner löschen.
 
Wie soll das bei Unterordnern funktionieren?

Hast 5 Unterordner mit je 500kb, werden nicht gelöscht.
Der Ordner der die 5 Unterordner aber enthält ist ja 2,5MB groß, wird also gelöscht.

Wie soll das Script nun entscheiden?
 
Korben2206 schrieb:
Wenn es nur um Ordner in einer Ebene geht:
PowerShell:
$pfad = 'C:\Test'
$minimum = 1000000

$ordnerListe = Get-ChildItem -Path $pfad -Directory
foreach ($ordner in $ordnerListe) {
    $size = 0
    foreach ($datei in (Get-ChildItem -Path $ordner.Fullname -File -Recurse)) {
        $size += $datei.Length
        if ($size -gt $minimum) { break }
    }
    if ($size -lt $minimum) {
        Write-Host "Loesche $($ordner.Name) [$size]"
        # Remove-Item -Path $ordner.FullName -Force
    }
}
Auf meinen Internen Laufwerken funktioniert es schonmal. Bei meinem SMB Laufwerk bekomme ich allerdings immer den Fehler "kann nicht entfernt werden: Die Anforderung wird nicht unterstützt"

Benötigt Powerscript noch irgendwelche Schreibrechte? Über den Explorer lässt sich alles normal löschen
 
@leipziger1979: Genau andersrum, mit dem Löschen, aber ja, die Frage ist berechtigt.

Ich nehme an, es geht nur um Ordner auf einer Ebene?

@xXFiskXx: Es wird auch wirklich der Ordner und nicht die Freigabe selbst versucht zu löschen?
Also nicht \\Rechnername\Freigabe sondern \\Rechnername\Freigabe\Ordner

Und vielleicht wird das rekursive Löschen über SMB nicht unterstützt?

Ich meine, wenn du sagst, dass sich im Explorer alles normal löschen lässt, dann spricht es schon für richtige Ordner, und ich nehme an, dass es am rekursiven Löschen liegt.

Teste es doch mal mit einem leeren Ordner.
 
Code:
Loesche Test [0]
Remove-Item : Das Element \\192.168.178.40\NVIDIA_SHIELD\Test\Neu kann nicht entfernt werden: Die Anforderung wird nicht unterstützt.
In C:\PS.ps1:13 Zeichen:9
+         Remove-Item -Path $ordner.FullName -Force
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (Neu:DirectoryInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand

Der Fehler kommt immer.

Mit dem Explorer habe ich auch oft Probleme mit Ordnern über SMB. Nach dem kopieren auf das Netzlaufwerk kann ich die Ordner nicht löschen, erst nach einem Rechner Neustart.

Mit Dateien gibt es nie Probleme, nur mit Ordnern.
 
Versuch es Mal mit der Zeile:
Remove-Item -Path Filesystem::$ordner.FullName -Force

Der Parameter force kann sich je nach Datenprovider unterschiedlich verhalten. Alternativ Mal ohne -Force
 
Code:
$pfad = '\\192.168.178.40\Test'
$minimum = 1000000

$ordnerListe = Get-ChildItem -Path $pfad -Directory
foreach ($ordner in $ordnerListe) {
    $size = 0
    foreach ($datei in (Get-ChildItem -Path $ordner.Fullname -File -Recurse )) {
        $size += $datei.Length
        if ($size -gt $minimum) { break }
    }
    if ($size -lt $minimum) {
        Write-Host "Loesche $($ordner.Name) [$size]"
        Remove-Item -Path $ordner.FullName
    }
}

Danke!
Ohne -Force funktioniert es :D


Nur wie bekomme ich diese Meldung weg?
"Der Order verfügt über untergeordnete Elemente, und der Recurse-Parameter wurde nicht angegeben".

Nach Enter wird zwar alles gelöscht, aber wäre super wenn es auch unsichtbar funktionieren würde ohne Eingabe.
 
Korben2206 schrieb:
Glaube Remove-Item hat auch einen -Recurse Parameter. Evtl. hilft das.
rsfb schrieb:
Ja -Recurse wäre der passende Parameter dafür
-Recurse dranhängen hat funktioniert.

Falls es nicht zu aufwendig ist.
Kann man sich auch vor dem löschen die Ordner auflisten lassen die gelöscht werden sollen? So das man erst bestätigen muss.
 
nicht schön, sollte aber funktionieren. Du musst J drücken zum löschen, bei N springt er in den nächsten Ordner, andere Eingaben akzeptiert er nicht.

PowerShell:
$pfad = '\\192.168.178.40\Test'
$minimum = 1000000

$ordnerListe = Get-ChildItem -Path $pfad -Directory
foreach ($ordner in $ordnerListe) {
    $size = 0
    foreach ($datei in (Get-ChildItem -Path $ordner.Fullname -File -Recurse )) {
        $size += $datei.Length
        if ($size -gt $minimum) { break }
    }
    if ($size -lt $minimum) {
        $i = 0
        while ($i -eq 0)
        {
        $confirm = Read-Host "Soll $($ordner.Name) gelöscht werden? Tippe J für Ja, oder N für Nein"
        if ($confirm -eq "J")
            {
            Write-Host "Loesche $($ordner.Name) [$size]"
            Remove-Item -Path $ordner.FullName
            $i = 1
            }
        elseif ($confirm -eq "N")
            {
            Write-Host "Überspringe $($ordner.Name) [$size]"
            $i = 1
            }
        else
            {
            Write-Host "ungültige Eingabe"
            }
        }
}
 
PowerShell:
$pfad = '\\192.168.178.40\Test'
$minimum = 1000000

$ordnerListe = Get-ChildItem -Path $pfad -Directory
foreach ($ordner in $ordnerListe) {
    $size = 0
    foreach ($datei in (Get-ChildItem -Path $ordner.Fullname -File -Recurse )) {
        $size += $datei.Length
        if ($size -gt $minimum) { break }
    }
    if ($size -lt $minimum) {
        [Void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
        $DEL = [System.Windows.Forms.MessageBox]::Show("$($Ordner.Name):`n`nSollen die Ordner unwiederbringlich gelöscht werden?","Zu löschende Ordner!","YESNO","Question")
        If ($DEL -Eq "YES")
        {
            Write-Host "Loesche $($ordner.Name) [$size]"
            Remove-Item -Path $ordner.FullName
        }
        ElseIf ($DEL -Eq "NO")
        {
            Exit
        }
    }
}
 
@rsfb
Da kommt immer ein Fehler
  • foreach ($ordner in $ordnerListe) {
  • ~
Die schließende "}" fehlt im Anweisungsblock oder der Typdefinition.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEndCurlyBrace

@NotNerdNotDau
Das Funktioniert zwar, aber ich muss jeden Ordner einzeln mit J bestätigen.
Eine Auflistung aller Ordner die gelöscht werden sollen im Powershell Fenster wäre besser, so das ich nur einmal mit J bestätigen muss.

Wenn es zu aufwendig ist, lasse ich das erstmal so laufen ohne Auflistung. Solange ich den richtigen Pfad angebe, wird mir da denke ich nichts falsches gelöscht^^
 
xXFiskXx schrieb:
@rsfb
Da kommt immer ein Fehler
Der Fehler bei dem Code von rsfb kommt deshalb, weil dort die schließende geschweifte Klammer des zweiten foreach fehlt.

PowerShell:
        }
    }
}
xXFiskXx schrieb:
Das Funktioniert zwar, aber ich muss jeden Ordner einzeln mit J bestätigen.
Stimmt, die Meldung ist in der foreach-Schleife und wiederholt sich ständig.

Versuche es mal so:

PowerShell:
$pfad = '\\192.168.178.40\Test'
$minimum = 1000000

$ordnerListe = Get-ChildItem -Path $pfad -Directory
foreach ($ordner in $ordnerListe) {
    $size = 0
    foreach ($datei in (Get-ChildItem -Path $ordner.Fullname -File -Recurse )) {
        $size += $datei.Length
        if ($size -gt $minimum) { break }
    }
    if ($size -lt $minimum) {
        [Void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
        $DEL = [System.Windows.Forms.MessageBox]::Show("$($Ordner.Name):`n`nSollen die Ordner unwiederbringlich gelöscht werden?","Zu löschende Ordner!","YESNO","Question")
        If ($DEL -Eq "YES")
        {
            DelDir
            Return
        }
        ElseIf ($DEL -Eq "NO")
        {
            Exit
        }
    }
}
Function DelDir
{
    cls
    Write-Host "Loesche $($ordner.Name) [$size]"
    Remove-Item -Path $ordner.FullName
}
 
Zuletzt bearbeitet von einem Moderator:
@NotNerdNotDau
Da kommt leider auch für jeden Ordner eine einzelne lösch abfrage. Ich lasse das jetzt erstmal so laufen ohne Bestätigung.

Damit kein falscher Ordner gelöscht wird, kann ich ja -exclude nutzen, das funktioniert ganz gut.
 
Zurück
Oben