可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
What is the simplest way to forcefully delete a directory and all its subdirectories in PowerShell? I am using PowerShell V2 in Windows 7.
I have learned from several sources that the most obvious command, Remove-Item $targetDir -Recurse -Force
, does not work correctly. This includes a statement in the PowerShell V2 online help (found using Get-Help Remove-Item -Examples
) that states:
...Because the Recurse parameter in this cmdlet is faulty, the command uses the Get-Childitem cmdlet to get the desired files, and it uses the pipeline operator to pass them to the Remove-Item cmdlet...
I have seen various examples that use Get-ChildItem and pipe it to Remove-Item, but the examples usually remove some set of files based on a filter, not the entire directory.
I am looking for the cleanest way to blow out an entire directory, files and child directories, without generating any user warning messages using the least amount of code. A one-liner would be nice if it is easy to understand.
回答1:
Remove-Item -Recurse -Force some_dir
does indeed work as advertised here.
rm -r -fo some_dir
are shorthand aliases that work too.
As far as I understood it, the -Recurse
parameter just doesn't work correctly when you try deleting a filtered set of files recursively. For killing a single dir and everything below it seems to work fine.
回答2:
I used:
rm -r folderToDelete
This works for me like a charm (I stole it from Ubuntu).
回答3:
When deleting files recursively using a simple Remove-Item "folder" -Recurse
I sometimes see an intermittent error : [folder] cannot be removed because it is not empty.
This answer attempts to prevent that error by individually deleting the files.
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
An important detail is the sorting of all the items with pspath -Descending
so that the leaves are deleted before the roots. The sorting is done on the pspath
parameter since that has more chance of working for providers other than the file system. The -Include
parameter is just a convenience if you want to filter the items to delete.
It's split into two functions since I find it useful to see what I'm about to delete by running
Get-Tree some_dir | select fullname
回答4:
rm -r ./folder -Force
...worked for me
回答5:
Use the old-school DOS command:
rd /s <dir>
回答6:
Try this example. If the directory does not exist, no error is raised. You may need PowerShell v3.0.
remove-item -path "c:\Test Temp\Test Folder" -Force -Recurse -ErrorAction SilentlyContinue
回答7:
To avoid the "The directory is not empty" errors of the accepted answer, simply use the good old DOS command as suggested before. The full PS syntax ready for copy-pasting is:
& cmd.exe /c rd /S /Q $folderToDelete
回答8:
For some reason John Rees' answer sometimes did not work in my case. But it led me in the following direction.
First I try to delete the directory recursively with the buggy -recurse option. Afterwards I descend into every subdir that's left and delete all files.
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
}
}
}
回答9:
I took another approach inspired by @john-rees above - especially when his approach started to fail for me at some point. Basically recurse the subtree and sort files by their path-length - delete from longest to the shortest
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
Regarding the -LiteralPath magic, here's another gotchya that may be hitting you: https://superuser.com/q/212808
回答10:
Really simple:
remove-item -path <type in file or directory name>, press Enter
回答11:
Another useful trick:
If you find a lot of files with same or similar name convention (like mac file with dot prefix name... that famous file pulltion), you can easily remove them with one single line from the powershell like this:
ls -r .* | rm
This line is going to remove all files with a dot in the begining of the name inside the current directory, and all files with same circumstances inside other folders inside this directory too. Be aware about it when using it. :D
回答12:
Deleting an entire folder tree sometimes works and sometimes fails with "Directory not empty" errors. Subsequently attempting to check if the folder still exists can result in "Access Denied" or "Unauthorized Access" errors. I do not know why this happens, though some insight may be gained from this StackOverflow posting.
I have been able to get around these issues by specifying the order in which items within the folder are deleted, and by adding delays. The following runs well for me:
# 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
A Microsoft TechNet article Using Calculated Properties in PowerShell was helpful to me in getting a list of sub-folders sorted by depth.
Similar reliability issues with RD /S /Q can be solved by running RD /S /Q twice - ideally with a pause in between (i.e. using ping as shown below).
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
回答13:
To delete the complete contents including the folder structure use
get-childitem $dest -recurse | foreach ($_) {remove-item $_.fullname -recurse}
The -recurse
added to remove-item
ensures interactive prompts are disabled.
回答14:
del <dir> -Recurse -Force # I prefer this, short & sweet
OR
remove-item <dir> -Recurse -Force
If you have a huge directory then what I usually do is
while (dir | where name -match <dir>) {write-host deleting; sleep -s 3}
Run this on another powershell terminal and it will stop when it is done.
回答15:
$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"
}
Wrote the above to clean some logfiles without deleting the parent directory and this works perfectly!