如何使用PowerShell 2.0递归删除整个目录?


308

在PowerShell中强制删除目录及其所有子目录的最简单方法是什么?我在Windows 7中使用PowerShell V2。

我从几个来源了解到,最明显的命令Remove-Item $targetDir -Recurse -Force不能正常工作。这包括PowerShell V2联机帮助(使用找到Get-Help Remove-Item -Examples)中的一条语句,该语句指出:

...由于此cmdlet中的Recurse参数错误,因此该命令使用Get-Childitem cmdlet来获取所需的文件,并使用管道运算符将它们传递给Remove-Item cmdlet ...

我已经看到了使用Get-ChildItem并将其通过管道传递到Remove-Item的各种示例,但是这些示例通常会基于过滤器而不是整个目录除去一些文件集。

我正在寻找一种最干净的方法来删除整个目录,文件和子目录,而不用最少的代码生成任何用户警告消息。如果易于理解,单线将是很好的。


2
Powershell,我知道,但是RD /S /Q
Rubens Farias


我不认为这是重复的。发布前,我审查了1667145。询问为什么在调用自定义PowerShell提供程序的Remove-Item方法实现时PowerShell无法正确设置Recurse bool参数。我问的是Remove-Item行为,因为它与内置文件系统提供程序有关。
马特·斯普拉德利

2
“ RD / S / Q”在PowerShell中似乎不起作用-说“ Remove-Item:找不到一个接受参数'/ q'的位置参数。”
BrainSlugs83 2012年

5
rdRemove-Itempowershell中的别名。cmd /c "rd /s /q"虽然有效。
codekaizen

Answers:


510
Remove-Item -Recurse -Force some_dir

确实按此处的广告宣传工作。

rm -r -fo some_dir

是也可以使用的速记别名。

据我了解,-Recurse当您尝试递归删除一组过滤的文件时,该参数无法正常工作。对于杀死单个目录及其下的所有内容,似乎都可以正常工作。


5
我认为你是对的。我收到“由于正在使用中,无法在'某些目录'中删除该项目”。错误,并假定这是递归算法的问题,因此开始寻找解决方法。事实证明,我在目标目录中正在运行的脚本中有一个先前触发的过程。更改脚本以等待其他进程时,“删除项目-递归-强制”命令将起作用。总是先照镜子:)
Matt Spradley

15
我发现在包含子目录的目录上运行时,我需要运行两次。第一次,将出现很多“目录不为空”错误。第二次完成,没有错误。
克里斯托弗·约翰逊

5
克里斯托弗·约翰逊(Kristopher Johnson),在Windows 7上使用各种工具时,我也会遇到类似的错误。似乎删除调用返回的时间早于实际删除文件或文件夹的时间,有时会造成麻烦。这似乎发生在Explorer,Far,cmd和PowerShell中。
乔伊(Joey)

2
@Joey“似乎删除调用返回的时间比实际删除文件或文件夹的时间早,有时会引起麻烦。” ->为了澄清:父文件夹不会被删除,并且会出现以下错误:“ [父文件夹]不能删除,因为它不是空的。” 我看到这在(慢速)网络驱动器上不断发生。唯一的解决方案是旧的解决方案:cmd /c rd如下所述。
Davor Josipovic

6
关于“目录不为空”错误怎么办?serverfault.com/questions/199921/powershell-remove-force也许更好地get-childitem * -include * .csv -recurse | 我不知道删除项目。参见stackoverflow.com/a/1668471/206730
Kiquenet

39

我用了:

rm -r folderToDelete

这对我来说就像一个魅力(我从Ubuntu上偷了它)。


是否不需要cygwin,git或其他可以在Windows上模拟bash shell的工具?
皮特

19
@Pete,不,它只需要PowerShell。rmRemove-ItemPowerShell默认配置中的别名。检查输出以Get-Alias rm了解更多详细信息。这-r利用了PowerShell在参数上的部分匹配行为。由于Remove-Item只有一个参数,它与“R”开始,-Recurse-r匹配。因此,下面的一切都将工作一样:rm -rrm -reRemove-Item -Recurse。(请注意,既不行,rm -rf也不行rm -r -f,但rm -r -fo-rf不匹配任何参数,并且-f不止一个。)
chwarr 2014年

1
那个怎么样。与直接使用remove-item相比,“ Remove-Item -Recurse -Force some_dir”的Powershell rm别名工作得更好。我收到了相同的错误“无法在'某些目录'上删除该项目。我从remove-item切换到rm -r,没有任何错误!?
Greg

有趣。我的盒子上确实有cygwin工具,并且尝试过rm -rf folder,当然失败了。我最初不赞成这个答案(因为它说的是Ubuntu)。感谢@chwarr的评论,我尝试了不使用的尝试,f并且它选择了别名而不是rm二进制文件。我希望Tuan能够更新他的消息来源(不确定Tuan是否知道它是别名还是真的认为它是unix rm ;-)
Joshua Ball

2
也许是因为我使用-R而不是-r(尽管据我所知PowerShell就像Windows的其余部分一样不区分大小写,因此应该没有区别),但是我收到一个错误,我要删除的文件夹是不是空的。
rbaleksandar

25

使用简单的递归方式删除文件时,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参数上完成的,因为有更多的机会为文件系统以外的提供程序工作。-Include如果要过滤要删除的项目,此参数只是一个方便。

它分为两个功能,因为我发现通过运行查看要删除的内容很有用

Get-Tree some_dir | select fullname

1
在TFS构建脚本中使用PowerShell解决问题时,这被证明是正确的答案。
rcabr 2014年

这也是我的解决方案。给我点点好消息!
Jammer

为我工作。我无法递归删除文件夹内容,但是您的解决方案对我有用。谢谢
SheldonH '16

这是一个非常强大的解决方案
Max Young

我不确定为什么接受的答案这么多票-我个人仍然remove-item -recurse在Powershell v5中使用间歇性错误,因此该解决方案最适合我。
JonoB


11

试试这个例子。如果该目录不存在,则不会引发任何错误。您可能需要PowerShell v3.0。

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

7

使用老式的DOS命令:

rd /s <dir>

如果这是脚本的一部分,则也必须使用/q(安静模式,不要问是否可以使用/ S删除目录树)。
wildeyes

6

由于某些原因,John Rees的回答有时对我而言不起作用。但这使我朝着以下方向发展。首先,我尝试使用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
        }
    }
}

运行我的功能时可以重现该错误吗?我想知道,以便我可以改进它们。
约翰·里斯

抱歉,忘记了确切的设置。:/我认为这是涉及多个子目录的时候。碰巧,对“ Remove-Item -force -recurse”的调用并未删除所有文件,在这种情况下,最后一个Remove-Tree失败了,因为目录不为空。这就是为什么我想出了一种新的解决方案,首先尝试使用有问题的内置版本(-force),然后手动进入每个目录并“手动”删除剩下的内容。该版本正在定期使用,直到现在仍在运行。失败的唯一原因是程序仍然拥有目录句柄时。
jdoose

5

为避免已接受答案的“目录不为空”错误,只需使用以前建议的旧DOS命令即可。准备复制粘贴的完整PS语法为:

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

3
文件夹仍然显示“目录不为空”错误!
奥尼尔Umut TURER

2

我采取了另一种受上述@ 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魔术,这可能是另一个困扰您的陷阱:https ://superuser.com/q/212808


2
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终端上运行它,完成后它将停止。


我承认您对监视的想法可能有用,但是与完成后仅打印消息几乎没有什么不同,并且如果在停止Remove-Item时遇到任何问题,循环将永远不会结束。
拉乌尔·萨利纳斯-蒙塔古多

@RaúlSalinas-Monteagudo是正确的,但绝对适用于产品或无人值守的用例场景。它必须足够小以使某人仅在旅途中记住并键入内容,而不是仅将复杂的.ps1文件运行到目录中。
延德拉·D·阿比

2

删除整个文件夹树有时会起作用,有时会失败,并显示“目录不为空”错误。随后尝试检查该文件夹是否仍然存在,可能会导致“访问被拒绝”或“未经授权的访问”错误。我不知道为什么会发生这种情况,尽管可以从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之前运行DEL / F / S / Q并在必要时第二次运行RD来解决RD / S / Q的类似可靠性问题-理想的是在两者之间稍作停顿(即,如图所示使用ping下面)。

DEL /F /S /Q "C:\Some\Folder\to\Delete\*.*" > nul
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

1

真的很简单:

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

您也应该提供示例执行。
不可分割的

1

另一个有用的技巧:

如果您发现许多具有相同或相似名称约定的文件(例如带有点前缀名的mac文件...那是著名的文件提取),则可以像这样从powershell中轻松地用一行删除它们:

ls -r .* | rm

此行将删除当前目录中名称开头的所有带点号的文件,以及该目录内其他文件夹中具有相同情况的所有文件。使用时请注意。:D


为什么不使用rm -rf .*?我没有进行测试的功能,但是我认为它可以工作。
Vini.g.fer

1
这简单; 如果仅从命令中删除“ | rm”,则可以查看要删除内容的整个全景图,确定后,可以完成命令。
丹尼尔·阿尔贝托·勒佩·阿亚拉

由西尔托(Pier citarto),洛斯阿基沃斯(Los Archivos que)的Empiecen con punto准个人,(科莫洛斯·德·马克(COMO LOS DE MAC))室
Daniel Alberto Lepe Ayala

1

要删除包括文件夹结构在内的完整内容,请使用

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

-recurse加入remove-item保证了交互提示被禁用。


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

在不删除父目录的情况下,编写了上面的代码以清理一些日志文件,这很完美!


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

1
请进一步说明,以便其他人可以从您的答案中学习
Nico Haase
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.