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

问题描述 投票:295回答:16

在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的示例,但是这些示例通常会基于过滤器而不是整个目录来删除一些文件集。

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

windows powershell windows-7 filesystems delete-directory
16个回答
484
投票
Remove-Item -Recurse -Force some_dir

确实确实如此处宣传的那样工作。

rm -r -fo some_dir

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

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


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

OR

remove-item <dir> -Recurse -Force

如果您的目录很大,那么我通常要做的是

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

在另一个powershell终端上运行它,完成后它将停止。


2
投票

删除整个文件夹树有时会起作用,有时会因“目录不为空”错误而失败。随后尝试检查文件夹是否仍然存在可能导致“访问被拒绝”或“未经授权的访问”错误。尽管可以从this StackOverflow posting中获得一些见识,但我不知道为什么会这样。

通过指定删除文件夹中项目的顺序并添加延迟,我能够解决这些问题。以下对我来说很好:

# 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

PowerShell中的Microsoft TechNet文章Using Calculated Properties有助于我获得按深度排序的子文件夹列表。

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


1
投票
非常简单:

1
投票

另一个有用的技巧:


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

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

38
投票

我用过:

rm -r folderToDelete

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


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

12
投票
rm -r ./folder -Force    

...为我工作


11
投票

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

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

7
投票

使用老式的DOS命令:

rd /s <dir>

5
投票

出于某种原因,约翰·里斯(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
        }
    }
}

5
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.