Как рекурсивно удалить весь каталог с помощью PowerShell 2.0?

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

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

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

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

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

Ответ 1

Remove-Item -Recurse -Force some_dir

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

rm -r -fo some_dir

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

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

Ответ 2

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

rm -r folderToDelete

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

Ответ 3

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

Ответ 4

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

rd /s <dir>

Ответ 5

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

remove-item -path "c:\Test Temp\Test Folder" -Force -Recurse -ErrorAction SilentlyContinue

Ответ 6

rm -r ./folder -Force    

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

Ответ 7

Почему-то ответ Джона Риса иногда не срабатывал в моем случае. Но это привело меня в следующем направлении. Сначала я пытаюсь удалить каталог рекурсивно с помощью параметра buggy -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
        }
    }
}

Ответ 8

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

& cmd.exe /c rd /S /Q $folderToDelete

Ответ 9

Еще один полезный трюк:

Если вы найдете много файлов с таким же или похожим соглашением имен (например, файл с именем префикса с точками... это известный файл pulltion), вы можете легко удалить их с помощью одной строки из командной строки, например:

ls -r .* | rm

В этой строке будут удалены все файлы с точкой в ​​начале имени внутри текущего каталога и все файлы с одинаковыми обстоятельствами внутри других папок внутри этого каталога. Имейте это в виду при использовании.: D

Ответ 10

Я принял еще один подход, вдохновленный @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

Ответ 11

Действительно просто:

remove-item -path <type in file or directory name>, press Enter

Ответ 12

Удаление всего дерева папок иногда работает, а иногда с ошибкой "Directory not empty". Впоследствии попытка проверить, сохраняется ли папка, может привести к ошибкам "Отказано в доступе" или "Несанкционированный доступ". Я не знаю, почему это происходит, хотя можно получить некоторую информацию из fooobar.com/questions/36127/....

Мне удалось обойти эти проблемы, указав порядок, в котором элементы в папке удалены, и добавив задержки. Следующие строки хорошо подходят для меня:

# First remove any files in the folder tree
Get-ChildItem -LiteralPath $FolderToDelete -Recurse -Force | Where-Object { -not ($_.psiscontainer) } | Remove-Item –Force

# Then remove any sub-folders (deepest ones first).    The -Recurse switch may be needed despite the deepest items being deleted first.
ForEach ($Subfolder in Get-ChildItem -LiteralPath $FolderToDelete -Recurse -Force | Select-Object FullName, @{Name="Depth";Expression={($_.FullName -split "\\").Count}} | Sort-Object -Property @{Expression="Depth";Descending=$true}) { Remove-Item -LiteralPath $Subfolder.FullName -Recurse -Force }

# Then remove the folder itself.  The -Recurse switch is sometimes needed despite the previous statements.
Remove-Item -LiteralPath $FolderToDelete -Recurse -Force

# Finally, give Windows some time to finish deleting the folder (try not to hurl)
Start-Sleep -Seconds 4

Статья Microsoft TechNet Использование вычисляемых свойств в PowerShell помогла мне в получении списка подпапок, отсортированных по глубине.

Аналогичные проблемы с безопасностью с RD/S/Q можно решить, дважды нажав RD/S/Q - в идеале с паузой между ними (т.е. используя ping, как показано ниже).

RD /S /Q "C:\Some\Folder\to\Delete" > nul
if exist "C:\Some\Folder\to\Delete"  ping -4 -n 4 127.0.0.1 > nul
if exist "C:\Some\Folder\to\Delete"  RD /S /Q "C:\Some\Folder\to\Delete" > nul

Ответ 13

Чтобы удалить полное содержимое, включая структуру папок, используйте

get-childitem $dest -recurse | foreach ($_) {remove-item $_.fullname -recurse}

-recurse, добавленный в remove-item, отключает интерактивные подсказки.

Ответ 14

$users = get-childitem \\ServerName\c$\users\ | select -ExpandProperty name

foreach ($user in $users)

{
remove-item -path "\\Servername\c$\Users\$user\AppData\Local\Microsoft\Office365\PowerShell\*" -Force -Recurse
Write-Warning "$user Cleaned"
}

Написал выше, чтобы очистить некоторые файлы журналов, не удаляя родительский каталог, и это отлично работает!