Làm cách nào để xóa đệ quy toàn bộ thư mục với PowerShell 2.0?


308

Cách đơn giản nhất để xóa mạnh một thư mục và tất cả các thư mục con của nó trong PowerShell là gì? Tôi đang sử dụng PowerShell V2 trong Windows 7.

Tôi đã học được từ một số nguồn rằng lệnh rõ ràng nhất Remove-Item $targetDir -Recurse -Force, không hoạt động chính xác. Điều này bao gồm một tuyên bố trong trợ giúp trực tuyến PowerShell V2 (được tìm thấy bằng cách sử dụng Get-Help Remove-Item -Examples) nói rằng:

... Vì tham số Recurse trong lệnh ghép ngắn này bị lỗi, nên lệnh sử dụng lệnh ghép ngắn Get-Childitem để lấy các tệp mong muốn và nó sử dụng toán tử đường ống để chuyển chúng đến lệnh ghép ngắn Loại bỏ ...

Tôi đã thấy các ví dụ khác nhau sử dụng Get-ChildItem và chuyển nó sang Remove-Item , nhưng các ví dụ này thường loại bỏ một số tập tin dựa trên bộ lọc, không phải toàn bộ thư mục.

Tôi đang tìm cách sạch nhất để thổi bay toàn bộ thư mục, tệp và thư mục con, mà không tạo ra bất kỳ thông báo cảnh báo người dùng nào sử dụng ít mã nhất. Một lớp lót sẽ tốt nếu nó dễ hiểu.


2
powershell, tôi biết, nhưngRD /S /Q
Rubens Farias


Tôi không nghĩ đó là một bản sao. Tôi đã xem lại 1667145 trước khi đăng. Đó là câu hỏi tại sao PowerShell không thiết lập đúng tham số bool Recurse khi gọi triển khai phương thức Remove-Item của nhà cung cấp PowerShell tùy chỉnh. Tôi đã hỏi về hành vi Remove-Item vì nó liên quan đến nhà cung cấp hệ thống tập tin tích hợp.
Matt Spradley

2
"RD / S / Q" dường như không hoạt động trong PowerShell - nói "Xóa mục: Không thể tìm thấy tham số vị trí chấp nhận đối số '/ q'."
BrainSlugs83

5
rdlà một bí danh cho Remove-Itemtrong powershell. cmd /c "rd /s /q"công trình, mặc dù.
codekaizen

Câu trả lời:


510
Remove-Item -Recurse -Force some_dir

thực sự làm việc như quảng cáo ở đây.

rm -r -fo some_dir

là bí danh tốc ký cũng hoạt động.

Theo như tôi hiểu, -Recursetham số sẽ không hoạt động chính xác khi bạn cố gắng xóa một tập hợp các tệp được lọc theo cách đệ quy. Để giết một dir duy nhất và mọi thứ bên dưới dường như hoạt động tốt.


5
Tôi nghĩ rằng bạn là chính xác. Tôi đã nhận được "Không thể xóa mục này tại 'một số thư mục' vì nó đang được sử dụng." lỗi và cho rằng đó là một vấn đề với thuật toán đệ quy và đã tìm kiếm một cách giải quyết. Hóa ra tôi đã có một quá trình tôi đã loại bỏ trước đó trong kịch bản đang làm việc trong thư mục đích. Khi thay đổi tập lệnh để chờ quá trình khác, lệnh "Remove-Item -Recurse -Force" hoạt động. Luôn luôn nhìn vào gương trước :)
Matt Spradley

15
Tôi thấy rằng tôi cần chạy cái này hai lần khi chạy trên một thư mục chứa các thư mục con. Lần đầu tiên, sẽ có rất nhiều lỗi "Thư mục không trống". Lần thứ hai, nó hoàn thành không có lỗi.
Kristopher Johnson

5
Kristopher Johnson, tôi gặp lỗi tương tự với các công cụ khác nhau trên Windows 7. Có vẻ như cuộc gọi xóa trả về sớm hơn một tệp hoặc thư mục thực sự bị xóa, đôi khi gây ra sự cố. Điều này dường như xảy ra trong Explorer, Far, cmd và PowerShell.
Joey

2
@Joey "Có vẻ như cuộc gọi xóa trả về sớm hơn một tệp hoặc thư mục thực sự bị xóa, đôi khi gây rắc rối." -> Để làm rõ: thư mục mẹ sẽ không bị xóa và người ta sẽ gặp lỗi sau: "[thư mục gốc] không thể xóa được vì nó không trống." Tôi thấy điều này xảy ra liên tục trên các ổ đĩa mạng (chậm). Giải pháp duy nhất là giải pháp cũ: cmd /c rdnhư đã nêu dưới đây.
Davor Josipovic

6
Những gì về lỗi "Thư mục không trống"? serverfault.com/questions/199921/powershell-remove-force Có lẽ tốt hơn get-childitem * -include * .csv -recurse | loại bỏ mục tôi không biết. Xem stackoverflow.com/a/1668471/206730
Kiquenet

39

Tôi đã sử dụng:

rm -r folderToDelete

Điều này đối với tôi như một cơ duyên (tôi đã đánh cắp nó từ Ubuntu).


Không yêu cầu cygwin, git hoặc một số công cụ khác có thể mô phỏng bash shell trên Windows?
Pete

19
@Pete, không, nó không yêu cầu gì ngoài PowerShell. rmlà bí danh cho Remove-Itemcấu hình mặc định của PowerShell. Kiểm tra đầu ra Get-Alias rmđể biết thêm chi tiết. Việc -rtận dụng hành vi khớp một phần của PowerShell trên các tham số. Vì Remove-Itemchỉ có một tham số bắt đầu bằng 'r', -Recursenên -rkhớp với tham số đó. Như vậy, sau tất cả sẽ làm việc như nhau: rm -r, rm -re, Remove-Item -Recurse. (Lưu ý rằng cả hai đều rm -rfkhông rm -r -fhoạt động, nhưng rm -r -fosẽ -rfkhông khớp với các tham số và -fkhớp với nhiều hơn một.)
chwarr

1
Thế còn cái đó. Bí danh Powershell rm cho "Remove-Item -Recurse -Force some_dir" hoạt động tốt hơn so với trực tiếp sử dụng remove-item. Tôi đã nhận được cùng một lỗi "Không thể xóa mục này tại 'một số thư mục'. Tôi chuyển từ mục gỡ bỏ sang rm -r không có lỗi!?
Greg

Hấp dẫn. Tôi có công cụ cygwin trên hộp của mình, và đã thử rm -rf foldervà tất nhiên nó đã thất bại. Tôi ban đầu bỏ phiếu trả lời (vì nó nói Ubuntu). Nhờ nhận xét của @chwarr, tôi đã thử nó mà không có fvà nó đã chọn bí danh thay vì rm nhị phân. Tôi ước Tuấn sẽ cập nhật nguồn của mình (không chắc là Tuấn biết đó là bí danh hay thực sự nghĩ đó là unix rm ;-)
Joshua Ball

2
Có lẽ đó là vì tôi sử dụng -Rthay vì -r(mặc dù theo như tôi biết PowerShell giống như phần còn lại của Windows không phân biệt chữ hoa chữ thường nên không tạo ra sự khác biệt) nhưng tôi đã gặp lỗi khi các thư mục tôi đang cố xóa không trống rỗng
rbaleksandar

25

Khi xóa các tệp đệ quy bằng cách sử dụng đơn giản, Remove-Item "folder" -Recurseđôi khi tôi thấy một lỗi không liên tục:[folder] cannot be removed because it is not empty.

Câu trả lời này cố gắng ngăn chặn lỗi đó bằng cách xóa từng tệp.

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

Một chi tiết quan trọng là sắp xếp tất cả các mục với pspath -Descendingcác lá để được xóa trước khi rễ. Việc sắp xếp được thực hiện trên pspaththam số vì có nhiều cơ hội làm việc cho các nhà cung cấp khác ngoài hệ thống tệp. Các -Includethông số chỉ là một sự tiện lợi nếu bạn muốn lọc các mục cần xóa.

Nó được chia thành hai chức năng vì tôi thấy hữu ích khi xem những gì tôi sắp xóa bằng cách chạy

Get-Tree some_dir | select fullname

1
Trong khi giải quyết vấn đề bằng PowerShell trong tập lệnh xây dựng TFS, đây là câu trả lời đúng.
RCabr

Đây là giải pháp cho tôi là tốt. Có cho mình một số điểm người đàn ông tốt của tôi!
Jammer

Đã làm cho tôi. Tôi không thể xóa đệ quy nội dung của một thư mục, nhưng giải pháp của bạn đã làm việc cho tôi. cảm ơn
SheldonH

Đây là một giải pháp rất mạnh mẽ
Max Young

Tôi không chắc tại sao câu trả lời được chấp nhận có quá nhiều phiếu bầu - Cá nhân tôi vẫn nhận được các lỗi không liên tục khi sử dụng remove-item -recursetrong Powershell v5 vì vậy giải pháp này là tốt nhất cho tôi.
JonoB


11

Hãy thử ví dụ này. Nếu thư mục không tồn tại, không có lỗi nào được nêu ra. Bạn có thể cần PowerShell v3.0.

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

7

Sử dụng lệnh DOS trường học cũ:

rd /s <dir>

Nếu đây là một phần của tập lệnh, bạn cũng phải sử dụng /q(Chế độ im lặng, đừng hỏi liệu có nên xóa cây thư mục bằng / S) không.
wildeyes

6

Vì một số lý do, câu trả lời của John Rees đôi khi không hoạt động trong trường hợp của tôi. Nhưng nó đã dẫn tôi theo hướng sau. Đầu tiên tôi cố gắng xóa thư mục theo cách đệ quy với tùy chọn buggy -recurse. Sau đó tôi đi xuống mọi thư mục con còn lại và xóa tất cả các tệp.

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

Bạn có thể tái tạo lỗi khi chạy các chức năng của tôi? Tôi muốn biết để tôi có thể cải thiện chúng.
John Rees

Xin lỗi, đừng nhớ cài đặt chính xác. : / Tôi nghĩ đó là khi nhiều thư mục con có liên quan. Nó đã xảy ra rằng lệnh gọi "Remove-Item -force -recurse" đã không xóa tất cả các tệp và trong trường hợp đó, Remove-Tree cuối cùng đã thất bại vì thư mục không trống. Đó là lý do tại sao tôi đã đưa ra giải pháp mới để thử phiên bản tích hợp lỗi (-force) sau đó giảm dần theo cách thủ công vào từng thư mục và xóa "thủ công" những gì còn lại. Phiên bản này được sử dụng thường xuyên và cho đến nay nó vẫn hoạt động. Nguyên nhân duy nhất khiến nó thất bại là khi một chương trình vẫn giữ một tay cầm cho một thư mục.
jdoose

5

Để tránh các lỗi "Thư mục không trống" của câu trả lời được chấp nhận, chỉ cần sử dụng lệnh DOS cũ như đề xuất trước đây. Cú pháp PS đầy đủ đã sẵn sàng để dán sao chép là:

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

3
Nó vẫn báo lỗi "Thư mục không trống" cho các thư mục!?
Oncel Umut TURER

2

Tôi đã thực hiện một cách tiếp cận khác lấy cảm hứng từ @ john-rees ở trên - đặc biệt là khi cách tiếp cận của anh ấy bắt đầu thất bại đối với tôi tại một số điểm. Về cơ bản lặp lại các cây con và sắp xếp các tệp theo độ dài đường dẫn của chúng - xóa từ dài nhất đến ngắn nhất

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

Về phép thuật -LiteralPath, đây là một gotchya khác có thể đánh bạn: https://superuser.com/q/212808


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

HOẶC LÀ

remove-item <dir> -Recurse -Force

Nếu bạn có một thư mục lớn thì điều tôi thường làm là

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

Chạy cái này trên một thiết bị đầu cuối powershell và nó sẽ dừng lại khi nó được thực hiện.


Tôi thừa nhận ý tưởng của bạn với việc giám sát có thể hữu ích, nhưng nó hoàn toàn khác với việc chỉ in một tin nhắn sau khi nó kết thúc và trong trường hợp có bất kỳ vấn đề nào dừng việc Loại bỏ Mục, vòng lặp của bạn sẽ không bao giờ kết thúc.
Raúl Salinas-Monteagudo

@ RaúlSalinas-Monteagudo đúng nhưng nó chắc chắn dành cho kịch bản trường hợp sử dụng prod hoặc không giám sát. Nó phải đủ nhỏ để ai đó chỉ cần nhớ và gõ khi đang di chuyển và không chạy tệp .ps1 tinh vi để chỉ một thư mục.
Gajendra D Ambi

2

Xóa toàn bộ cây thư mục đôi khi hoạt động và đôi khi không thành công với lỗi "Thư mục không trống". Sau đó, cố gắng kiểm tra xem thư mục có còn tồn tại có thể dẫn đến lỗi "Truy cập bị từ chối" hoặc "Truy cập trái phép" hay không. Tôi không biết tại sao điều này xảy ra, mặc dù một số thông tin chi tiết có thể thu được từ bài đăng StackOverflow này .

Tôi đã có thể khắc phục các vấn đề này bằng cách chỉ định thứ tự các mục trong thư mục bị xóa và bằng cách thêm độ trễ. Sau đây chạy tốt cho tôi:

# 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

Một bài viết Microsoft TechNet sử dụng các thuộc tính được tính toán trong PowerShell rất hữu ích cho tôi trong việc lấy danh sách các thư mục con được sắp xếp theo độ sâu.

Các vấn đề về độ tin cậy tương tự với RD / S / Q có thể được giải quyết bằng cách chạy DEL / F / S / Q trước RD / S / Q và chạy RD lần thứ hai nếu cần - lý tưởng là tạm dừng ở giữa (ví dụ như sử dụng ping như được hiển thị phía dưới).

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

Thực sự đơn giản:

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

Bạn nên cung cấp một ví dụ thực hiện quá.
không thể chia sẻ

1

Một mẹo hữu ích khác:

Nếu bạn tìm thấy rất nhiều tệp có quy ước tên giống hoặc tương tự (như tệp mac có tên tiền tố dấu chấm ... kéo tệp nổi tiếng đó), bạn có thể dễ dàng xóa chúng bằng một dòng duy nhất từ ​​quyền hạn như thế này:

ls -r .* | rm

Dòng này sẽ xóa tất cả các tệp có dấu chấm ở đầu tên trong thư mục hiện tại và tất cả các tệp có cùng hoàn cảnh bên trong các thư mục khác trong thư mục này. Hãy nhận biết về nó khi sử dụng nó. : D


Tại sao không sử dụng rm -rf .*? Tôi không có quyền hạn để kiểm tra, nhưng tôi nghĩ nó sẽ hoạt động.
Vini.g.fer

1
Dễ thôi; nếu bạn chỉ xóa "| rm" khỏi lệnh, bạn có thể xem toàn cảnh của những gì bạn sẽ xóa, sau khi bạn chắc chắn, bạn có thể hoàn thành lệnh.
Daniel Alberto Lepe Ayala

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
Daniel Alberto Lepe Ayala

1

Để xóa các nội dung đầy đủ bao gồm cả cấu trúc thư mục sử dụng

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

Việc -recursethêm vào để remove-itemđảm bảo lời nhắc tương tác bị vô hiệu hóa.


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

Đã viết ở trên để làm sạch một số logfiles mà không xóa thư mục cha và điều này hoạt động hoàn hảo!


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

1
Vui lòng giải thích thêm để những người khác có thể học hỏi từ câu trả lời của bạn
Nico Haase
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.