PowerShellでファイル情報取得＆重複ファイルの確認

n 日以上前の、n MB以上のファイルを取得して、csvでリストを出力するスクリプト
出力内容としては以下の通りget-childitemプロパティを基本出力してますが、aclのowner情報も取得したかったので追加しました。

ついでにファイル名＋ファイルサイズが一致したものは、重複ファイルとして判定する機能もあります。
日数と容量の上限を絞ってあげると処理が速くなります。

#### 取得情報[↑](#目次)
プロパティ|説明
:--|:--
FullName|ファイルのフルパス
Name|ファイル名
Length|ファイルサイズ
CreationTime|作成日時
LastWriteTime|更新日時
LastAccessTime|アクセス日時
Mode|属性
Extension|拡張子
Owner|ファイル所有者

実行するときはこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604770/2ffeedb0-25e9-758e-51bb-d39fd19d347e.png)


logフォルダにログが吐かれる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604770/8ee7b274-5473-3abd-3f3b-499cbdb30ce4.png)

吐き出したcsvのイメージはこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604770/180ebecf-53d0-c008-132b-442feee5b1b7.png)


## 実際のコード[↑](#目次)
投稿内容の記載
```PowerShell:ファイル情報取得.ps1
cls

#==============日時・ログファイル定義==============
$Date = Get-Date -Format yyyyMMdd
$Time = Get-Date -Format HHmmss
$Now = "$Date`_$Time"
$Name_ps1 = [System.IO.Path]::GetFileNameWithoutExtension($PSCommandPath)
$Log_Ps1 = "$PSScriptRoot\log\$Name_ps1`_$Now`_$env:COMPUTERNAME`_$env:USERNAME`.log"

#==============スクリプト終了定義==============
Function Finish_Ps1{
    Write-Host (Get-Date -Format HH_mm_ss) "`t**********スクリプトを終了します**********"
    Stop-Transcript
    ii "$PSScriptRoot\log"
    Exit
}

#==============スクリプト開始==============
Start-Transcript $Log_Ps1
Write-Host (Get-Date -Format HH_mm_ss) "`t**********スクリプトを開始します**********"
Write-Host ""

#==============対象フォルダ入力==============
do{
    Write-Host "============================"
    Write-Host "フォルダ内のファイル情報を検索して出力します。対象フォルダのパスを指定してください。"
    Write-Host "※ダブルクォーテーション`"不要`t（例）C:\work\重複ファイル削除"
    $Path_Target = Read-Host
#    $Path_Target = "C:\work\重複ファイル削除"

    if ($Path_Target.Contains("`"")){
        Write-Host "！！！！！パスにダブルクォーテーション(`")が含まれています！！！！！"
        Write-Host "入力し直して下さい"
    }
}while($Path_Target.Contains("`""))

$Name_dir = (Split-Path $Path_Target -Leaf)
$Log_Csv = "$PSScriptRoot\log\$Name_dir`_$Now`.csv"

#==============古いファイルの検索条件入力==============
do{
    Write-Host ""
    Write-Host "============================"
    Write-Host "何日前のファイルを検索しますか？半角英数字で入力してください"
    Write-Host "※全て検索したい場合は 0 を入力してください`t（例）30"
    $day_old = Read-Host 
#    $day_old = "0"
    $day_old = [double]$day_old
    
    if ($day_old.GetType().Name -ne "double"){
        Write-Host "！！！！！日数の入力が半角英数字ではありません！！！！！"
        Write-Host "半角英数字で入力直して下さい"
    }
}while($day_old.GetType().Name -ne "double")

#==============古いファイルの検索条件入力==============
do{
    Write-Host ""
    Write-Host "============================"
    Write-Host "何MB以上のファイルを検索しますか？半角英数字で入力してください"
    Write-Host "※全て検索したい場合は 0 を入力してください`t（例）1"
    $size_file = Read-Host
#    $size_file = "0.001"
    $size_file = [double]$size_file
    
    if ($size_file.GetType().Name -ne "Double"){
        Write-Host "！！！！！日数の入力が半角英数字ではありません！！！！！"
        Write-Host "半角英数字で入力直して下さい"
    }
}while($size_file.GetType().Name -ne "Double")

#==============実行確認==============
do{
    Write-Host ""
    Write-Host "============================"
    Write-Host "以下の条件が入力されました。"
    Write-Host "処理を実行してよろしいでしょうか？"
    Write-Host ""
    Write-Host "検索対象フォルダ`t`t：$Path_Target"
    Write-Host "何日以上前のファイルを検索？`t：$day_old 日以上前のファイル"
    Write-Host "何MB以上のファイルを検索？`t：$size_file MB以上のファイル"

    $yesno = Read-Host "(y/n)"
#    $yesno = "y"
    Write-Host ""

    if($yesno -eq "n"){
        Write-Host " n が入力されました。処理を中断します"
        Start-Sleep 3
        Finish_Ps1
    }
}while($yesno -ne "y")

#==============ファイル情報取得==============
Write-Host (Get-Date -Format HH_mm_ss) "`t▼▼▼▼▼▼▼▼▼▼ファイル情報取得処理を開始します▼▼▼▼▼▼▼▼▼▼"
Write-Host (Get-Date -Format HH_mm_ss) "`t情報を収集しています…"

$Add_Dup = Get-ChildItem $Path_Target -Recurse | 
Where-Object{$_.LastAccessTime -lt (Get-Date).AddDays($day_old)} |
Where-Object{$_.Length -ge $size_file * 1024 * 1024 } |

Select-Object `
@{name = 'ファイルパス' ; Expression = {$_.FullName}} ,
@{name = 'ファイル名' ; Expression = {$_.Name}} ,
@{name = 'サイズ(MB)' ; Expression = {[Math]::Round($_.Length / 1024 / 1024 , 2, [MidpointRounding]::AwayFromZero)}} ,
@{name = '作成日時' ; Expression = {$_.CreationTime}} ,
@{name = '更新日時' ; Expression = {$_.LastWriteTime}} ,
@{name = 'アクセス日時' ; Expression = {$_.LastAccessTime}} ,
@{name = '属性(l＝リンク、d＝ディレクトリ、a＝アーカイブ、r＝読み取り専用、h＝非表示、s＝システム)' ; Expression = {$_.Mode}} ,
@{name = '拡張子' ; Expression = {$_.Extension}} ,
@{name = 'ファイル所有者' ; Expression = {(get-acl $_.fullname).owner}} ,
@{name = '重複確認用(ファイル名＋ファイルサイズ)' ; Expression = {$_.Name + $_.Length / 1024 / 1024}} ,
@{name = '重複ファイル数' ; Expression = {""}} |

Sort-Object -Descending { $_.'サイズ(MB)' }

$Count_Crray = $null
$Add_Dup |
ForEach-Object {
    Write-Host $_.'ファイル名'
    $Add_Dup | Where-Object {$_[$Count_Crray]} | Where-Object { $_.'重複ファイル数' = ($Add_Dup.'重複確認用(ファイル名＋ファイルサイズ)' -eq $_.'重複確認用(ファイル名＋ファイルサイズ)').Count -1}
    $Count_Crray ++
}

$Add_Dup | Export-Csv $Log_Csv -Encoding Default -NoTypeInformation

Write-Host (Get-Date -Format HH_mm_ss) "`t▲▲▲▲▲▲▲▲▲▲ファイル情報取得処理を終了します▲▲▲▲▲▲▲▲▲▲"
Write-Host ""

#==============スクリプト終了==============
Finish_Ps1
```