Edited at

PowerShellでフォルダ一覧を再帰的にTSVファイルに出力する方法

More than 1 year has passed since last update.

フォルダ一覧を高速にエクスポートする方法を模索していたところ、PowerShellでの実装にたどり着きました。

<要件>

・指定したフォルダを再帰的に探索して、フォルダ一覧を作成したい。

・フォルダ名、フルパス、親フォルダのフルパス、フォルダのサイズと所有者も取得したい。

幾つかの方法を試しましたが、今ところPowerShellでの実行がお手軽で高速でした。

検証環境では、60GBの共有フォルダ(15000フォルダあった)を2分半程度で探索し終わります。

以下の情報を参考にスクリプトを作成しました。

https://technet.microsoft.com/en-us/library/ff730945.aspx

Scripting.FileSystemObject という昔からあるネイティブライブラリを呼び出すことで、

サイズ付きのフォルダ一覧を高速にエクスポートすることができます。


powershell


$targetRootDirectory="\\sharedserver\foldername"
$filePath = "C:\temp\Export.csv"

$objFSO = New-Object -com Scripting.FileSystemObject
Get-ChildItem -Path $targetRootDirectory -Recurse -Force | Where-Object {$_.PSIsContainer} | Select-Object @{Name="ParentPath"; Expression = {$(Get-Item -LiteralPath $_.PSParentPath)}},Name,Parent,Exists,Root,FullName,Extension,CreationTime,CreationTimeUtc,LastAccessTime,LastAccessTimeUtc,LastWriteTime,LastWriteTimeUtc,Attributes,@{Name="Length" ; Expression={$objFSO.GetFolder($_.FullName).Size}} | Export-Csv -Path $filePath -Encoding Default -Delimiter "`t"


上記スクリプトの中の、以下の記述がミソで、フォルダサイズも一緒に出力します。

不要でしたら、削除してください。



@{Name="Length" ; Expression={$objFSO.GetFolder($_.FullName).Size}}

フォルダの所有者も出力したい場合は@{Name="Owner";Expression={(Get-ACL $_.FullName).Owner}}も追加してください。


powershell

$targetRootDirectory="\\sharedserver\foldername"

$filePath = "C:\temp\Export.csv"

$objFSO = New-Object -com Scripting.FileSystemObject

Get-ChildItem -Path $targetRootDirectory -Recurse -Force | Where-Object {$_.PSIsContainer} | Select-Object @{Name="ParentPath"; Expression = {$(Get-Item -LiteralPath $_.PSParentPath)}},Name,Parent,FullName,LastAccessTime,LastWriteTime,@{Name="Length" ; Expression={$objFSO.GetFolder($_.FullName).Size}} ,@{Name="Owner";Expression={(Get-ACL $_.FullName).Owner}}| Export-Csv -Path $filePath -Encoding Default -Delimiter "`t"


追記:

探索の際にGet-ChilditemにForceオプションを付けていて、隠しフォルダも探索の範囲としている。

スクリプト内で親フォルダのフルパスも取得しているが、

親フォルダがドットで始まる隠しフォルダの場合、この書き方だと空文字が返ってくる。

@{Name="ParentPath"; Expression = {$(Get-Item -LiteralPath $_.Parent.FullName)}}

こちらの書き方であれば、取得できる。

@{Name="ParentPath"; Expression = {$(Split-Path $_.FullName -Parent)}}