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

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

...因为这个cmdlet中的递归参数是错误的,该命令使用get - childitem cmdlet来获取所需的文件,并使用管道操作符将它们传递给Remove-Item cmdlet…

我见过使用Get-ChildItem并将其输送到remove - item的各种示例,但这些示例通常基于过滤器删除一些文件集,而不是整个目录。

我正在寻找最干净的方法来吹出整个目录,文件和子目录,而不生成任何用户警告消息使用最少的代码量。如果简单易懂,那么一行代码最好。


当前回答

在PowerShell $profile中添加一个自定义函数:

function rmrf([string]$Path) {
    try {
        Remove-Item -Recurse -ErrorAction:Stop $Path
    } catch [System.Management.Automation.ItemNotFoundException] {
        # Ignore
        $Error.Clear()
    }
}

这是rm -rf行为最准确的表示。

其他回答

如果你致力于powershell,你可以使用这个,正如在接受的答案中解释的那样:

rm -r -fo targetDir

但我发现使用Windows命令提示符更快

rmdir /s/q targetDir

除了速度更快之外,使用命令提示符选项的另一个优点是它立即开始删除文件(powershell首先执行一些枚举),因此如果在运行时出现故障,您至少在删除文件方面取得了一些进展。

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

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

...为我工作

在PowerShell $profile中添加一个自定义函数:

function rmrf([string]$Path) {
    try {
        Remove-Item -Recurse -ErrorAction:Stop $Path
    } catch [System.Management.Automation.ItemNotFoundException] {
        # Ignore
        $Error.Clear()
    }
}

这是rm -rf行为最准确的表示。