サーバーやシステムを管理する際には、空きディスク容量を維持することが重要です。管理者としては、「ディスクフル」の状況に気付かないようにすることが望ましいです。確実に対応するために、PowerShellを使用してファイルを削除する方法を学ぶべきです。
本記事では、PowerShellを使用してシステムからファイルを削除する方法をほぼすべて紹介します。
さあ、始めましょう!
前提条件
この記事ではPowerShellを使用して例を示しており、一緒に進める予定の場合は、以下が必要です。
- A computer that is running Windows 10 or above.
- Windows PowerShell 5.1またはPowerShell 7.0
- A script editor such as Visual Studio Code, Atom, or Notepad++.
ファイルを削除するためにRemove-Itemコマンドレットを使用する
ファイルを削除するために単純にPowerShellを使用する必要がある場合、おそらくすぐにRemove-Item
コマンドレットについて学ぶことでしょう。このコマンドレットは、PowerShellでファイルを削除するための事実上の標準です。
Remove-Item
をGet-ChildItem
コマンドレットと組み合わせてファイルとフォルダを読み取り、強力なPowerShellパイプラインを利用すると、作業が簡単になります。
関連記事:Get-ChildItem:ファイル、レジストリ、証明書などの一覧表示
Remove-Item
コマンドレットには、del
という別名があることを知っていましたか?PowerShellで作業する際に、Remove-Item
またはdel
を使用すると同じコマンドが実行されます。
ファイルを削除するためにPowerShellを使用する
最も役立つ最初の例は、最も基本的なものです。つまり、単一のファイルを削除することです。単一のファイルを削除するには、以下のコマンドを使用するだけです。以下のコードは、ファイル C:\temp\random.txt を削除します。
このコードをPowerShellで実行すると、エラーが発生しない限り、画面には何も表示されません。
フォルダ内のすべてのファイルを削除するためにPowerShellを使用する
この例では、以下のコードはフォルダ内のすべてのファイルを削除します。 Get-ChildItem
cmdletは、-Path
パラメータを使用して C:\temp を対象にします。 -File
パラメータは、ファイル のみを含めることを示します。 Get-ChildItem
はフォルダを無視します。
出力は以下のスクリーンショットのようになります。

PowerShellを使用してすべてのファイルを再帰的に削除する
前の例では、C:\temp フォルダ内のファイルのみが削除されました。すべてのサブディレクトリ内のファイルも削除する場合は、Get-ChildItem
cmdletに -Recurse
スイッチを追加してファイルを再帰的に取得する必要があります。
上記のコードを実行すると、PowerShellはすべてのサブフォルダを調べ、ファイルの一覧を取得します。以下の出力は、コードがトップフォルダ内のファイルを削除できたことを示していますが、サブフォルダ内のファイルを取得できなかったことを示しています。

長いパスの問題に対処する
上記のエラーは、PowerShellが 「パスの一部が見つかりませんでした」ということを示しています。このエラーは、cmdletがアクセスしようとしているパスが存在しないことを示しており、誤解を招くものです。
この場合、エラーは、Get-ChildItem
が読み取ろうとしているパスが、260文字の最大パス長を超えているためです。
以下のスクリーンショットは、パスまたはディレクトリとそのサブディレクトリが存在し、1つのテキストファイルであるInTooDeep.txtが最も下位のサブディレクトリに存在していることを示しています。ネストされたディレクトリ名を構成するすべての文字の組み合わせが、長いパスの問題を引き起こしています。

Windows PowerShell 5.1では、長いパス名の問題に対する回避策があります。回避策は、パスのUnicodeバージョンを使用することです。パスを次のように指定する代わりに- C:\temp、このようにUnicodeバージョンを使用します- ‘\\?\C:\temp’(ローカルに位置するフォルダの場合)、または’\\?\UNC\<computername>\<share>\Temp’(フォルダがUNCパスに位置する場合)
長いパス名に対応した変更済みのコードを使用して、上記の出力は、PowerShellが深くネストされたパス名を正常に読み取り、ファイルを削除したことを示しています。

長いパス名の問題はPowerShell 7.0には影響しません。PowerShell 7.0では、長いパス名に対する組み込みサポートが既にあるため、Unicodeバージョンのパスを使用する必要はありません。
フォルダも削除する必要がある場合は、Get-ChildItem
コマンドレットから-File
パラメータを削除し、PowerShellはファイルとフォルダを含むすべてのアイテムを削除するはずです。
PowerShellを使用してx日より古いファイルを削除する
ディスクスペースの整理のもう一つの典型的な例として、特定の日数よりも古いファイルを削除することが挙げられます。この例では、IISウェブサーバーによって生成されるような古いログファイルを削除してディスクスペースを解放するのに役立ちます。
この例では、c:\tempに14日よりも古いファイルがあります。以下のスクリプトを使用すると、c:\tempの各ファイルのName
、CreationTime
、およびAgeInDays
が表示されます。
以下のスクリーンショットで確認できるように、15日前、7日前、および0日前のファイルがあります。

削除するファイルを把握したので、特定の日数よりも古いファイル(この場合は14日よりも古い)のみを削除するスクリプトを作成できます。
以下の例のスクリプトでは、C:\tempにあるCreationTime
の値が設定された閾値よりも古いファイルが削除されます。
最初の行では、Get-ChildItem
が検索するパスを定義しています。パスは$path
変数に保存されます。次に、2行目で閾値が指定されます。$threshold
の値は削除するファイルの年齢(日数)を表します。
$threshold
変数の次のコード行では、以下のことを行います:
$path
変数で指定されたフォルダにあるファイルのコレクションを取得します。この例では、パスはC:\tempです。$threshold
変数に保存された日数よりもCreationTime
の値が古いファイルのみを出力に含めます。この例では、閾値は14日です。- フィルタリングされたファイルのリストを
Remove-Item
にパイプして、それらのファイルを削除します。
上記のコードを実行すると、以下のような出力が表示されます。

上のスクリーンショットからわかるように、詳細メッセージに基づいて、スクリプトは14日前より古い5つのファイルのみを削除しました。14日より新しいファイルがまだ存在することを確認するために、以下のコードを実行して再度リストアップします。
以下の結果は、Remove-Item
が新しいファイルを削除しなかったことを確認しています。

PowerShellを使用してファイルのパターンを一致させて削除する
ファイルの名前、種類、拡張子に関係なく、すべてのファイルを削除することは常に最善の方法ではありません。削除プロセスで特定のファイルを明示的に除外または含める必要がある場合があります。
次の例では、*.LOGというファイル名に一致するファイルを削除する方法を示しています。一つの方法は、-Include
パラメータを使用してRemove-Item
コマンドレットを直接使用する方法です。
もう一つの方法は、おそらく慎重なアプローチとして、まずGet-ChildItem
を使用して削除するファイルのリストを収集することです。削除するファイルのリストに満足した場合にのみ、収集したリストをRemove-Item
コマンドレットにパイプすることができます。
たとえば、以下のコードでは、c:\temp内の*.LOGファイルを取得します。
上記のコードの結果、Get-ChildItem
は*.LOGファイル名に一致するファイルのリストを返します。

しかし、名前に数字5が含まれるファイルを除外したい場合はどうすればよいでしょうか?次のコードのように、-Exclude
パラメータを追加することで除外することができます。
数字5のファイルが除外されたため、結果は異なります。具体的には、以下のようにファイルFile_5.logはリストに含まれなくなります。

コードで作成されたファイルのコレクションに満足したら、Remove-Item
コマンドレットにファイルのコレクションをパイプして、最終的にそれらのファイルを削除することができます。
最終的なコードを実行すると、選択したファイルのみを削除する目標を達成することができます。

PowerShellを使用したWMIを使用してファイルを削除する
共通のRemove-Item
コマンドレットを使用してファイルを削除する方法についての理解ができたので、より高度な使用例であるWMIの使用について説明します。
PowerShellにはWMIのサポートが付属しています。そして、WMIのサポートとは、PowerShell内からWMIクエリとメソッドを呼び出すことができることを意味します。そうです、WMIはWindowsの初期の日々に管理者が使用したVisual Basicスクリプトだけのものではありません。
MicrosoftはPowerShell 3.0でWMI固有のCIMコマンドレットをリリースしました。ファイルを削除するために使用されるCIMコマンドレットは、Get-CimInstance
とInvoke-CimMethod
です。
PowerShellとWMIを使用してファイルを削除する
この例では、削除する特定のファイルのパスを知っていることを前提としています。 Get-CimInstance
コマンドレットを使用して、削除するファイルの情報を取得するために、Cim_DataFile
クラスを使用します。この例では、削除するファイルはC:\Temp\random.txtです。
上記のコードでは、-Filter
パラメーターはWQL形式のクエリを受け入れます。WQLを使用する場合、バックスラッシュなど一部の文字をエスケープする必要があります。また、WQLのエスケープ文字もバックスラッシュであるため、バックスラッシュが2重化された文字\\
になります。
上記のコードを実行すると、以下のデモンストレーションに示す結果が得られます。 C:\Temp\random.txtの情報が$file2delete
変数に保存されます。

今、ファイルC:\Temp\random.txtの情報が取得されたので、$file2delete
変数内のオブジェクトをInvoke-CimMethod
コマンドレットにパイプすることができます。 Invoke-CimMethod
コマンドレットには、-Name
というパラメーターがあり、Cim_DataFile
クラスのメソッド名を表します。
以下のスクリーンショットで示されているように、ReturnValue
が0と表示されており、これはコマンドが成功したことを意味します。

可能なReturnValueコードについては、このリンクを参照してください – CIM_DataFileクラスのDeleteメソッド
さらに、以下のスクリーンショットは、Invoke-CimMethod
Delete()
メソッドを実行した後、CIMがC:\Temp\random.txtファイルのみを削除したことを示しています。他のファイルは削除されませんでした。

PowerShellとWMIを使用してフォルダ内のすべてのファイルを削除する方法
次の例では、PowerShellとWMIを使用してフォルダ内のすべてのファイルを削除する方法を示します。前の例で使用されたGet-CimInstance
とInvoke-CimMethod
のコマンドレットが使用されます。ただし、今回はWQLクエリがフォルダ内のすべてのファイルを取得します。
次のコードでは、Get-CimInstance
コマンドレットがC:\tempにあるすべてのファイルを取得します。以下のように、クエリはCim_DataFile
クラスのDrive
およびPath
プロパティをフィルタリングします。
上記のコードを実行すると、$file2delete
変数にC:\tempのファイルに関する情報が保存されます。$file2delete
変数の値を表示すると、以下の出力が表示されます。

今、$file2delete
変数に格納された値をInvoke-CimMethod
にパイプして、c:\tempのすべてのファイルを削除できます。
ReturnValue
コードが0の場合、成功を意味します。また、deleteメソッドが呼び出された各ファイルには、個別のReturnValue
コードが付いています。

PowerShellとWMIを使用して拡張子でファイルを削除する
前の例では、拡張子に関係なくフォルダ内のすべてのファイルを削除する方法を見てきました。しかし、拡張子に基づいて削除するファイルを制御することもできます。
以下のコードで確認できるように、今回のクエリには追加条件(Name LIKE '%.log
)があります。この追加条件は、.LOG拡張子に一致するファイルのみが返されることを意味します。パーセント(%
)記号は、WQLのLIKE演算子であり、「0個以上の文字列」を意味します。プログラミング用語では、%
はワイルドカードを表すアスタリスク(*
)文字と同じです。
以下のデモンストレーションは、上記のコードが実行される前に、9つの.LOGファイルと1つの.TXTファイルが存在することを示しています。コードの実行が終わると、*.LOGファイルが削除され、フォルダ内には*.TXTファイルだけが残ります。

WMIとRemove-Itemの比較
これまでのチュートリアルでは、PowerShellを使用してファイルを削除する方法の概要を広く学びました。Remove-Item
とWMIの両方について学びました。両方の機能は似ていますが、非常に異なる方法で動作します。
ファイルを削除するためには、どちらの方法を使用すべきですか?Remove-Item
またはWMI?
PowerShellの組み込みのコマンドレットであるGet-ChildItem
とRemove-Item
を使用してファイルを取得および削除すると、WMIを使用する場合よりもはるかに高速です。
以下の例では、WMIと組み込みのPowerShellコマンドレットを使用して、C:\windows\webディレクトリとそのサブディレクトリのファイルのリストを取得する場合の比較を示しています。
上記のコードをPowerShellで実行すると、以下のような出力が表示されます。

上記の出力からわかるように、C:\windows\webのファイルをリストするには、Get-CimInstance
を使用する場合は10倍ほど時間がかかりましたが、Get-ChildItem
の場合は短時間で完了しました。
また、Get-ChildItem
の行がGet-CimInstance
よりもずっと短いことに気づきましたか? Get-ChildItem
を使用すると、実行がより高速になるだけでなく、コードもよりシンプルで短くなります。
次の手順
この記事では、組み込みのコマンドレットとWMI/CIMを使用してファイルを削除するPowerShellの2つの異なる方法を紹介しました。
常にGet-ChildItem
およびRemove-Item
コマンドレットを使用してファイルを削除することを覚えておいてください。これらの組み込みのコマンドレットは、WMIを使用する場合よりも柔軟で簡単で高速です。
ディスクスペースの整理を行うスクリプトを作成することを試みてください。もちろん、その目的で既に存在するスクリプトがあるかもしれません。それらを参考にしても構いませんが、練習して学びたいのであれば、独自のスクリプトを作成してみてください。
さらなる読み物
Source:
https://adamtheautomator.com/powershell-to-delete-files/