Frage Erzwingen Sie das Entfernen von Dateien und Verzeichnissen in PowerShell manchmal, aber nicht immer


Ich versuche ein Verzeichnis rekursiv mit zu löschen rm -Force -Recurse somedirectory, Bekomme ich mehrere "Das Verzeichnis ist nicht leer" -Fehler. Wenn ich wiederhole den gleichen Befehles gelingt.

Beispiel:

PS I:\Documents and Settings\m\My Documents\prg\net> rm -Force -Recurse .\FileHelpers
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers\FileHelpers.Tests\Data\RunTime\_svn: The directory is not empty.
At line:1 char:3
+ rm <<<<  -Force -Recurse .\FileHelpers
    + CategoryInfo          : WriteError: (_svn:DirectoryInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers\FileHelpers.Tests\Data\RunTime: The directory is not empty.
At line:1 char:3
+ rm <<<<  -Force -Recurse .\FileHelpers
    + CategoryInfo          : WriteError: (RunTime:DirectoryInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers\FileHelpers.Tests\Data: The directory is not empty.
At line:1 char:3
+ rm <<<<  -Force -Recurse .\FileHelpers
    + CategoryInfo          : WriteError: (Data:DirectoryInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers\FileHelpers.Tests: The directory is not empty.
At line:1 char:3
+ rm <<<<  -Force -Recurse .\FileHelpers
    + CategoryInfo          : WriteError: (FileHelpers.Tests:DirectoryInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers\Libs\nunit\_svn: The directory is not empty.
At line:1 char:3
+ rm <<<<  -Force -Recurse .\FileHelpers
    + CategoryInfo          : WriteError: (_svn:DirectoryInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers\Libs\nunit: The directory is not empty.
At line:1 char:3
+ rm <<<<  -Force -Recurse .\FileHelpers
    + CategoryInfo          : WriteError: (nunit:DirectoryInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers\Libs: The directory is not empty.
At line:1 char:3
+ rm <<<<  -Force -Recurse .\FileHelpers
    + CategoryInfo          : WriteError: (Libs:DirectoryInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers: The directory is not empty.
At line:1 char:3
+ rm <<<<  -Force -Recurse .\FileHelpers
    + CategoryInfo          : WriteError: (I:\Documents an...net\FileHelpers:DirectoryInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
PS I:\Documents and Settings\m\My Documents\prg\net> rm -Force -Recurse .\FileHelpers
PS I:\Documents and Settings\m\My Documents\prg\net>

Natürlich passiert das nicht immer. Es passiert auch nicht nur mit _svn Verzeichnisse, und ich habe keine SchildkröteSVN Cache oder irgendetwas ähnliches, so blockiert nichts das Verzeichnis.

Irgendwelche Ideen?


25
2017-11-09 15:42


Ursprung




Antworten:


help Remove-Item sagt:

Der Recurse-Parameter in diesem Cmdlet funktioniert nicht ordnungsgemäß.

und

Da der Recurse-Parameter in diesem Cmdlet fehlerhaft ist, verwendet der Befehl das Cmdlet Get-Childitem, um den Wunsch zu erhalten   d-Dateien und verwendet den Pipeline-Operator, um sie an das Cmdlet Remove-Item zu übergeben.

und schlägt diese Alternative als Beispiel vor:

get-childitem * -include *.csv -recurse | remove-item

Du solltest also pumpen get-childitem -recurse in remove-item.


28
2017-11-09 18:35



Vielen Dank. Habe diesen Thread von 2006 gefunden: vistax64.com/powershell/... sieht aus wie Microsoft ist nicht wirklich daran interessiert, dies zu beheben. - Mauricio Scheffer
@Mausch: Siehe diese neuere, aber immer noch ungelöste Referenz: Remove-Item -Recurse - Dennis Williamson
Wenn Sie eine Traversierung und Löschung durchführen, müssen Sie zuerst die untergeordneten Verzeichnisse und dann deren Dateien durchlaufen. - fschwiet
Zumindest sagt die Dokumentation, dass es nicht funktioniert. - derekerdmann
Ich musste beide -force-recurse-Flags für Remove-Item setzen, sonst hielt es mich auffordern "Bitte bestätigen Sie" Get-ChildItem -Path $ Destination -Recurse | Remove-Item -force -recurse - Michael Freidgeim


@JamesCW: Das Problem besteht immer noch in PowerShell 4.0

Ich habe einen anderen Workaround ausprobiert und es hat geklappt: benutze cmd.exe:

&cmd.exe /c rd /s /q $somedirectory

10
2017-09-10 06:59



Gute alte rd / s / q! - JamesCW
Ich habe jede Variation von Get-ChildItem ausprobiert; Wiederholungsschleifen; Berufung iisreset vor dem Löschen und nichts scheint zu funktionieren zuverlässig. Ich werde es versuchen, obwohl ich, als ich es zum ersten Mal gesehen habe, mich geweigert habe, DOS in meiner Powershell zu haben ... - Peter McEvoy


Die neue Version von PowerShell (PSVersion 4.0) hat dieses Problem vollständig gelöst und Remove-Item "targetdirectory" -Recurse -Force funktioniert ohne Timing-Probleme.

Sie können Ihre Version überprüfen, indem Sie ausführen $PSVersiontable aus dem ISE oder PowerShell Prompt. 4.0 ist die Version, mit der geliefert wird Windows 8.1 und Server 2012 R2und es kann auch auf früheren Versionen von Windows installiert werden.


6
2018-05-27 15:36



Tritt immer noch für mich in PowerShell 4.0 vor - ajbeaven
Immer noch in PowerShell v5 !!!!! 11 !! 1! 1 !!! - Richard Hauer
@RichardHauer nun, jetzt bin ich nur verwirrt - JamesCW
@JamesCW Ich habe in die konvertiert rd Ausführung. Abgesehen von der tatsächlichen Arbeit ist es etwa 3x schneller - Richard Hauer


Die aktuelle Antwort löscht ein Verzeichnis nicht wirklich, nur seine Kinder. Außerdem wird es Probleme mit verschachtelten Verzeichnissen geben, da es wieder versucht, ein Verzeichnis vor seinem Inhalt zu löschen. Ich habe etwas geschrieben, um die Dateien in der richtigen Reihenfolge zu löschen, würde immer noch das gleiche Problem haben, obwohl das Verzeichnis manchmal später immer noch da ist.

So, jetzt verwende ich etwas, das die Ausnahme abfangen, warten und wiederholen (3 Mal):

Fürs Erste benutze ich das:

function EmptyDirectory($directory = $(throw "Required parameter missing")) {

    if ((test-path $directory) -and -not (gi $directory | ? { $_.PSIsContainer })) {
        throw ("EmptyDirectory called on non-directory.");
    }

    $finished = $false;
    $attemptsLeft = 3;

    do {
        if (test-path $directory) {
            rm $directory -recurse -force
        }

        try {
            $null = mkdir $directory
            $finished = $true
        } 
        catch [System.IO.IOException] {
            Start-Sleep -Milliseconds 500
        }

        $attemptsLeft = $attemptsLeft - 1;
    } 
    while (-not $finished -and $attemptsLeft -gt 0)

    if (-not $finished) {
        throw ("Unable to clean and recreate directory " + $directory)
    }
}

3
2017-12-26 22:36



Das ist gut, aber ich hatte immer noch Probleme damit. Wenn der Befehl mkdir ausgeführt wird, bevor das System den Befehl rm abgeschlossen hat, kann er eine System.UnauthorizedAccessException mit einer FullyQualifiedErrorId von ItemExistsUnauthorizedAccessError auslösen. Das heißt, das Verzeichnis wurde noch nicht vom Betriebssystem gelöscht (auf meiner langsamen Festplatte). Also muss dieser Fehler auch abgefangen werden. Da es sich um einen nicht terminierenden Fehler handelt, muss die ErrorAction auf Stop gesetzt werden. Ich habe auch den Befehl rm in den try-Block gesetzt, nur in Fällen, in denen vorübergehende IO-Fehler beim Löschen auftreten. - Mark Lapierre
Ich kann nicht glauben, dass dies sogar getan werden muss. Verdammt, Powershell saugt! - jcollum


Das Löschen des Verzeichnisses und seines Inhalts erfolgt in zwei Schritten. Lösche zuerst den Inhalt und dann den Ordner selbst. Mit der Problemumgehung für das fehlerhafte rekursive Remove-Element würde die Lösung folgendermaßen aussehen:

Get-ChildItem -Path "$folder\\*" -Recurse | Remove-Item -Force -Recurse
Remove-Item $folder

Auf diese Weise können Sie auch das übergeordnete Verzeichnis entfernen.


3
2017-12-13 23:40



Dies ist genau das, was die angenommene Antwort gesagt hat. Hast du etwas hinzuzufügen? - Michael Hampton♦
Sie weisen darauf hin, dass die akzeptierte Antwort das Verzeichnis selbst nicht löscht, daher dauert es zwei Schritte. - Paul George
Das Remove-Item befehlen Sie Ihre Rohrleitungen in hat das gleiche Problem, das ursprünglich angegeben. Es stolpert möglicherweise auf ein Verzeichnis-Element, das auf die gleiche Weise nicht leer ist. - Dejan
@Dejan Dieses Verzeichnis konnte nicht immer leer sein, wenn die erste Zeile dieses Codes funktionierte, oder? - Ifedi Okonkwo


Das ist, woran ich arbeite:

$Target = "c:\folder_to_delete"

Get-ChildItem -Path $Target -Recurse -force |
  Where-Object { -not ($_.psiscontainer) } |
   Remove-Item –Force

Remove-Item -Recurse -Force $Target

Diese erste Zeile löscht alle Dateien in der Baumstruktur. Die zweite löscht alle Ordner einschließlich der oberen.


2
2017-09-30 21:20





Übernehmen Sie zuerst die Dateien / Verzeichnisse mit Takeown.exe und löschen Sie sie

https://learn-powershell.net/2014/06/24/change-ownership-of-file-or-folder-using-powershell/


0
2017-08-17 17:18