Как рекурсивно удалить весь каталог с помощью 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 и вставьте его в Удалить-Пункт, но примеры обычно удаляют некоторый набор файлов на основе фильтра, а не весь каталог.

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

16 ответов


Remove-Item -Recurse -Force some_dir

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

rm -r -fo some_dir

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

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


Я:

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 параметр, так как это имеет больше шансов работать для поставщиков, отличных от файловой системы. The -Include параметр-это просто удобство, если вы хотите отфильтровать элементы для удаления.

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

Get-Tree some_dir | select fullname

rm -r ./folder -Force    

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


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

rd /s <dir>

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

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

чтобы избежать ошибок" каталог не пуст " принятого ответа, просто используйте старую добрую команду 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, вот еще одна gotchya, которая может ударить вас:https://superuser.com/q/212808


очень просто:

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

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

Если вы найдете много файлов с тем же или подобным именем (например, Mac-файл с именем префикса точки... этот знаменитый файл 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 гарантирует, что интерактивные подсказки отключены.


использование PowerShell commnads для удаления всех файлов и папок

Удалить-Элемент-Путь "C:\dotnet-helpers*.* "- recurse

Recurse сверлит и находит много больше файлов. Этот ... --7-->параметр recurse позволит PowerShell удалять любые дочерние элементы без запроса разрешения.Кроме того, параметр-force можно добавить для удаления скрытых или доступных только для чтения файлов.

используя -сила команды мы можем удалить файлы сила полностью

использование PowerShell commnads для полного удаления всех файлов

Удалить-Элемент-Путь "C:\dotnet-helpers*.* "- Force

С Примером: http://dotnet-helpers.com/powershell-demo/how-to-delete-a-folder-or-file-using-powershell/


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

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