技術者情報
ソリューション
2016年8月31日(水)公開
第200回
記事INDEX
Sample1.ps1
→ Sample1.ps1 ファイルダウンロード
Sample2.ps1
→ Sample2.ps1 ファイルダウンロード
この2つのスクリプトは、Get-ChildItemコマンドを利用して、指定したフォルダと配下のすべてのサブフォルダを探索して、容量の大きい上位20件を表示します。
Sample1.ps1は、フォルダ内のファイルの合計サイズを集計してフォルダサイズとしています。含まれるサブフォルダの容量は含まれておらず、純粋なフォルダ内のファイルの合計サイズとなります。
Sample2.ps2はフォルダ内のすべてのファイルとサブフォルダの合計サイズを集計しています。スクリプト内ではPowerShellの特徴である「パイプライン」を利用して、効率的にスクリプトを作成しています。Sample1.ps1とSample2.ps1のコードの違いは5行目と14行目の2箇所だけです。Sample1.ps1を元にコードを見ていきましょう。
まずはルートフォルダ直下のファイルサイズを合計してフォルダサイズを取得します。パラメーターとして、探索対象のフォルダパスをルートフォルダとして指定します。パイプランを分解して一つずつ見ていきましょう。
$Items = (Get-ChildItem -Path $RootFolder -ErrorAction "SilentlyContinue" -Force | Where-Object {$_.GetType().Name -eq "FileInfo"} | Measure-Object -Property Length -Sum)
Get-ChildItem -Path $RootFolderでルートフォルダ内のオブジェクトを取得します。「-Force」オプションを付けることで、既定で非表示設定となっているフォルダやオプションも探索対象とすることができますが、フォルダやファイルによっては特殊なオブジェクトがあるためアクセスができなくエラーとなってしまうことがあります。
これらエラーは無視してコマンドを実行するために、-ErrorAction "SilentlyContinue"を指定しておきます。
Get-ChildItem -Path $RootFolder -ErrorAction "SilentlyContinue" -Force
Sample2.ps1では5行目に「-Recurse」オプションが付いています。
$Items = (Get-ChildItem -Path $RootFolder -ErrorAction "SilentlyContinue" -Force -Recurse | Where-Object {$_.GetType().Name -eq "FileInfo"} | Measure-Object -Property Length -Sum)
このオプションは、ルートフォルダ配下のサブフォルダ内のファイルまで再帰的に取得するためのものです。Sample1.ps1とSample2.ps1の違いは、純粋なフォルダ内のファイルサイズの合計をフォルダのサイズとするか、フォルダ内のファイルとサブフォルダ、さらにサブフォルダ内のファイル、フォルダというように、すべてを含めてフォルダサイズとするかの違いとなります。
次にパイプラインで引き渡されたオブジェクトに対して、Where-Objectコマンドを使ってファイルのみ抽出しています。フォルダのサイズはフォルダ内に配置されたファイルのみの合計サイズとして計算する必要があります。ファイルのみを抽出するには、オブジェクトに対してGetType()コマンドを実行して、オブジェクト名が”FileInfo”となっている物を抽出します。$_ はパイプラインで引き渡されたオブジェクトが格納されています。これはPowerShellのあらかじめ決められている組み込み変数です。-eq はPowerShellの演算子で「=」(等号)の意味です。
Where-Object {$_.GetType().Name -eq "FileInfo"}
ファイルのみ抽出したオブジェクトに対して、Measure-Objectコマンドを使ってファイルサイズ(Lengthプロパティ)の合計値を-Sumオプションを付けて取得しています。最後に取得したオブジェクトを変数$Itemsに保存しておきます。
Measure-Object -Property Length -Sum
ルートフォルダのフォルダサイズ情報を配列に格納しておきます。この配列は最終的に、フォルダパスとフォルダサイズを配列に格納して、サイズ順に並び替え、上位10件を表示するため利用します。
[Array]$Folders = [PSCustomObject]@{
"Fullname" = $RootFolder
"Size(MB)" = ("{0:N1}" -F ($Items.Sum / 1MB))
}
$Folders変数が配列であることを定義します。
[Array]$Folders
[PSCustomObject]を使うと連想配列のフィールド名を独自に定義することができます(既定ではNameとValue)。フォルダパスと、フォルダサイズを格納します。フォルダサイズは見やすいように {0:N1} –FでMB単位でカンマ付の小数点第一位の値に表示形式を直して保存しています。
[PSCustomObject]@{
"Fullname" = $RootFolder
"Size(MB)" = ("{0:N1}" -F ($Items.Sum / 1MB))
}
次にルートフォルダ配下のサブフォルダに対してサイズ取得を行います。Get-ChildItemコマンドで-Recurseオプションを指定すると、サブフォルダ内のサブフォルダ、さらにそのサブフォルダというようにすべての子オブジェクトを取得します。このブロックは、ルートフォルダとは異なりフォルダ一覧を取得するので、Where-Objectコマンドでは"DirectoryInfo"を指定してフォルダのみ抽出しています。
$Items = (Get-ChildItem -Path $RootFolder -ErrorAction "SilentlyContinue" -Recurse | Where-Object {$_.GetType().Name -eq "DirectoryInfo"})
取得したすべてのサブフォルダのオブジェクトそれぞれに対して、ファイルのサイズを合計してそれぞれのフォルダサイズとして計算していきます。すべてのフォルダ情報に対して処理を行う場合は、ForEach()の制御構文が便利です。$Itemsに格納されたオブジェクトを1つずつ順番に$iに格納してサイズ計算処理を行います。計算された全てのフォルダサイズ情報は、ルートフォルダの情報を格納した連想配列$Foldersに追加で格納します。
$Folders += ForEach ($i in $Items)
{
~
}
$iにはフォルダ情報がオブジェクトとして格納されています。それぞれルートフォルダと同様にファイルの合計サイズを計算して、フォルダサイズとして連想配列に格納します。
$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))
}
Sample2.ps1では14行目に「-Recurse」オプションが付いています。
$SubFolderItems = (Get-ChildItem -Path $i.FullName -ErrorAction "SilentlyContinue" -Force -Recurse | Where-Object {$_.GetType().Name -eq "FileInfo"} | Measure-Object -Property Length -Sum)
ルートフォルダと同様に、サブフォルダ内のすべてのサブフォルダに対して再帰的にファイルを取得して合計しています。
最後にすべてのフォルダ情報を格納した連想配列$Foldersに対して、-Descendingオプションを使ってフォルダサイズを昇順で並べ替え、パイプラインを使って配列内の上位20件を抽出します。
さらにFormat-Tableコマンドを使って、テーブル表示で出力します。このとき-AutoSizeオプションを指定すると、自動でテーブルサイズなどを調整して出力します。
$Folders | Sort "Size(MB)" -Descending | Select-Object -First 20 | Format-Table -AutoSize
スクリプトの実行結果。(Sample1.ps1)
Fullname | Size(MB) | |
-------- | -------- | |
C:\Program Files\Common Files\microsoft shared\ink | 41.8 | |
C:\Program Files\Windows Defender | 10.2 | |
C:\Program Files\Windows Journal | 7.8 | |
C:\Program Files\Hyper-V | 6.8 | |
C:\Program Files\Windows Photo Viewer | 5.9 | |
C:\Program Files\Hyper-V\6.3 | 5.5 | |
C:\Program Files\Windows Mail | 5.4 | |
C:\Program Files\Hyper-V\6.2 | 4.9 | |
C:\Program Files\Windows NT\Accessories | 4.4 | |
C:\Program Files\Common Files\System\Ole DB | 3.4 | |
C:\Program Files\Hyper-V\6.3\ja-JP | 3.1 | |
C:\Program Files\Hyper-V\ja-JP | 2.9 | |
C:\Program Files\Windows NT\TableTextService | 2.8 | |
C:\Program Files\Hyper-V\6.2\ja-JP | 2.7 | |
C:\Program Files\Windows Media Player | 2.6 | |
C:\Program Files\Common Files\System\ado | 2.6 | |
C:\Program Files\Internet Explorer | 2.4 | |
C:\Program Files\Common Files\System | 1.8 | |
C:\Program Files\Common Files\System\msadc | 1.7 | |
C:\Program Files\Common Files\microsoft shared\ink\en-US | 1.0 |
スクリプトの実行結果。(Sample2.ps1)
Fullname | Size(MB) | |
-------- | -------- | |
C:\Program Files\Common Files | 55 | |
C:\Program Files\Common Files\microsoft shared | 45.4 | |
C:\Program Files\Common Files\microsoft shared\ink | 43.4 | |
C:\Program Files\Hyper-V | 25.9 | |
C:\Program Files\Windows Defender | 10.4 | |
C:\Program Files\Common Files\System | 9.7 | |
C:\Program Files\Hyper-V\6.3 | 8.6 | |
C:\Program Files\Windows Journal | 8.4 | |
C:\Program Files\Hyper-V\6.2 | 7.6 | |
C:\Program Files\Windows NT | 7.3 | |
C:\Program Files\Windows Photo Viewer | 5.9 | |
C:\Program Files\Windows Mail | 5.9 | |
C:\Program Files\Windows NT\Accessories | 4.5 | |
C:\Program Files\Common Files\System\Ole DB | 3.5 | |
C:\Program Files\Hyper-V\6.3\ja-JP | 3.1 | |
C:\Program Files\Windows NT\TableTextService | 2.9 | |
C:\Program Files\Hyper-V\ja-JP | 2.9 | |
C:\Program Files\Windows Media Player | 2.8 | |
C:\Program Files\Hyper-V\6.2\ja-JP | 2.7 | |
C:\Program Files\Common Files\System\ado | 2.6 |
以上、Get-ChildItemコマンドを利用したフォルダサイズの取得方法を紹介しました。
Get-ChildItemコマンドは、サブフォルダを深く掘り下げる場合でも、再起コードを呼び出すといった手間が必要ありません。簡単なオプションスイッチ(-Recurse)を付けるだけで、自動的に再起処理を行ってくれるという優れものです。
この他にも、特定のファイルを拡張子をキーとして抽出したり、ファイル構造だけではなく、レジストリの設定値を取得したりと様々な応用が可能です。ぜひ、チャレンジしてみてください。
Windows Azure Pack プライベートクラウド構築ガイド
GMOインターネット株式会社 樋口 勝一 著
Category
Report Archive
2018年4月18日(水)
2018年3月28日(水)
2018年2月21日(水)
2017年12月13日(水)
2017年11月22日(水)
2017年9月20日(水)
2017年8月30日(水)
2017年7月19日(水)