サーバーやシステムを管理する際に、空きディスク容量を維持することは重要です。管理者としては、「ディスクフル」の状況に不意をつかれたくありません。安心して作業を続けるためには、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 Cmdletを使用する
ファイルを単に削除する必要がある場合、おそらくすぐに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
コマンドレットは -Path
パラメータでC:\tempを対象とします。 -File
パラメータは、含めるアイテムの唯一のタイプがファイルであることを示します。 Get-ChildItem
はフォルダを無視します。
出力は以下のスクリーンショットのようになります。

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

長いパスの問題を回避する
上記のエラーは、PowerShellが“パスの一部が見つかりませんでした”と表示しています。 このエラーは、コマンドレットがアクセスしようとしているパスが存在しないことを示しています – これは誤解を招くものです。
この場合、エラーの原因は、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
cmdletから-File
パラメータを削除するだけで、PowerShellがファイルとフォルダを含むすべてのアイテムを削除するはずです。
x日より古いファイルを削除するためにPowerShellを使用する
ディスク容量の整理の典型的な例のもう一つは、特定の日数よりも古いファイルを削除することです。この例は、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ファイル名に一致するファイルを削除する方法を示しています。これを行う方法の1つは、-Include
パラメーターを使用してRemove-Item
コマンドレットを直接使用する方法です。
もう1つの方法は、おそらく、慎重なアプローチであると言えるでしょう。まず、Get-ChildItem
を使用して削除するファイルのリストを収集します。削除するファイルのリストに満足した場合にのみ、最終的にコレクションをRemove-Item
コマンドレットにパイプします。
たとえば、以下のコードは、c:\temp.内の*.LOGファイルを取得します。
上記のコードの結果として、Get-ChildItem
が*.LOGファイル名に一致するファイルのリストを返します。

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

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

PowerShellを使用してファイルを削除する
これで、ファイルを削除するための一般的な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 のエスケープ文字もバックスラッシュであるため、二重バックスラッシュ文字 \\
が生成されます。
上記のコードを実行すると、以下のデモで示されている結果が生成されます。 C:\Temp\random.txt の情報は $file2delete
変数に保存されます。

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

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

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

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

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

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

上記の出力からわかるように、Get-CimInstance
を使用してC:\windows\webのファイルをリストするのに、Get-ChildItem
が完了するのにかかった時間の約10倍の時間がかかりました。
また、Get-ChildItem
の行がGet-CimInstance
よりもはるかに短いことに気づきましたか?Get-ChildItem
を使用すると、実行が高速になるだけでなく、よりクリーンで短いコードを得ることができます。
次のステップ
この記事では、組み込みのcmdletおよびWMI/CIMを使用してファイルを削除するPowerShellの2つの異なる方法を見てきました。
ファイルを削除する場合は常にGet-ChildItem
およびRemove-Item
cmdletを使用する必要があることを知っておいてください。これらの組み込みのcmdletは、WMIを使用する場合よりも柔軟で簡単で高速です。
ディスクスペースの整理を自動化するスクリプトを作成してみてください。既存のスクリプトを参考にしても構いませんが、練習して学びたいのであれば、自分で作成してみてください。
さらなる参考資料
Source:
https://adamtheautomator.com/powershell-delete-file/