windows use Como excluir recursivamente um diretório inteiro com o PowerShell 2.0?




windows powershell remove file (13)

Tomei outra abordagem inspirada em @ john-rees acima - especialmente quando sua abordagem começou a falhar para mim em algum momento. Basicamente, recurse a subárvore e classifique os arquivos pelo comprimento do caminho - apague do mais longo para o mais curto

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

Em relação à magia -LiteralPath, aqui está outro gotchya que pode estar acertando você: https://superuser.com/q/212808

Qual é a maneira mais simples de excluir com força um diretório e todos os seus subdiretórios no PowerShell? Estou usando o PowerShell V2 no Windows 7.

Eu aprendi com várias fontes que o comando mais óbvio, Remove-Item $targetDir -Recurse -Force , não funciona corretamente. Isso inclui uma declaração na ajuda on-line do PowerShell V2 (encontrada usando Get-Help Remove-Item -Examples ) que declara:

... Como o parâmetro Recurse neste cmdlet está com defeito, o comando usa o cmdlet Get-Childitem para obter os arquivos desejados e usa o operador de pipeline para passá-los ao cmdlet Remove-Item ...

Eu vi vários exemplos que usam Get-ChildItem e canalizá-lo para Remove-Item , mas os exemplos geralmente removem alguns conjuntos de arquivos com base em um filtro, não no diretório inteiro.

Eu estou procurando a maneira mais limpa para soprar um diretório inteiro, arquivos e diretórios filho, sem gerar mensagens de aviso de usuário usando a menor quantidade de código. Um one-liner seria bom se fosse fácil de entender.


rm -r <folder_name>
c:\>rm -r "my photos"

Use o comando DOS da velha escola:

rd /s <dir>

Muito simples:

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

Tente este exemplo. Se o diretório não existir, nenhum erro será gerado. Você pode precisar do PowerShell v3.0.

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

Remove-Item -Recurse -Force some_dir

funciona de fato como anunciado aqui.

rm -r -fo some_dir

são aliases abreviados que funcionam também.

Tanto quanto eu entendi, o parâmetro -Recurse simplesmente não funciona corretamente quando você tenta excluir um conjunto filtrado de arquivos de forma recursiva. Para matar um único diretório e tudo abaixo, parece funcionar bem.


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

OU

remove-item <dir> -Recurse -Force

Se você tem um diretório enorme, então o que eu costumo fazer é

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

Execute isso em outro terminal PowerHell e ele será interrompido quando isso for feito.


Eu usei:

rm -r folderToDelete

Isso funciona para mim como um encanto (eu roubei do Ubuntu).


Por alguma razão, a resposta de John Rees às vezes não funcionou no meu caso. Mas isso me levou na seguinte direção. Primeiro tento excluir o diretório recursivamente com a opção buggy -recurse. Depois eu desço em cada subdir que resta e apago todos os arquivos.

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

Para excluir o conteúdo completo, incluindo a estrutura da pasta, use

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

O -recurse adicionado ao remove-item garante que os prompts interativos estejam desabilitados.


A exclusão de uma árvore de pastas inteira às vezes funciona e às vezes falha com erros "Diretório não vazio". Subseqüentemente, tentar verificar se a pasta ainda existe pode resultar em erros de "Acesso negado" ou "Acesso não autorizado". Eu não sei porque isso acontece, apesar de alguns insights podem ser obtidos a partir deste lançamento .

Consegui contornar esses problemas especificando a ordem em que os itens da pasta são excluídos e adicionando atrasos. O seguinte corre bem para mim:

# 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

Um artigo do Microsoft TechNet Usando Propriedades Calculadas no PowerShell foi útil para obter uma lista de subpastas classificadas por profundidade.

Problemas de confiabilidade similares com RD / S / Q podem ser resolvidos executando RD / S / Q duas vezes - idealmente com uma pausa no meio (ou seja, usando o ping como mostrado abaixo).

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

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

Escreveu o acima para limpar alguns arquivos de log sem excluir o diretório pai e isso funciona perfeitamente!


Para evitar que os erros "O diretório não está vazio" da resposta aceita, simplesmente use o bom e velho comando DOS como sugerido anteriormente. A sintaxe completa do PS pronta para copiar e colar é:

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




delete-directory