Pergunta

Qual é a maneira mais simples de excluir com força um diretório e todas as suas subdiretas 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 online do PowerShell v2 (encontrada usando Get-Help Remove-Item -Examples) que afirma:

... Porque 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 para o cmdlet Remove-Item ...

Eu já vi vários exemplos que usam Get-Childitem e puxar para Remover item, mas os exemplos geralmente removem algum conjunto de arquivos com base em um filtro, não no diretório inteiro.

Estou procurando a maneira mais limpa de explodir um diretório inteiro, arquivos e diretórios filhos, sem gerar mensagens de aviso de usuário usando a menor quantidade de código. Uma frase seria boa se for fácil de entender.

Foi útil?

Solução

Remove-Item -Recurse -Force some_dir

De fato, funciona como anunciado aqui.

rm -r -fo some_dir

são aliases abreviados que também funcionam.

Tanto quanto eu entendi, o -Recurse O parâmetro simplesmente não funciona corretamente quando você tenta excluir um conjunto filtrado de arquivos recursivamente. Por matar um único dir e tudo abaixo, parece funcionar bem.

Outras dicas

Eu usei:

rm -r folderToDelete

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

Ao excluir arquivos recursivamente usando um simples Remove-Item "folder" -Recurse Às vezes vejo um erro intermitente: [folder] cannot be removed because it is not empty.

Esta resposta tenta impedir esse erro excluindo individualmente os arquivos.

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

Um detalhe importante é a classificação de todos os itens com pspath -Descending para que as folhas sejam excluídas antes das raízes. A classificação é feita no pspath Parâmetro, pois isso tem mais chance de trabalhar para provedores que não sejam o sistema de arquivos. o -Include O parâmetro é apenas uma conveniência se você deseja filtrar os itens a serem excluídos.

É dividido em duas funções, pois acho útil ver o que estou prestes a excluir correndo

Get-Tree some_dir | select fullname
rm -r ./folder -Force    

... trabalhou para mim

Experimente este exemplo. Se o diretório não existir, nenhum erro será levantado. Você pode precisar de PowerShell v3.0.

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

Use o comando DOS da velha escola:

rd /s <dir>

Para evitar os erros "O diretório não está vazio" da resposta aceita, basta usar o bom comando antigo do DOS, conforme sugerido antes. A sintaxe PS completa pronta para a coleta é:

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

Por alguma razão, a resposta de John Rees às vezes não funcionava 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, descendo para todos os subdir que resta e exclua 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
        }
    }
}

Aproveitei outra abordagem inspirada em @John -Rees acima - especialmente quando sua abordagem começou a falhar para mim em algum momento. Basicamente recorrente a subárvore e classifique os arquivos por seu comprimento de caminho - exclua de mais longos para os mais curtos

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 atingindo você: https://superuser.com/q/212808

Muito simples:

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

Outro truque útil:

Se você encontrar muitos arquivos com a mesma convenção de nomes ou similar (como o arquivo MAC com o nome do prefixo de ponto ... aquela famosa puxão de arquivo), você pode removê -los facilmente com uma única linha do PowerShell como este:

ls -r .* | rm

Essa linha removerá todos os arquivos com um ponto no início do nome dentro do diretório atual e todos os arquivos com as mesmas circunstâncias em outras pastas dentro deste diretório também. Esteja ciente disso ao usá -lo. : D

Excluir uma árvore de pastas inteira às vezes funciona e às vezes falha com erros de "diretório não vazio". Posteriormente, tentar verificar se a pasta ainda existe pode resultar em erros de "acesso negado" ou "acesso não autorizado". Eu não sei por que isso acontece, embora algum insight possa ser obtido de Esta postagem de Stackoverflow.

Consegui contornar esses problemas especificando a ordem em que os itens da pasta são excluídos e adicionando atrasos. O seguinte é bom 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 da Microsoft Technet Usando propriedades calculadas Em Powershell, foi útil para mim para obter uma lista de sub-osdores classificados em profundidade.

Problemas de confiabilidade semelhantes com Rd /s /q pode ser resolvido correndo Rd /s /q duas vezes - idealmente com uma pausa intermediária (ou seja, usando 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

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

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

o -recurse Adicionado a remove-item Garante que os avisos interativos sejam desativados.

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

OU

remove-item <dir> -Recurse -Force

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

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

Execute isso em outro terminal do PowerShell e ele parará quando estiver pronto.

$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!

rm -r <folder_name>
c:\>rm -r "my photos"
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top