PowerShell 2.0でディレクトリ全体を再帰的に削除する方法は?


308

PowerShellでディレクトリとそのすべてのサブディレクトリを強制的に削除する最も簡単な方法は何ですか?Windows 7でPowerShell V2を使用しています。

私はいくつかのソースから、最も明白なコマンドでRemove-Item $targetDir -Recurse -Forceあるが正しく機能しないことを学びました。これには、PowerShell V2オンラインヘルプ(を使用して検出Get-Help Remove-Item -Examples)のステートメントが含まれています。

...このコマンドレットのRecurseパラメーターに欠陥があるため、コマンドはGet-Childitemコマンドレットを使用して目的のファイルを取得し、パイプライン演算子を使用してそれらをRemove-Itemコマンドレットに渡します...

Get-ChildItemを使用してそれをRemove-Itemにパイプするさまざまな例を見てきましたが、例では通常、ディレクトリ全体ではなく、フィルターに基づいていくつかのファイルセットを削除します。

最小限のコードを使用してユーザー警告メッセージを生成せずに、ディレクトリ全体、ファイル、および子ディレクトリを破壊する最もクリーンな方法を探しています。わかりやすいのならワンライナーでいいです。


2
powershell、私は知っていますが、RD /S /Q
ルーベンスファリアス


重複しているとは思いません。投稿する前に1667145を確認しました。カスタムPowerShellプロバイダーのRemove-Itemメソッド実装を呼び出すときに、PowerShellがRecurse boolパラメーターを正しく設定しない理由を尋ねています。組み込みのファイルシステムプロバイダーに関連するため、Remove-Itemの動作について尋ねていました。
Matt Spradley、2009年

2
「RD / S / Q」はPowerShellでは機能しないようです-「Remove-Item:引数 '/ q'を受け入れる定位置パラメーターが見つかりません。」
BrainSlugs83 2012

5
rdRemove-ItemPowerShellのエイリアスです。cmd /c "rd /s /q"動作します。
codekaizen 2013年

回答:


510
Remove-Item -Recurse -Force some_dir

ここで宣伝されているように実際に動作します。

rm -r -fo some_dir

も機能する省略形のエイリアスです。

私が理解している限り-Recurse、フィルター処理されたファイルのセットを再帰的に削除しようとすると、パラメーターが正しく機能しません。単一のディレクトリとそれ以下のすべてを殺すためにそれはうまくいくようです。


5
私はあなたが正しいと思います。「「使用中のため、 '一部のディレクトリ'にあるアイテムを削除できません。」というメッセージが表示されました。エラーが発生し、再帰アルゴリズムの問​​題であると想定し、回避策を探しました。ターゲットディレクトリで動作していたスクリプトの前半で実行したプロセスがあることがわかりました。他のプロセスを待機するようにスクリプトを変更すると、「Remove-Item -Recurse -Force」コマンドが機能します。常に最初に鏡を見てください:)
Matt Spradley、2009年

15
サブディレクトリを含むディレクトリで実行すると、これを2回実行する必要があることがわかりました。初めて、多くの「ディレクトリが空ではありません」エラーが発生します。2回目は、エラーなしで完了します。
クリストファージョンソン2011

5
クリストファージョンソン、Windows 7のさまざまなツールで同様のエラーが発生します。ファイルまたはフォルダーが実際に削除される前に削除呼び出しが返され、問題が発生する場合があります。これは、Explorer、Far、cmd、およびPowerShellで発生するようです。
Joey

2
@Joey「ファイルまたはフォルダが実際に削除される前に削除呼び出しが返され、問題が発生する場合があります。」->説明のために:親フォルダーは削除されず、次のエラーが表示されます:「[親フォルダー]は空でないため削除できません。」これは(低速の)ネットワークドライブで常に発生します。唯一の解決策は古いものですcmd /c rd
Davor Josipovic 2013

6
「ディレクトリは空ではありません」というエラーは何ですか?serverfault.com/questions/199921/powershell-remove-force多分良くなる-ChildItemコマンドレット* -include * .CSV -recurse | remove-itemわかりません。stackoverflow.com/a/1668471/206730を
Kiquenet 2013

39

私が使用した:

rm -r folderToDelete

これは私にとって魅力のように機能します(Ubuntuから盗みました)。


Windowsでbashシェルをシミュレートできるcygwin、git、またはその他のツールは必要ありませんか?
ピート

19
@Pete、いいえ、PowerShell以外は必要ありません。PowerShellのデフォルト構成のrmエイリアスRemove-Itemです。Get-Alias rm詳細については、の出力を確認してください。これ-rは、パラメーターに対するPowerShellの部分一致動作を利用しています。Remove-Item「r」で始まるパラメータが1つしかないので、はそれ-Recurse-r一致します。したがって、以下のすべてが同じように動作します:rm -rrm -reRemove-Item -Recurse。(どちらrm -rfも機能しませんrm -r -fが、機能しますが、機能しませんrm -r -fo-rfパラメータに一致せず、-f複数に一致します。)
chwarr

1
どのようにそのことについて。「Remove-Item -Recurse -Force some_dir」のPowershell rmエイリアスは、remove-itemを直接使用するよりもうまく機能します。同じエラーが表示されました。「 'some directory'のアイテムを削除できません。remove-itemからrm -rにエラーなしで切り替えます!?
Greg

面白い。私の箱にはcygwinツールがあり、試しましたがrm -rf folder、もちろん失敗しました。私は最初に回答に反対票を投じました(Ubuntuと書かれていたため)。@chwarrのコメントのおかげで、私はそれなしで試してみましたが、frmバイナリではなくエイリアスを取得しました。私はトゥアンが彼のソースを更新してくれることを望みます(トゥアンがエイリアスであることを知っていたか、本当にそれがUNIXのrmであると本当に思ったのかは
Joshua Ball

2
おそらく、-R代わりに私が使用しているためです-r(私が知っている限り、PowerShellはWindowsの他の部分と同様で、大文字と小文字は区別されないため、違いはありません)削除しようとしているフォルダーが空ではない。
rbaleksandar 2017年

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削除する項目をフィルタしたい場合は、パラメータは単なる便利です。

実行して削除しようとしているものを確認すると便利なので、2つの関数に分割されています。

Get-Tree some_dir | select fullname

1
TFSビルドスクリプトでPowerShellを使用して問題を解決している間、これは正しい答えであることが判明しました。
rcabr 14

これも私にとっての解決策です。私の良い人に自分自身にいくつかのポイントがあります!
ジャマー2016年

私のために働いた。フォルダーの内容を再帰的に削除することはできませんでしたが、あなたの解決策は私にとってうまくいきました。ありがとう
SheldonH

これは非常に堅牢なソリューションです
Max Young

なぜ承認された回答が非常に多くの票を投じるのかはわかりません-私は個人的remove-item -recurseにPowershell v5で断続的なエラーを取得しているため、このソリューションが最適です。
JonoB


11

この例を試してください。ディレクトリが存在しない場合、エラーは発生しません。PowerShell v3.0が必要になる場合があります。

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

7

古い学校のDOSコマンドを使用します。

rd /s <dir>

これがスクリプトの一部である場合は、/q(Quietモード、/ Sでディレクトリツリーを削除してもよいかどうかを尋ねないでください)も使用する必要があります。
wildeyes

6

何らかの理由で、ジョンリースの回答が私の場合うまく機能しない場合がありました。しかし、それは私を次の方向に導きました。まず、バグの多い-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
        }
    }
}

私の関数を実行するときにエラーを再現できますか?私はそれらを改善できるように知りたいのですが。
ジョンリース2016年

申し訳ありませんが、正確な設定を覚えていません。:/それは複数のサブディレクトリが関わっていたときだと思います。「Remove-Item -force -recurse」の呼び出しですべてのファイルが削除されず、その場合、ディレクトリが空ではなかったため、最後のRemove-Treeが失敗しました。そのため、最初にバグのある組み込みバージョン(-force)を試し、次に手動で各ディレクトリに降りて、残っているものを「手動で」削除する新しいソリューションを思い付きました。このバージョンは定期的に使用されており、現在まで機能しています。失敗した唯一の原因は、プログラムがディレクトリへのハンドルをまだ保持している場合でした。
jdoose

5

受け入れられた回答の「ディレクトリは空ではありません」というエラーを回避するには、以前に提案されている古き良きDOSコマンドを使用するだけです。コピー貼り付けの準備ができている完全なPS構文は次のとおりです。

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

3
それでもフォルダに対して「ディレクトリは空ではありません」エラーが発生します!?
Oncel Umut TURER 2017

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


2
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ターミナルで実行すると、完了すると停止します。


監視を使用したアイデアは役立つ可能性がありますが、終了後にメッセージを出力するだけとほとんど変わりません。Remove-Itemの停止で問題が発生した場合、ループが終了することはありません。
ラウル・サリナス- Monteagudo

@RaúlSalinas-Monteagudotrueですが、それは間違いなく本番または無人のユースケースシナリオ用です。誰かが外出先で覚えてタイプするだけで十分であり、洗練された.ps1ファイルをディレクトリだけで実行しないようにする必要があります。
Gajendra D Ambi

2

フォルダツリー全体の削除が機能することもあれば、「ディレクトリが空ではない」というエラーで失敗することもあります。その後、フォルダがまだ存在するかどうかを確認しようとすると、「アクセスが拒否されました」または「不正なアクセス」エラーが発生する可能性があります。これが発生する理由はわかりませんが、この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を実行することによって解決することができるDEL / F / S / Qの前にRD / 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

本当にシンプル:

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

実行例も提供する必要があります。
2014年

1

別の便利なトリック:

同じまたは類似した名前の規則を持つファイルが多数ある場合(ドットプレフィックス名の付いたmacファイルなど...有名なファイルプル)、次のようにPowerShellから1行で簡単に削除できます。

ls -r .* | rm

この行は、現在のディレクトリ内の名前の先頭にドットが含まれるすべてのファイルと、このディレクトリ内の他のフォルダ内の同じ状況のすべてのファイルも削除します。ご使用の際はご注意ください。:D


なぜ使用しないのrm -rf .*ですか?テストするPowerShellはありませんが、うまくいくと思います。
Vini.g.fer 2016年

1
それは簡単です; コマンドから "| rm"を削除するだけで、削除するものの全体のパノラマを表示できます。確信があると、コマンドを完了できます。
Daniel Alberto Lepe Ayala

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

フォルダ構造を含む完全なコンテンツを削除するには、以下を使用します

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

-recurse追加するとremove-item、インタラクティブプロンプトが無効になります。


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

1
他の人があなたの答えから学ぶことができるように、さらに説明してください
ニコ・ハーセ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.