Вопрос

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

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

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

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

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

Это было полезно?

Решение

Remove-Item -Recurse -Force some_dir

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

rm -r -fo some_dir

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

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

Другие советы

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

rm -r folderToDelete

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

При рекурсивном удалении файлов с использованием простого 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
rm -r ./folder -Force    

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

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

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

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

rd /s <dir>

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

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

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

Я выбрал другой подход, вдохновленный описанным выше @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

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

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

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

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

ls -r .* | rm

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

Удаление всего дерева папок иногда работает, а иногда завершается сбоем с ошибками "Каталог не пуст".Последующая попытка проверить, существует ли папка по-прежнему, может привести к ошибкам "Доступ запрещен" или "Несанкционированный доступ".Я не знаю, почему это происходит, хотя некоторое представление можно получить из эта публикация StackOverflow.

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

# 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 дважды - в идеале с паузой между ними (т.е.используя пинг-понг как показано ниже).

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

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

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

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

del <dir> -Recurse -Force # I prefer this, short & sweet

или

remove-item <dir> -Recurse -Force

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

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

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

$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"
}

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

rm -r <folder_name>
c:\>rm -r "my photos"
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top