PowerShell で空のフォルダーを削除する方法
効果的なディレクトリ管理は PowerShell スクリプティングで重要であり、Get-ChildItem cmdlet はファイルシステムのナビゲーションの基盤となります。空のフォルダーをクリーンアップする場合、フォルダー階層を辿ることが重要です。
この記事では、Get-ChildItem を他の cmdlet と共に活用し、指定したパス内の空のディレクトリを体系的に特定して削除する実用的な使用法を掘り下げます。PowerShell の強力なスクリプト機能を活用することで、ユーザーはディレクトリを効率的に管理し、整理されたファイルシステムを確保できます。
PowerShell の Get-ChildItem Cmdlet
Get-ChildItem cmdlet は、指定された場所のすべての子アイテム(ファイルとフォルダー)を取得します。指定されたフォルダーのパス内のすべての空のフォルダーを削除する必要がある場合、フォルダー階層を辿ることが必須です。
したがって、Get-ChildItem cmdlet は役立ちます。この cmdlet は、Recurse や Directory といったパラメータを受け入れ、ディレクトリタイプの子アイテムを取得し、フォルダー構造を再帰的に辿ります。
構文:
Get-ChildItem -Path -Directory -Recurse
使用可能なオプションのパラメータはさらに多数あります。次のようなフォルダー構造を作成してみましょう。
somepath/testA
testB
testD
testE
a.txt
testC
testF
b.txt
testG
testH
目的は、testA フォルダー内のすべての空のフォルダーを削除することです。したがって、削除すべきフォルダーは次のとおりです。
testDtestGtestH
指定されたフォルダーのパス(somepath/testA)内のすべてのサブディレクトリを取得しましょう。
$path = "D:\testA"
$fetchedDirList = Get-ChildItem $path -Directory -Recurse
このスニペットでは、変数 $path にディレクトリパス"D:\testA"を割り当て、Get-ChildItem cmdlet を -Directory および -Recurse パラメータと共に使用して、指定されたパスから再帰的にすべてのディレクトリを取得します。得られたディレクトリのリストは変数 $fetchedDirList に保存され、これは"D:\testA"およびそのサブディレクトリ内のすべてのディレクトリを表すディレクトリオブジェクトのコレクションとなります。
エイリアス gci を使用して Get-ChildItem の代わりに使用することもできます。
$fetchedDirList = gci $path -directory -Recurse
元のコードからこの修正されたバージョンに移行する際、Get-ChildItem cmdlet を使用して取得したディレクトリオブジェクトを変数 $fetchedDirList にキャプチャし続けます。しかし、この更新されたコードでは、完全な cmdlet 名 Get-ChildItem の代わりにエイリアス gci を使用します。
この省略形は、指定されたパス $path からディレクトリを再帰的に取得し、それを $fetchedDirList に保存する機能を維持します。
$fetchedDirList 変数を確認しましょう。
$fetchedDirList
出力:

すべてのディレクトリとサブディレクトリが期待通りに取得されました。
PowerShell の Where-Object Cmdlet
上記の結果から空のディレクトリをフィルタリングする必要があります。Where-Object cmdlet は、そのプロパティに基づいてコレクションからオブジェクトをフィルタリングします。
Where エイリアスを Where-Object コマンドの代わりに使用できます。各ディレクトリ内のアイテム数に基づいて上記のディレクトリリストをフィルタリングする必要があります。
条件は次のように示されます。
where { (gci $_.fullName).count -eq 0 }
コレクションから与えられたオブジェクトにサブアイテムが 0 であれば、それは空のディレクトリと見なされます。したがって、削除する必要があります。
前のステップの出力を Where cmdlet にパイプしましょう。
$emptyDirectoryList = $fetchedDirList | where { (gci $_.fullName).count -eq 0 }
このコード行では、変数 $emptyDirectoryList に、$fetchedDirList から Where エイリアスを使用してディレクトリをフィルタリングした結果を割り当てています。フィルタリング条件はスクリプトブロック内に定義されており、各ディレクトリ内の子アイテムの数(gci $_.FullName を使用して取得)が 0 であるかどうかを確認します。
このアプローチにより、空のディレクトリを表すディレクトリオブジェクトのみが $emptyDirectoryList に特定され、捕らえられます。
$emptyDirectoryList を印刷しましょう。
$emptyDirectoryList
出力:

結果は完全に正しいです。空のコンテンツを持つ testD と testH という 2つのフォルダーだけを取得しました。
$emptyDirectoryList コレクションから各オブジェクトを簡単に削除できます。アイテムを削除するために Remove-Item cmdlet を使用できます。
その前に、$emptyDirectoryList 内の各オブジェクトの完全パスを取得する必要があります。Select-Object cmdlet は、その FullName プロパティを持つオブジェクトを取得できます。
$finalListToRemove = $emptyDirectoryList | select -ExpandProperty FullName
このコード行では、$emptyDirectoryList に格納されているディレクトリの完全パスを抽出することで、新たに変数 $finalListToRemove を作成します。Select-Object cmdlet を -ExpandProperty FullName パラメータと共に使用し、$emptyDirectoryList 内の各ディレクトリオブジェクトの FullName プロパティの値を取得します。
その結果、$finalListToRemove は空のディレクトリへの完全なパスのリストを含み、削除の準備が整います。
$finalListToRemove
$finalListToRemove の出力:

これで削除するフォルダーのリストが得られました。
PowerShell のコレクションからアイテムを削除する
コレクション内のアイテムをループするために ForEach-Object cmdlet を使用することができます。ループ内で Remove-Item cmdlet を使用できます。
$finalListToRemove | ForEach-Object { Remove-Item $_ }
$_ はコレクション内の現在のアイテムを示します。これにより、testD および testH フォルダーが削除されます。
ここには一つトリッキーな部分があります。testH フォルダーが削除されると、testG ディレクトリも空になります。
したがって、スクリプトを少し修正する必要があります。空でないフォルダーが残るまで上記の手順を繰り返す必要があります。
これを行うために do...while ループを使用できます。
$path = "D:\testA"
do {
$fetchedDirList = Get-ChildItem $path -Directory -Recurse
$emptyDirectoryList = $fetchedDirList | where { (gci $_.fullName).count -eq 0 }
$finalListToRemove = $emptyDirectoryList | select -ExpandProperty FullName
$finalListToRemove | ForEach-Object { Remove-Item $_ }
} while ( $finalListToRemove.count -gt 0 )
このコードブロックでは、指定されたパスおよびそのサブディレクトリ内の空のディレクトリを体系的に検出し削除するためにループを設定します。ループ内では、まず指定されたパスから再帰的にすべてのディレクトリを取得するために Get-ChildItem cmdlet を使用します。
次に、Where-Object cmdlet を使用して空のディレクトリをフィルタリングします。これらの空のディレクトリの完全パスを抽出した後、ForEach-Object ループ内で Remove-Item cmdlet を使用して一つずつ削除します。
このループは、削除のための空のディレクトリが残っている限り繰り返され、指定されたパスおよびそのサブディレクトリ内の空のディレクトリの徹底的なクリーンアップを保証します。
隠しファイルやフォルダーも考慮する必要がある場合、以下のように Get-ChildItem cmdlet に -Force パラメータを渡すことができます。
$emptyDirectoryList = $fetchedDirList | where { (gci $_.fullName -Force).count -eq 0 }
出力:

結論
PowerShell では、空のフォルダーを効率的に特定し削除することが、整理されたファイルシステムを維持するために重要です。Get-ChildItem、Where-Object、および Remove-Item のような cmdlet を戦略的に活用することで、ユーザーはディレクトリ管理タスクを合理化できます。
これらの cmdlet は、指定されたパス内のディレクトリの包括的なクリーンアップを可能にし、システムの効率と整理を向上させます。PowerShell のスクリプティング環境を活用することで、ユーザーはディレクトリ管理プロセスを自動化し、整理されたファイルシステムを確保しながら、時間と労力を節約できます。
PowerShell の強力な機能を活用することで、ディレクトリ管理はシステム管理のシームレスな側面となり、ユーザーが最適なシステム性能を維持できるようになります。
Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.
