さらば、全てのフォルダのプロパティを見る作業。
4部構成の最終作。長編です。
この話の続きです。
これまでの「PowerShell でフォルダサイズの一覧を取得する」
:1.0 ではフォルダサイズの一覧を取得するのに PowerShell を使ってみました。私が創り出した最初の PowerShell スクリプトです。
:2.0 で、:1.0 のスクリプトを1年越しに書き直し、one-liner 版と function 版を作りました。
:3.0 で、取得したフォルダサイズを CSV ファイルに出力して再利用できるようにしました。
そして今回が最終作。効率化を求めるタイダログの物語は、どこへと続くのか。
- これまでの「PowerShell でフォルダサイズの一覧を取得する」
- 右クリックから実行できるようにする
- Measure-Directory の説明を書いてなかった
- サブディレクトリも含めたサイズを取得する
- さようなら、全てのフォルダのプロパティを見る作業
- 更新履歴
右クリックから実行できるようにする
ある時、ふと思いました。「いちいちコンソールを開くより、右クリックで使えた方が楽なのでは?」怠惰だからね。
そんなわけで、対象のフォルダを右クリックして、コンテキストメニューからスクリプトを実行できるようにしましょう。
スクリプトを用意する
今回必要なものは以下の2つです。
- フォルダサイズの一覧を取得する function (.psm1)
- function を呼び出すスクリプト (.ps1)
適当なフォルダを作り、そこに上の2つを保存します。今回はドキュメントフォルダ内に "get_the_list_of_directory_size" フォルダを作成することにします。
function (Measure-Directory) は以前のものを流用します。Gist からスクリプトをダウンロードして .psm1
のまま保存してください。今回は "get_the_list_of_directory_size.psm1" で保存することにします。
get_the_list_of_directory_size.psm1 · GitHub
function を呼び出すスクリプトは以下の通りです。.ps1
で保存してください。今回は "caller.ps1" で保存することにします。
$measureDirectoryModuleName = "get_the_list_of_directory_size.psm1" $measureDirectoryModulePath = Join-Path $PSScriptRoot $measureDirectoryModuleName Import-Module $measureDirectoryModulePath -Force $csvFilePrefix = "DirectorySizes_" $datetimeFormat = "yyyy-MM-dd_HH-mm-ss" $csvExtension = ".csv" $csvPath = Join-Path ([Environment]::GetFolderPath("MyDocuments")) "$($csvFilePrefix)$((Get-Date).ToString($datetimeFormat))$($csvExtension)" foreach ($a in $args) { Get-ChildItem -LiteralPath $a -Recurse -Directory | Measure-Directory | Export-Csv -Path $csvPath -Encoding utf8 -Append -NoTypeInformation } Pause
最終的なフォルダ構成はこのようになります。
D:\Users\taidalog\Documents └──get_the_list_of_directory_size ├─caller.ps1 └─get_the_list_of_directory_size.psm1
ショートカットファイルを作る
caller.ps1
へのショートカットファイルを作成して、ファイル名を分かりやすいように変えてください。今回は「フォルダサイズの一覧を取得する」にします。
※get_the_list_of_directory_size.psm1
へのショートカットファイルではありません。
次にプロパティを開いて「リンク先(T):」の先頭に以下の文字列を追加します。元々入っている文字列を消さないように注意してください。スクリプトをネットワーク上に置く場合は、RemoteSigned
を Bypass
に変更してください。
PowerShell -ExecutionPolicy RemoteSigned -NoExit -File
最終的にこうなります。
PowerShell -ExecutionPolicy RemoteSigned -NoExit -File D:\Users\taidalog\Documents\get_the_list_of_directory_size\caller.ps1
「適用(A)」をクリックすると PowerShell
の部分が C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
に変わりますが、それが正常です。
同時にアイコンも変わるはずです。変わっていなかったら何か間違っている可能性があります。
-File
が重要です。これが無くても動くには動きますが、パスに半角スペースや半角カッコが入っているとエラーになります。私はこれを抜かしていたために来る日も来る日もエラーを大量生産していました。
「送る(N)」に追加する
これで最後。いよいよ右クリックに登録します。
右クリックメニューへの登録を調べるとレジストリをいじる方法が出てきて諦めてしまう人もいると思います。実はもっと簡単な方法があります。
コンテキストメニューの「送る(N)」って使ったことありますか?
エクスプローラでファイルやフォルダを右クリックするとメニューが出ますよね。その中に「送る(N)」という項目があるはずです。
たとえば、この中の「ドキュメント」を選択すると、右クリックしたファイルやフォルダをドキュメントフォルダに送ることができます。送るという言葉からファイルの移動(=切り取り+貼り付け)を想像しましたが、実際にはコピーを行うようですね。
ここにフォルダのショートカットファイルを追加すると、「送る(N)」からそのフォルダにコピーできるのですが、ここにスクリプトのショートカットファイルを追加すると、「送る(N)」からスクリプトを起動できるようになるのです。
というわけやってみましょう。Win + R
で「ファイル名を指定して実行」を開き、shell:sendto
と入力してOK してください。
「SendTo」というフォルダが開きましたね。ここに、先ほど作成したショートカットファイルを切り取り+貼り付けします。
さて、コンテキストメニューを開くと……
いょっしゃぁぁ! できました!
知恵と意志を持つ人類が、管理者権限の助けなしにここまで来てるよ。
使い方
- エクスプローラーを開き、
- サイズを知りたいフォルダを選択し、
- 右クリック→送る(N)→フォルダサイズの一覧を取得する
です。
これでフォルダサイズの一覧が CSV ファイルになってドキュメントフォルダに出てきます。もちろん、フォルダを複数選択して右クリック→(以下略)すれば、まとめてサイズを取得できます。その分時間がかかりますけどね。
※CSV ファイルから取り込んだ段階では、数字のデータであっても文字列になっています。これを数値に変換する方法は、:3.0の記事を参照してください。
PowerShell でフォルダサイズの一覧を取得する:3.0 REDO. - タイダログ
Measure-Directory の説明を書いてなかった
そもそも Measure-Directory
の説明を書いていませんでした。この function は、
- 受け取ったフォルダの直下のファイルサイズを合計し、(=そのフォルダのサイズ)
- そのフォルダの Path その他諸々とまとめて
PSCustomObject
で出力する
ということをしています。
フォルダはパイプラインから受け取れます。Get-ChildItem -Recurse -Directory
で渡してください
また、出力した PSCustomObject
もパイプラインで次のコマンドレットに渡せます。Select なり Sort なり Where なり何でもどうぞ。
サブディレクトリも含めたサイズを取得する
フォルダAの中にフォルダBとフォルダCがあるとします。それぞれのフォルダ内にはファイルがあります。
A ├─B └─C
上で説明した通り Measure-Directory では、Aのサイズとして取得できるのはA直下のファイルのサイズの合計です。BやCの中身は含んでいません。
ですがBやCを含んだ形でフォルダサイズを知りたいこともあるでしょう。ということで、サブディレクトリ対応型スクリプト8号機です(たぶんシリーズ中8個目くらいのスクリプト)。上記の caller.ps1
の代わりにこれを「送る(N)」に追加してください。
$measureDirectoryModuleName = "get_the_list_of_directory_size.psm1" $measureDirectoryModulePath = Join-Path $PSScriptRoot $measureDirectoryModuleName Import-Module $measureDirectoryModulePath -Force $csvFilePrefix = "DirectorySizes_" $datetimeFormat = "yyyy-MM-dd_HH-mm-ss" $csvExtension = ".csv" $csvPath = Join-Path ([Environment]::GetFolderPath("MyDocuments")) "$($csvFilePrefix)$((Get-Date).ToString($datetimeFormat))$($csvExtension)" [long]$n = 0 foreach ($a in $args) { $directorySizes = Get-ChildItem -LiteralPath $a -Recurse -Directory | Measure-Directory foreach ($ds in $directorySizes) { [long]$lengthTotal = 0 $subDirectoriesAndItself = @($directorySizes | Where-Object {$_.FullName -match "$([regex]::Escape($ds.FullName))(\\.+)?"}) if ($subDirectoriesAndItself.Length -gt 0) { $lengthTotal = ($subDirectoriesAndItself | Measure-Object -Property Length -Sum).Sum } $ds | Select-Object ` @{label="Length"; expression={$_.Length}}, @{label="LengthMB"; expression={$_.LengthMB}}, @{label="LengthGB"; expression={$_.LengthGB}}, @{label="LengthTotal"; expression={$lengthTotal}}, @{label="DirectoryCount"; expression={$subDirectoriesAndItself.Length}}, @{label="FullName"; expression={$_.FullName}} | Export-Csv -Path $csvPath -Encoding utf8 -Append -NoTypeInformation $n++ $writeProgressParameters = @{ Activity = "フォルダサイズの一覧を取得中……" Status = ([string]::Format("{0,8} 個目のフォルダを処理しています。", $n)) Id = 0 PercentComplete = -1 } Write-Progress @writeProgressParameters } } Pause
それぞれのフォルダに対していちいちサブディレクトリを取得していては無駄が多くなります。ですので、一度、全てのフォルダにおいて、それ自身のフォルダサイズのみを取得した後、正規表現で自身とそのサブディレクトリを抽出してサイズを合計しています。
サブディレクトリは、「自身のパス + "\" + 何かしらの文字列」と考えればいいですね。正規表現では 自身のパス\\.+
と表せます。ただこれだと「自身のパス」だけのものが引っかかりません。自身のパス(\\.+)?
とすることで、「自身のパス」と「自身のパス\何かしらの文字列」の両方を抽出することができます。
さようなら、全てのフォルダのプロパティを見る作業
私と Windows PowerShell の出会いのきっかけでもある「フォルダサイズの一覧を取得する」シリーズもこれで終わりです。
今回紹介したスクリプトを GitHub に上げました。よろしければどうぞ。
taidalog /
get_the_list_of_directory_size - GitHub
仕事の上でフォルダサイズを知りたいことはあっても、それが仕事の中心ということはあまりないと思います。このシリーズを読んでくださった方が、サクッとフォルダサイズの一覧を取得できて、本来のお仕事に時間をより多く割けたら、わたしも幸いです。
終劇
更新履歴
- 「Measure-Directory の説明を書いてなかった」のコードを訂正(半角スペースを追加) (2021/07/28)
- GitHub へのリンクの文字列を変更 (2021/08/22)
- 目次の下に「こちらもどうぞ」を追加 (2021/09/09)
- 「こちらもどうぞ」を更新 (2023/04/24)