Powershell: ローカルドライブの巨大ファイルを見つける

時々、パソコンのユーザーから、「ドライブCがいっぱいでアプリケーションを開けなくなったので何とかして欲しい」と、ふざけんじゃないよ〜と言いたくなる問い合わせがあります。
「あなたのPCのドライブの内容なんて知りませんよ。」と言いたいところなんですが、会社PCの場合、複数ユーザーで1台のPCを共有しているものがあるので、対象がそういう共有PCの場合、対応が面倒です。
共有PCの管理者ではないユーザーAはユーザーBフォルダーの下を知ることが出来ませんからね。ユーザーが10人ともなると、管理者ではないユーザーは他ユーザーのフォルダー容量を知ることが出来ませんので、誰が犯人かはわかりません。

同様にアクセス権の問題で Program filesフォルダーの下とか、Windowsフォルダー下にどれくらいの容量が食われているのかを知ることが出来ないケースがあります。
いずれにせよ、PCの管理者権限が必要になるので、こういうリクエストが発生するわけです。

個人フォルダーが巨大なユーザーを見つけるには、

  1. システムのプロパティ→詳細設定→ユーザープロファイル でユーザーのトータルディスク使用量を知る
  2. bash を管理者として起動して、/mnt/c/Users 下を du -s * で計算する
  3. powershell など、スクリプトで計算する

などが考えられます。

Unixなら find や du コマンドがあるので、結構簡単なんですけどね。個人的には上記2が一番使い易いのですが、残念ながら bash はWindows10のオプション。32bit WindowsではWSLを入れることさえ出来ません。

システムプロパティーを使うのは、OSの機能を使えるのがいいところなんですが、容量を大量消費しているユーザーを見つけることは出来ても、何のフォルダーが巨大なのかが分かりません。

やむなく、「powershellで大きなフォルダーを見つける」でWeb検索してみたところ、

https://www.gmo.jp/report/single/?art_id=210

が見つかりました。以下は、その sample1 の転記。赤字の部分が編集すべきポイント。

Param(
$RootFolder = "C:\Program Files"
)
 
$Items = (Get-ChildItem -Path $RootFolder -ErrorAction "SilentlyContinue" -Force | Where-Object {$_.GetType().Name -eq "FileInfo"} | Measure-Object -Property Length -Sum)
[Array]$Folders = [PSCustomObject]@{
    "Fullname" = $RootFolder
    "Size(MB)" = ("{0:N1}" -F ($Items.Sum / 1MB))
    }
 
$Items = (Get-ChildItem -Path $RootFolder -ErrorAction "SilentlyContinue" -Recurse | Where-Object {$_.GetType().Name -eq "DirectoryInfo"})
$Folders += ForEach ($i in $Items)
{
    $SubFolderItems = (Get-ChildItem -Path $i.FullName -ErrorAction "SilentlyContinue" -Force | Where-Object {$_.GetType().Name -eq "FileInfo"} | Measure-Object -Property Length -Sum)
 
    [PSCustomObject]@{
    "Fullname" = $i.FullName
    "Size(MB)" = [decimal]("{0:N1}" -F ($SubFolderItems.Sum / 1MB))
    }
}
 
$Folders | Sort "Size(MB)" -Descending  | Select-Object -First 20 | Format-Table -AutoSize
Fullname                                                                                               Size(MB)
--------                                                                                               --------
C:\Program Files\Windows XP Mode                                                                         1354.6
C:\Program Files\NVIDIA Corporation\Installer2\Display.Driver.{76A353B3-4985-4627-843E-F577BDDB290B}      298.2
C:\Program Files\NVIDIA Corporation\Installer2\Display.Driver.{D00ED827-D0C9-4A77-B973-F2693D41BF9B}      282.6
C:\Program Files\Oracle\VirtualBox                                                                        147.3
C:\Program Files\NVIDIA Corporation\Display                                                               105.6
C:\Program Files\Microsoft Silverlight\5.1.50918.0                                                         50.9
C:\Program Files\Common Files\microsoft shared\ink                                                         41.2
C:\Program Files\rempl\Logs                                                                                25.3
C:\Program Files\NVIDIA Corporation\Control Panel Client                                                   24.9
C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0                                             22.4
C:\Program Files\BOINC                                                                                     18.9
C:\Program Files\NVIDIA Corporation\Installer2\Display.3DVision.{520E41E5-593A-427E-87D3-062CBF93F374}     17.5
C:\Program Files\Windows Defender                                                                          14.2
C:\Program Files\Oracle\VirtualBox\nls                                                                     12.2
C:\Program Files\Windows Defender Advanced Threat Protection                                               11.8
C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5                                             10.6
C:\Program Files\NVIDIA Corporation\Installer2\CoreTemp.{541C1400-0F25-49EF-A7F1-97F6F84A56A9}             10.2
C:\Program Files\NVIDIA Corporation\Installer2\CoreTemp.{80E99450-4302-4349-AF15-A0E25E227A49}              9.1
C:\Program Files\NVIDIA Corporation\Installer2\CoreTemp.{9C78E31E-7059-4EFB-901B-C925E10E608E}              9.1
C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore                                                9.1

スキャンするフォルダーを Program Files から Users に変更して実行したのが以下。

Fullname                                                                                                            Size(MB)
--------                                                                                                            --------
C:\Users\Public\Documents\Hyper-V\Virtual hard disks                                                                 46325.0
C:\Users\tahonda\Documents\radika\kirakira                                                                            41963.2
C:\Users\Public\Documents                                                                                            40217.7
C:\Users\tahonda\VirtualBox VMs\ubuntu                                                                                13049.1
C:\Users\tahonda\Documents\radikool\records\TBS                                                                       10434.1
C:\Users\tahonda\Documents\radika                                                                                     10180.2
C:\Users\tahonda\Documents\RadioMate Record Files\AM954_TBS                                                            5503.8
以下略

ファイルとサブフォルダーを含むフォルダーの計算方法が重複しまくるので、数値は正確ではありませんが、大まかなファイルの場所が分かります。

一言でディスク容量が逼迫していると言っても、いろんなパターンがあります。VMの仮想ディスクのように1個で巨大なファイルもありますし、アプリケーションのインストーラ残骸のように、一つのフォルダーの下に小さいファイルがたくさん置かれているような場合があります。前者のVM仮想ディスクの場合は巨大ファイルを見つけたとしても消去するわけには行かないでしょうし、後者のケースでは、大きなファイルを探しても見つからないわけですよ。

上記の Program Files を計測した結果では、NVIDIAのドライバーと、XP mode がディスクを使用しているという傾向が見えてきます。
Users以下は、VMの仮想HDDとラジオ番組録音ファイルが多いことが分かります。

まずは正確な数字を掴むよりも、ユーザーフォルダーの傾向を知ることが出来るコマンドの方が作業するには都合が良い場合があるためこのスクリプトで十分。正確でも、ファイルのスキャンに数十分〜数時間掛かるというのも勘弁です。

この Powershellスクリプトの作者の方に感謝です。

この後で、リクエストされたPCにリモートデスクトップで接続し、管理者としてフォルダーをスキャン。
結果をユーザーに伝えてお終い。

本当は、リモートデスクトップ接続せず、リモートコマンド実行で結果だけ取りたいところなんですが、とりあえずはこれでいいでしょう。

コメントを残す