PowerShell でフォルダサイズの一覧を取得する話です。ハードディスクがパンパンになった時に原因になっているフォルダを特定できます。
たぶん私が書いた最初の PowerShell スクリプトです。
C ドライブの容量が一杯
たしか社会人4年目。職場の先生から、パソコンの容量が一杯になっていて困っていると相談されました。エクスプローラで見ると C ドライブの容量が真っ赤っ赤。空き容量0。ファイルのコピーすらできないので仕事になりません。
ちなみに D ドライブはなく、普段からデータはファイルサーバ上の個人フォルダか共有フォルダに保存しています。
サイズが大きいフォルダを探す
サイズの大きいフォルダやファイルを見つけて、削除するなり移動させるなりしなければいけません。
まずは容量を占めているフォルダの特定から。上述の通り C:\Users\[ユーザ名]\
はほとんど空なので、怪しいのはC:\Program Files\
や C:\Windows\
でしょうか。
フォルダサイズを見るのが面倒
ところでフォルダサイズを見るのって面倒ですよね。ファイルのサイズはエクスプローラ上に出ますが、フォルダのサイズはプロパティからしか見られません。
フォルダのプロパティの見方にはこんなのがあります。
- (マウスで操作)フォルダを選択→右クリック→「プロパティ」
- (キーで操作)フォルダを選択→
Alt + Enter
ひとつひとつ、心を込めて Alt + Enter
。サイズを確認。容量が大きいフォルダはサイズの計算に時間がかかります。しばらく待って容量が出たら、次のフォルダで Alt + Enter
......
4つ目くらいで込める心が尽きました。
PowerShell を使うことにする
VBA を始めて一年。これはプログラムでなんとかなると判断しました。さっそく VBA でなんとかしようと思ったのですが、
- フォルダ内のファイルの一覧を取得する
- それぞれのサイズを合計する
- それを全てのフォルダに対して行う
というのが当時の私にはできそうにありませんでした。
FSO
を使えばできるのはわかっていたのですが、やったことなかったし、もう遅い時間で疲れていたし……ごにょごにょ。
ということで別の方法を考え、Windows PowerShell を使うことに決めました。実はこんなこともあろうかとフォルダサイズの取得方法を調べていて、 PowerShell を使う方法を見つけていたのです。加えてちょうど PowerShell に興味を持ち始めた時期でもありました。
さっそくコンソールを開いてカタカタ。上手にできるかな?
結局勘と手作業
できませんでした。そりゃそうさ。比較的慣れている VBA でもできなかったことが初めての PowerShell でできるはずがない。
結局ネットで検索したりそれらしきフォルダをひとつひとつ心を込めて見たりして手作業で解決したのでした。ちなみに原因は pagefile.sys
と hiberfil.sys
でした。2つのファイルを削除してとりあえず終了。たしかそんな感じでした。
リトライ
このままじゃ終われない。私のプライドが許さない。何よりこのままでは次も手作業になる。それは嫌だ! もう心込めたくない!
ということで、ネットで調べなおしてスクリプトを書きました。こちらのサイトをほぼそのまま使わせていただきました。(肝心のコードは見られなくなっていますね)
実際のコード
function Get-DirectorySizeList { $dirs = Get-ChildItem -Recurse -Force -Directory -ErrorAction SilentlyContinue [double]$size = 0 $result = @() foreach ($d in $dirs) { $size = (Get-ChildItem $d.FullName -Force -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum $result += [PSCustomObject]@{ LastWriteTime = $d.LastWriteTime Length_GB = [Math]::Round($size / 1GB, 2) Length_MB = [Math]::Round($size / 1MB, 2) Length = $size FullName = $d.FullName } } return $result | Sort-Object -Property FullName }
VBA との比較
VBA と違っていて戸惑ったこと
PowerShell の醍醐味であろうパイプラインの概念が全く分かっていませんでした。「左から来たものを右に受け流す」という動きはとってもムーディですね。
PSCustomObject
も理解できず、まさに「よくわかんないけど動いた」という状態でした。
書式の面でも戸惑いました。たとえばパラメータとオプションの -
の有無。
Get-ChildItem -ErrorAction SilentlyContinue
Get-ChildItem ErrorAction -SilentlyContinue
Get-ChildItem ErrorAction SilentlyContinue
どれが正解か分かりませんでした。
他にも PowerShell のコマンドレットと .NET のメソッドとの間で、()
や ,
の有無で迷ったりしました。
VBA よりも好きなところ
コマンドレットがの命名規則が好みです。動詞-単数名詞
で統一してあります。一番いいのは単語を省略していないところです。そのおかげで比較的英語を読むようにコードを読めます。
それから配列に要素を追加するのが楽ですね。要素が増えすぎると重たくなるけど。
VBA だと、こう。
n = n + 1 ReDim Preserve arr(n) arr(n) = 123
PowerShell なら、こう。
$arr += 123
一連の流れを終えて
そんなこんなで PowerShell に魅了された私は、業務では主に VBA を使いつつ PowerShell でも遊ぶという日々を送っていくのでした。
続編
一年後、このテーマに再挑戦しました。よかったらその話もどうぞ。
さらにその続編です。こちらもぜひ。
シリーズ最終作です。最後までどうぞ。