【问题标题】:How to recursively delete an entire directory with PowerShell 2.0?如何使用 PowerShell 2.0 递归删除整个目录?
【发布时间】:2010-12-17 16:24:21
【问题描述】:

在 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


【解决方案1】:

在您的 PowerShell 中添加自定义函数$profile

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

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

【讨论】:

    【解决方案2】:

    虽然 rm -r 产生良好的结果,但以下方法更快:

    $fso = New-Object -ComObject scripting.filesystemobject
    $fso.DeleteFolder("D:\folder_to_remove")
    

    要对此进行测试,您可以轻松地创建一个包含 X 文件的文件夹(我使用:Disk Tools 来快速生成文件)。

    然后使用以下命令运行每个变体:

    Measure-Command {rm D:\FOLDER_TO_DELETE -r}
    Measure-Command {Remove-Item -Path D:\FOLDER_TO_DELETE -Recurse -Force}
    Measure-Command {rd -r FOLDER_TO_DELETE }
    $fso.DeleteFolder("D:\folder_to_remove")
    Measure-Command {$fso.DeleteFolder("D:\FOLDER_TO_DELETE")}
    

    我的测试文件夹中的结果是:

    Remove-Item - TotalMilliseconds : 1438.708
    rm - TotalMilliseconds : 1268.8473
    rd - TotalMilliseconds : 739.5385
    FSO - TotalMilliseconds : 676.8091
    

    结果各不相同,但在我的系统上,获胜者是 fileSystemObject。我建议在目标文件系统上进行测试,看看哪种方法最适合您。

    【讨论】:

      【解决方案3】:

      基于@John Reesanswer 进行了一些改进。

      初始文件 树 . /f

      C:\USERS\MEGAM\ONEDRIVE\ESCRITORIO\PWSHCFX
      │   X-Update-PowerShellCoreFxs.ps1
      │   z
      │   Z-Config.json
      │   Z-CoreFxs.ps1
      │
      ├───HappyBirthday Unicorn
      │       collection-of-unicorns-and-hearts-with-rainbows.zip
      │       hand-drawing-rainbow-design.zip
      │       hand-drawn-unicorn-birthday-invitation-template (2).zip
      │       hontana.zip
      │       Unicorn - Original.pdf
      │       Unicorn-free-printable-cake-toppers.png
      │       Unicorn.pdf
      │       Unicorn.png
      │       Unicorn2.pdf
      │       Unicorn3.pdf
      │       Unicorn4.pdf
      │       Unicorn5.pdf
      │       UnicornMLP.pdf
      │
      ├───x
      └───y
      

      代码

      function Get-ItemTree() {
          param (
              [Parameter()]
              [System.String]
              $Path = ".",
      
              [Parameter()]
              [System.String]
              $Include = "*",
      
              [Parameter()]
              [switch]
              $IncludePath,
      
              [Parameter()]
              [switch]
              $Force
      
          )
          $result = @()
          if (!(Test-Path $Path)) {
              throw "Invalid path. The path `"$Path`" doesn't exist." #Test if path is valid.
          }
          if (Test-Path $Path -PathType Container)
          {
              $result += (Get-ChildItem "$Path" -Include "$Include" -Force:$Force -Recurse) # Add all items inside of a container, if path is a container.
          }
          if($IncludePath.IsPresent)
          {
              $result += @(Get-Item $Path -Force) # Add the $Path in the result.
          }
          $result = ,@($result | Sort-Object -Descending -Unique -Property "PSPath") # Sort elements by PSPath property, order in descending, remove duplicates with unique.
          return  $result
      }
      
      function Remove-ItemTree {
          param (
              [Parameter()]
              [System.String]
              $Path, 
      
              [Parameter()]
              [switch]
              $ForceDebug
          )
          (Get-ItemTree -Path $Path -Force -IncludePath) | ForEach-Object{
              Remove-Item "$($_.PSPath)" -Force
              if($PSBoundParameters.Debug.IsPresent)
              {
                  Write-Debug -Message "Deleted: $($_.PSPath)" -Debug:$ForceDebug
              }
          }
      }
      
      Write-Host "███ Test 1"
      $a = Get-ItemTree "./Z-Config.json" -Force -Include "*" -IncludePath:$true # Tree of a file path. 1 element the file (IncludePath parameter = $true)
      $a | Select-Object -ExpandProperty PSPath | ConvertTo-Json
      Write-Host
      
      Write-Host "███ Test 2"
      $b = Get-ItemTree "./Z-Config.json" -Force -Include "*" -IncludePath:$false # Tree of a file path. No Result (IncludePath parameter = $false)
      $b | Select-Object -ExpandProperty PSPath | ConvertTo-Json
      Write-Host
      
      Write-Host "███ Test 3"
      $c = Get-ItemTree "." -Force -Include "*" -IncludePath:$true # Tree of a container path. All elements of tree and the container included (IncludePath parameter = $true).
      $c | Select-Object -ExpandProperty PSPath | ConvertTo-Json
      Write-Host
      
      Write-Host "███ Test 4"
      $d = Get-ItemTree "." -Force -Include "*" -IncludePath:$false # All elements of tree, except the container (IncludePath parameter = $false).
      $d | Select-Object -ExpandProperty PSPath | ConvertTo-Json
      Write-Host
      
      Remove-ItemTree -Path "./HappyBirthday Unicorn" -Debug -ForceDebug #Remove the contents of container and remove the container. -Debug Prints debug messages and -ForceDebug forces to prints messages if DebugPreference is SilentlyContinue.
      Remove-ItemTree -Path "./x" -Debug -ForceDebug #Remove the contents of container and remove the container. -Debug Prints debug messages and -ForceDebug forces to prints messages if DebugPreference is SilentlyContinue.
      Remove-ItemTree -Path "./y" -Debug -ForceDebug #Remove the contents of container and remove the container. -Debug Prints debug messages and -ForceDebug forces to prints messages if DebugPreference is SilentlyContinue.
      Remove-ItemTree -Path "./z" -Debug -ForceDebug #Remove file. -Debug Prints debug messages and -ForceDebug forces to prints messages if DebugPreference is SilentlyContinue.
      
      Get-ChildItem -Force
      

      输出

      ███ Test 1
      "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\Z-Config.json"
      
      ███ Test 2
      
      ███ Test 3
      [
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\Z-CoreFxs.ps1",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\Z-Config.json",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\z",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\y",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\X-Update-PowerShellCoreFxs.ps1",       
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\x",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\UnicornMLP.pdf",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn5.pdf",  
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn4.pdf",  
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn3.pdf",  
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn2.pdf",  
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn.png",   
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn.pdf",   
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn-free-printable-cake-toppers.png",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn - Original.pdf",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\hontana.zip",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\hand-drawn-unicorn-birthday-invitation-template (2).zip",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\hand-drawing-rainbow-design.zip",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\collection-of-unicorns-and-hearts-with-rainbows.zip",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx"
      ]
      
      ███ Test 4
      [
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\Z-CoreFxs.ps1",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\Z-Config.json",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\z",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\y",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\X-Update-PowerShellCoreFxs.ps1",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\x",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\UnicornMLP.pdf",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn5.pdf",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn4.pdf",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn3.pdf",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn2.pdf",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn.png",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn.pdf",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn-free-printable-cake-toppers.png",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\Unicorn - Original.pdf",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\hontana.zip",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\hand-drawn-unicorn-birthday-invitation-template (2).zip",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\hand-drawing-rainbow-design.zip",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn\\collection-of-unicorns-and-hearts-with-rainbows.zip",
        "Microsoft.PowerShell.Core\\FileSystem::C:\\Users\\Megam\\OneDrive\\Escritorio\\pwshcfx\\HappyBirthday Unicorn"
      ]
      
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\HappyBirthday Unicorn\UnicornMLP.pdf
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\HappyBirthday Unicorn\Unicorn5.pdf
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\HappyBirthday Unicorn\Unicorn4.pdf
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\HappyBirthday Unicorn\Unicorn3.pdf
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\HappyBirthday Unicorn\Unicorn2.pdf
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\HappyBirthday Unicorn\Unicorn.png
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\HappyBirthday Unicorn\Unicorn.pdf
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\HappyBirthday Unicorn\Unicorn-free-printable-cake-toppers.png
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\HappyBirthday Unicorn\Unicorn - Original.pdf
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\HappyBirthday Unicorn\hontana.zip
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\HappyBirthday Unicorn\hand-drawn-unicorn-birthday-invitation-template (2).zip
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\HappyBirthday Unicorn\hand-drawing-rainbow-design.zip
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\HappyBirthday Unicorn\collection-of-unicorns-and-hearts-with-rainbows.zip
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\HappyBirthday Unicorn
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\x
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\y
      DEBUG: Deleted: Microsoft.PowerShell.Core\FileSystem::C:\Users\Megam\OneDrive\Escritorio\pwshcfx\z
      
      
          Directory: C:\Users\Megam\OneDrive\Escritorio\pwshcfx
      
      Mode                 LastWriteTime         Length Name
      ----                 -------------         ------ ----
      la---           17/5/2021     1:57            272 X-Update-PowerShellCoreFxs.ps1
      la---           14/5/2021    18:51            252 Z-Config.json
      la---           17/5/2021     4:04          30931 Z-CoreFxs.ps1
      

      树。 /f

      C:\USERS\MEGAM\ONEDRIVE\ESCRITORIO\PWSHCFX
          X-Update-PowerShellCoreFxs.ps1
          Z-Config.json
          Z-CoreFxs.ps1
      
      No subfolders exist
      

      【讨论】:

        【解决方案4】:

        如果您致力于 powershell,则可以使用它,如已接受的答案中所述:

        rm -r -fo targetDir
        

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

        rmdir /s/q targetDir
        

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

        【讨论】:

          【解决方案5】:

          由于底层文件系统是异步的,Remove-Item -Force -Recurse 在 Windows 上似乎会出现间歇性失败的问题。 This answer 似乎解决了这个问题。该用户还积极参与了 Powershell 团队on GitHub

          【讨论】:

            【解决方案6】:

            删除整个文件夹树有时会奏效,有时会失败并出现“目录非空”错误。随后尝试检查该文件夹是否仍然存在可能会导致“访问被拒绝”或“未经授权的访问”错误。我不知道为什么会发生这种情况,尽管可以从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 的类似可靠性问题可以通过在 RD /S /Q 之前运行 DEL /F /S /Q 来解决strong> 并在必要时再次运行 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
            

            【讨论】:

            • 请参阅 David Faivre 在下面的回答中提到的 this answer,了解为什么目录删除有时会失败,以及更复杂的补救措施。
            【解决方案7】:
            rm -r <folder_name>
            c:\>rm -r "my photos"
            

            【讨论】:

            • 请进一步解释,以便其他人可以从您的回答中学习
            【解决方案8】:
            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 终端上运行它,它会在完成后停止。

            【讨论】:

            • 我承认你的监控想法可能很有用,但它与完成后打印一条消息几乎没有什么不同,如果停止删除项目有任何问题,你的循环将永无止境。
            • @RaúlSalinas-Monteagudo 是的,但它绝对适用于生产或无人值守的用例场景。它必须足够小,以便人们可以在旅途中记住和输入,而不是将复杂的 .ps1 文件运行到一个目录。
            【解决方案9】:

            当使用简单的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
            

            【讨论】:

            • 在 TFS 构建脚本中使用 PowerShell 解决问题时,这被证明是正确的答案。
            • 这也是我的解决方案。给自己加分,我的好人!
            • 为我工作。我无法递归删除文件夹的内容,但您的解决方案对我有用。谢谢
            • 这是一个非常强大的解决方案
            • 我不确定为什么接受的答案有这么多选票 - 我个人在 Powershell v5 中使用 remove-item -recurse 仍然会遇到间歇性错误,所以这个解决方案最适合我。
            【解决方案10】:
            Remove-Item -Recurse -Force some_dir
            

            确实像这里宣传的那样工作。

            rm -r -fo some_dir
            

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

            据我了解,当您尝试递归删除一组过滤的文件时,-Recurse 参数无法正常工作。杀死一个目录和它下面的所有东西似乎都可以正常工作。

            【讨论】:

            • 我认为你是对的。我收到“无法删除‘某个目录’中的项目,因为它正在使用中。”错误并假设这是递归算法的问题,并开始寻找解决方法。事实证明,我之前在目标目录中运行的脚本中启动了一个进程。当更改脚本以等待其他进程时,“Remove-Item -Recurse -Force”命令有效。总是先照镜子:)
            • 我发现在包含子目录的目录上运行时需要运行两次。第一次会出现很多“目录不为空”的错误。第二次,它没有错误地完成。
            • Kristopher Johnson,我在 Windows 7 上使用不同的工具时遇到了类似的错误。似乎删除调用在文件或文件夹被实际删除之前返回,有时会造成麻烦。这似乎发生在 Explorer、Far、cmd 和 PowerShell 中。
            • @Joey "似乎删除调用在文件或文件夹被实际删除之前返回,有时会造成麻烦。" --> 澄清一下:父文件夹不会被删除,并且出现以下错误:“[父文件夹]不能被删除,因为它不是空的。”我看到这种情况经常发生在(慢速)网络驱动器上。唯一的解决方案是旧的:cmd /c rd,如下所述。
            • “目录不为空”错误是怎么回事?serverfault.com/questions/199921/powershell-remove-force 也许更好 get-childitem * -include *.csv -recurse |删除项目我不知道。见stackoverflow.com/a/1668471/206730
            【解决方案11】:
            $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"
            }
            

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

            【讨论】:

              【解决方案12】:

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

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

              添加到remove-item-recurse 可确保禁用交互式提示。

              【讨论】:

                【解决方案13】:

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

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

                【讨论】:

                  【解决方案14】:

                  我采用了受上述@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

                  【讨论】:

                    【解决方案15】:

                    另一个有用的技巧:

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

                    ls -r .* | rm
                    

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

                    【讨论】:

                    • 为什么不使用rm -rf .* ?我没有要测试的 powershell,但我认为它会起作用。
                    • 很简单;如果您只是从命令中删除“| rm”,您可以查看要删除的内容的完整全景,确定后,您可以完成命令。
                    • Por cierto, para quitar los archivos que empiecen con punto, (como los de mac) pero que tengan propiedad de oculto, puedes usar: ls -r -h .* | rm
                    【解决方案16】:

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

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

                    【讨论】:

                    • 它仍然给出文件夹的“目录不为空”错误!?
                    【解决方案17】:

                    使用老式的 DOS 命令:

                    rd /s <dir>
                    

                    【讨论】:

                    • 如果这是脚本的一部分,您也必须使用/q(安静模式,不要询问是否可以使用 /S 删除目录树)。
                    【解决方案18】:

                    出于某种原因,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),然后手动下降到每个目录并“手动”删除剩下的内容。这个版本经常使用,直到现在它还在工作。它失败的唯一原因是程序仍然持有目录句柄。
                    【解决方案19】:
                    rm -r ./folder -Force    
                    

                    ...为我工作

                    【讨论】:

                      【解决方案20】:

                      真的很简单:

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

                      【讨论】:

                      • 你也应该提供一个执行示例。
                      【解决方案21】:

                      我用过:

                      rm -r folderToDelete
                      

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

                      【讨论】:

                      • 不需要 cygwin、git 或其他可以在 Windows 上模拟 bash shell 的工具吗?
                      • @Pete,不,它不需要任何东西,只需要 PowerShell。 rm 是 PowerShell 默认配置中 Remove-Item 的别名。检查Get-Alias rm 的输出以获取更多详细信息。 -r 正在利用 PowerShell 对参数的部分匹配行为。由于Remove-Item 只有一个以“r”开头的参数,-Recurse-r 与之匹配。因此,以下所有操作都将相同:rm -rrm -reRemove-Item -Recurse。 (注意rm -rfrm -r -f 都不起作用,但rm -r -fo 会。-rf 不匹配任何参数,-f 匹配多个参数。)
                      • 怎么样。 “Remove-Item -Recurse -Force some_dir”的 Powershell rm 别名比直接使用 remove-item 效果更好。我收到了同样的错误“无法删除 'some directory' 中的项目。我从 remove-item 切换到 rm -r 没有错误!?
                      • 也许是因为我使用-R 而不是-r (尽管据我所知PowerShell 就像Windows 的其余部分一样,不区分大小写,因此它不应该有所作为)但是我收到一条错误消息,提示我要删除的文件夹不为空。
                      • 它在 PowerShell 5.1 上不起作用,我不得不使用 rm -r -form -r -f 也不起作用,因为 -f 参数不明确,因为它可以匹配 -Force 和 @987654343 @)。
                      猜你喜欢
                      • 2023-01-08
                      • 1970-01-01
                      • 2014-05-12
                      • 1970-01-01
                      • 2018-10-15
                      • 1970-01-01
                      • 2018-10-13
                      相关资源
                      最近更新 更多