Как рекурсивно удалить весь каталог с PowerShell 2.0? - PullRequest
242 голосов
/ 18 ноября 2009

Какой самый простой способ принудительно удалить каталог и все его подкаталоги в PowerShell? Я использую PowerShell V2 в Windows 7.

Из нескольких источников я узнал, что наиболее очевидная команда Remove-Item $targetDir -Recurse -Force работает неправильно. Это включает в себя справку в онлайн-справке PowerShell V2 (с использованием Get-Help Remove-Item -Examples), в которой говорится:

... Поскольку параметр Recurse в этом командлете неисправен, команда использует командлет Get-Childitem для получения нужных файлов и использует оператор конвейера для передачи их в командлет Remove-Item ...

Я видел различные примеры, которые используют Get-ChildItem и передают его на Remove-Item , но примеры обычно удаляют некоторый набор файлов на основе фильтра, а не весь каталог.

Я ищу самый чистый способ уничтожить весь каталог, файлы и дочерние каталоги, не генерируя никаких предупреждений пользователя, используя наименьшее количество кода. Однострочник был бы хорош, если бы его было легко понять.

Ответы [ 16 ]

414 голосов
/ 18 ноября 2009
Remove-Item -Recurse -Force some_dir

действительно работает так, как здесь рекламируется.

rm -r -fo some_dir

это сокращенные псевдонимы, которые тоже работают.

Насколько я понял, параметр -Recurse просто не работает правильно, когда вы пытаетесь рекурсивно удалить отфильтрованный набор файлов. Кажется, что для убийства одного dir и всего, что находится ниже, все работает нормально.

36 голосов
/ 25 марта 2013

Я использовал:

rm -r folderToDelete

Это работает для меня как брелок (я украл его из Ubuntu).

20 голосов
/ 17 июля 2012

При рекурсивном удалении файлов с использованием простого Remove-Item "folder" -Recurse иногда я вижу периодически возникающую ошибку: [folder] cannot be removed because it is not empty.

Этот ответ пытается предотвратить эту ошибку путем индивидуального удаления файлов.

function Get-Tree($Path,$Include='*') { 
    @(Get-Item $Path -Include $Include -Force) + 
        (Get-ChildItem $Path -Recurse -Include $Include -Force) | 
        sort pspath -Descending -unique
} 

function Remove-Tree($Path,$Include='*') { 
    Get-Tree $Path $Include | Remove-Item -force -recurse
} 

Remove-Tree some_dir

Важной деталью является сортировка всех элементов с pspath -Descending, так что листья удаляются перед корнями. Сортировка выполняется по параметру pspath, поскольку у него больше шансов работать для поставщиков, отличных от файловой системы. Параметр -Include удобен, если вы хотите отфильтровать элементы для удаления.

Он разделен на две функции, так как я считаю полезным увидеть, что я собираюсь удалить, запустив

Get-Tree some_dir | select fullname
10 голосов
/ 30 ноября 2014

Попробуйте этот пример. Если каталог не существует, ошибка не возникает. Вам может понадобиться PowerShell v3.0.

remove-item -path "c:\Test Temp\Test Folder" -Force -Recurse -ErrorAction SilentlyContinue
9 голосов
/ 13 февраля 2015
rm -r ./folder -Force    

... работал для меня

8 голосов
/ 18 ноября 2009

Используйте команду старой школы DOS:

rd /s <dir>
6 голосов
/ 26 февраля 2016

Чтобы избежать ошибок «Каталог не пуст» принятого ответа, просто используйте старую добрую команду DOS, как предлагалось ранее. Полный синтаксис PS, готовый для вставки копии:

& cmd.exe /c rd /S /Q $folderToDelete
5 голосов
/ 16 июля 2015

Почему-то ответ Джона Риса иногда не работал в моем случае. Но это привело меня в следующем направлении. Сначала я пытаюсь рекурсивно удалить каталог с ошибкой -recurse. После этого я спускаюсь в каждый оставшийся подкаталог и удаляю все файлы.

function Remove-Tree($Path)
{ 
    Remove-Item $Path -force -Recurse -ErrorAction silentlycontinue

    if (Test-Path "$Path\" -ErrorAction silentlycontinue)
    {
        $folders = Get-ChildItem -Path $Path –Directory -Force
        ForEach ($folder in $folders)
        {
            Remove-Tree $folder.FullName
        }

        $files = Get-ChildItem -Path $Path -File -Force

        ForEach ($file in $files)
        {
            Remove-Item $file.FullName -force
        }

        if (Test-Path "$Path\" -ErrorAction silentlycontinue)
        {
            Remove-Item $Path -force
        }
    }
}
2 голосов
/ 02 августа 2016

Я выбрал другой подход, вдохновленный @ john-rees выше - особенно, когда его подход начал терпеть неудачу для меня в какой-то момент. В основном, рекурсивно проверяйте поддерево и сортируйте файлы по их длине пути - удаляйте от самого длинного до самого короткого

Get-ChildItem $tfsLocalPath -Recurse |  #Find all children
    Select-Object FullName,@{Name='PathLength';Expression={($_.FullName.Length)}} |  #Calculate the length of their path
    Sort-Object PathLength -Descending | #sort by path length descending
    %{ Get-Item -LiteralPath $_.FullName } | 
    Remove-Item -Force

Что касается магии -LiteralPath, вот еще одна ошибка, которая может ударить вас: https://superuser.com/q/212808

1 голос
/ 24 июля 2018
del <dir> -Recurse -Force # I prefer this, short & sweet

OR

remove-item <dir> -Recurse -Force

Если у вас огромный каталог, то я обычно делаю

while (dir | where name -match <dir>) {write-host deleting; sleep -s 3}

Запустите это на другом терминале PowerShell, и он остановится, когда это будет сделано.

...