Question

Quelle est la façon la plus simple de supprimer avec force un répertoire et tous ses sous-répertoires dans PowerShell? J'utilise PowerShell V2 dans Windows 7.

Je l'ai appris de plusieurs sources que la commande la plus évidente, Remove-Item $targetDir -Recurse -Force, ne fonctionne pas correctement. Cela inclut une déclaration dans l'aide en ligne PowerShell V2 (trouvé en utilisant Get-Help Remove-Item -Examples) qui indique:

  

... Parce que le paramètre Recurse dans cette applet de commande est défectueuse, la commande utilise la commande Get-Childitem cmdlet pour obtenir les fichiers désirés, et il utilise pour les transmettre à l'opérateur de pipeline à l'applet de commande Remove-Item ...

Je l'ai vu plusieurs exemples qui utilisent Get-ChildItem et le tuyau à Remove-Item , mais les exemples supprimer généralement un ensemble de fichiers basé sur un filtre, non le répertoire entier.

Je cherche la façon la plus propre à souffler un répertoire entier, les fichiers et les répertoires enfants, sans générer des messages d'avertissement de l'utilisateur en utilisant le moins de code. serait bien en une ligne si elle est facile à comprendre.

Était-ce utile?

La solution

Remove-Item -Recurse -Force some_dir

ne fonctionne en effet comme annoncé ici.

rm -r -fo some_dir

sont des alias sténographie qui fonctionnent aussi.

Pour autant que je compris, le paramètre -Recurse ne fonctionne tout simplement lorsque vous essayez fonctionne pas correctement la suppression d'un ensemble filtré de fichiers récursive. Pour tuer un seul répertoire et tout en dessous semble fonctionner très bien.

Autres conseils

je:

rm -r folderToDelete

Cela fonctionne pour moi comme un charme (je l'ai volé de Ubuntu).

Lors de la suppression des fichiers en utilisant récursive simple Remove-Item "folder" -Recurse je vois parfois une erreur intermittente: [folder] cannot be removed because it is not empty.

Cette réponse tente d'éviter cette erreur en supprimant individuellement les fichiers.

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

Un détail important est le tri de tous les éléments avec pspath -Descending afin que les feuilles sont effacées avant que les racines. Le tri se fait sur le paramètre pspath depuis qui a plus de chance de travailler pour les fournisseurs autres que le système de fichiers. Le paramètre -Include est juste une commodité si vous souhaitez filtrer les éléments à supprimer.

Il est divisé en deux fonctions que je trouve utile de voir ce que je suis sur le point de supprimer en exécutant

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

... travaillé pour moi

Essayez cet exemple. Si le répertoire n'existe pas, aucune erreur est soulevée. Vous devrez peut-être PowerShell v3.0.

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

Utilisez l'ancienne école commande DOS:

rd /s <dir>

Pour éviter le « Le répertoire est pas vide » erreurs de la réponse acceptée, il suffit d'utiliser la bonne vieille commande DOS comme suggéré précédemment. La syntaxe complète PS prêt à du copier-coller est:

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

Pour une raison quelconque la réponse de John Rees parfois ne fonctionnait pas dans mon cas. Mais il m'a conduit dans la direction suivante. D'abord, je tente de supprimer le répertoire récursive avec l'option poussette récursif. Plus tard, je descends dans tous les subdir qui reste et supprimer tous les fichiers.

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

Je pris une autre approche inspirée par @ john-rees ci-dessus - surtout quand son approche a commencé à échouer pour moi à un moment donné. En fait récursif la sous-arborescence et trier les fichiers par leur chemin longueur - supprimer de la plus longue à la plus courte

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

En ce qui concerne la magie de -LiteralPath, voici une autre gotchya qui peuvent vous frapper: https://superuser.com/q/212808

Vraiment simple:

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

Une autre astuce utile:

Si vous trouvez un grand nombre de fichiers avec convention de nom identique ou similaire (comme fichier mac avec le nom du préfixe dot ... qui célèbre pulltion de fichier), vous pouvez facilement les enlever avec une seule ligne de la Powershell comme ceci:

ls -r .* | rm

Cette ligne va supprimer tous les fichiers avec un point au début du nom dans le répertoire courant, et tous les fichiers ayant les mêmes circonstances à l'intérieur d'autres dossiers dans ce répertoire aussi. Sachez à ce sujet lors de son utilisation. : D

Suppression d'un arbre de dossier complet fonctionne parfois et échoue parfois avec des erreurs « Répertoire non vide ». Par la suite tenter de vérifier si le dossier existe toujours peut entraîner des erreurs « Accès refusé » ou « accès non autorisé ». Je ne sais pas pourquoi cela se produit, si une idée peut tirer de ce StackOverflow affichage .

Je suis en mesure de contourner ces problèmes en spécifiant l'ordre dans lequel les éléments contenus dans le dossier sont supprimés, et en ajoutant des retards. Ce qui suit fonctionne bien pour moi:

# 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

Un article Microsoft TechNet Utilisation des propriétés dans Calculée PowerShell utile me à obtenir une liste des sous-dossiers classés par profondeur.

problèmes de fiabilité similaires avec RD / S / Q peut être résolu en exécutant RD / S / Q deux fois - idéalement avec une pause entre les deux (par exemple en utilisant ping comme indiqué ci-dessous).

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

Pour supprimer le contenu complet, y compris la structure dossier utilisation

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

Le -recurse ajouté à remove-item assure des invites interactives sont désactivées.

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

ou

remove-item <dir> -Recurse -Force

Si vous avez un répertoire énorme alors ce que je fais habituellement est

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

Exécuter ce sur un autre terminal et Powershell s'arrête quand il est fait.

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

A écrit ci-dessus pour nettoyer certains fichiers journaux sans supprimer le répertoire parent et cela fonctionne parfaitement!

rm -r <folder_name>
c:\>rm -r "my photos"
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top