web-dev-qa-db-ja.com

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

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にパイプ処理するさまざまな例を見てきましたが、これらの例では通常、ディレクトリ全体ではなく、フィルタに基づくファイル。

ユーザー警告メッセージを最小限のコードで生成せずに、ディレクトリ全体、ファイル、および子ディレクトリを消去する最もクリーンな方法を探しています。それが理解しやすいのならワンライナーはいいでしょう。

240
Matt Spradley
Remove-Item -Recurse -Force some_dir

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

rm -r -fo some_dir

同様に機能する省略形のエイリアスです。

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

412
Joey

私は使った:

rm -r folderToDelete

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

36
Tuan Jinn

単純な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
20
John Rees

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

remove-item -path "c:\Test Temp\Test Folder" -Force -Recurse -ErrorAction SilentlyContinue
10
steve
rm -r ./folder -Force    

...私のために働いた

9
stevethecollier

Old-school DOSコマンドを使用してください。

rd /s <dir>
8
Anonymous

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

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

なんらかの理由でJohn Reesの答えが私の場合うまくいかなかったことがあります。しかし、それは私を次の方向に導きました。まず、バグの多い-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
jdoose

私は上記の@ 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マジックに関しては、ここにあなたを打っているかもしれないもう一つのgotchyaがあります: https://superuser.com/q/212808

2
Peter McEvoy

フォルダツリー全体を削除するとうまくいくことがあり、「ディレクトリが空ではありません」というエラーで失敗することがあります。その後、そのフォルダがまだ存在するかどうかを確認しようとすると、 "Access Denied"または "Unauthorized Access"エラーが発生する可能性があります。 この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に関する同様の信頼性の問題は、RD/S/Qを2回実行することで解決できます。間(つまり、下に示すようにpingを使用)。

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
MikeOnline

本当に簡単です。

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

フォルダ構造を含む完全な内容を削除するには

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

-recurseremove-itemを追加すると、対話型プロンプトが無効になります。

1
steve simon
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端末でこれを実行すると、終了すると停止します。

1
Gajendra D Ambi

もう1つの便利なトリック:

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

ls -r .* | rm

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