在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的示例,但是这些示例通常会基于过滤器而不是整个目录来删除一些文件集。
我正在寻找一种最干净的方法来删除整个目录,文件和子目录,而不用最少的代码生成任何用户警告消息。如果易于理解,单线将是不错的选择。
Remove-Item -Recurse -Force some_dir
确实确实如此处宣传的那样工作。
rm -r -fo some_dir
也是可以使用的速记别名。
据我了解,当您尝试递归删除一组过滤的文件时,-Recurse
参数只是无法正常工作。对于杀死单个目录及其下的所有内容,它似乎都可以正常工作。
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终端上运行它,完成后它将停止。
删除整个文件夹树有时会起作用,有时会因“目录不为空”错误而失败。随后尝试检查文件夹是否仍然存在可能导致“访问被拒绝”或“未经授权的访问”错误。尽管可以从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有助于我获得按深度排序的子文件夹列表。
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
另一个有用的技巧:
$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"
}
rm -r <folder_name>
c:\>rm -r "my photos"
我用过:
rm -r folderToDelete
这对我来说就像一个魅力(我从Ubuntu上偷了它。
当使用简单的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
rm -r ./folder -Force
...为我工作
尝试这个例子。如果该目录不存在,则不会引发任何错误。您可能需要PowerShell v3.0。
remove-item -path "c:\Test Temp\Test Folder" -Force -Recurse -ErrorAction SilentlyContinue
使用老式的DOS命令:
rd /s <dir>
出于某种原因,约翰·里斯(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
}
}
}
为避免已接受的答案出现“目录不为空”错误,只需使用以前建议的旧DOS命令即可。可供复制粘贴的完整PS语法为:
& cmd.exe /c rd /S /Q $folderToDelete
我采用了另一种受上述@ 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