[PowerShell] ファイルをフォルダに自動振り分け(撮影日時・作成日時・更新日時のうち最も古い日付で)

カレントフォルダ内のすべてのファイルを、「作成日時」「更新日時」「撮影日時」のうち最も古い日付のフォルダに移動するスクリプト


コード

# 撮影日を取得する関数
function Get-PhotoTakenDate {
    param (
        [string]$path  # 画像ファイルのパスを受け取る
    )
    
    # System.Drawingライブラリをロードする
    Add-Type -AssemblyName System.Drawing
    
    # 画像ファイルを読み込む
    $image = [System.Drawing.Image]::FromFile($path)
    
    # ExifのDateTakenプロパティID(36867)を指定
    $propertyId = 36867
    
    # 撮影日を格納する変数を初期化
    $takenDate = $null
    
    # 画像にDateTakenプロパティが含まれているか確認
    if ($image.PropertyIdList -contains $propertyId) {
        # DateTakenプロパティを取得
        $propItem = $image.GetPropertyItem($propertyId)
        
        # プロパティの値を文字列として取得し、不要な空白を削除
        $dateTaken = [System.Text.Encoding]::ASCII.GetString($propItem.Value).Substring(0, 19);
        
        # 文字列をDateTime形式に変換
        $takenDate = [DateTime]::ParseExact($dateTaken, 'yyyy:MM:dd HH:mm:ss', $null)
    }
    
    # 画像リソースを解放
    $image.Dispose()
    
    # 撮影日を返す(存在しない場合は$null)
    return $takenDate
}

# カレントディレクトリのパスを取得
$dst = $PWD.Path

# カレントディレクトリ内のファイルのみを取得
$list = Get-ChildItem -File

# 各ファイルを処理
foreach ($flist in $list) {
    # ファイルの拡張子を小文字で取得
    $extension = $flist.Extension.ToLower()
    
    # 日付を格納するリストを初期化
    $dates = @()
    
    # PS1ファイルは除外
    if ($extension -eq ".ps1") {
    	continue
    }
    
    # JPEGファイルの場合、撮影日を取得
    if ($extension -eq ".jpg" -or $extension -eq ".jpeg") {
        $takenDate = Get-PhotoTakenDate -path $flist.FullName
        if ($takenDate) {
            $dates += $takenDate
        }
    }
    
    # 作成日と更新日をリストに追加
    $dates += $flist.CreationTime
    $dates += $flist.LastWriteTime
    
    # 最も古い日付を取得
    $oldestDate = ($dates | Sort-Object)[0]
    
    # 日付を"yyyy-MM-dd"形式の文字列に変換
    $dt = $oldestDate.ToString("yyyy-MM-dd")
    
    # 移動先のディレクトリパスを作成
    $targetDir = Join-Path -Path $dst -ChildPath $dt
    
    # ディレクトリが存在しない場合は作成
    if (-Not (Test-Path $targetDir)) {
        mkdir $targetDir
    }
    
    # ファイルを移動
    Move-Item $flist.FullName $targetDir
}

pause

処理でやってること

  • JPEGファイル以外は「作成日時」「更新日時」のみ取得

  • JPEGファイルは「作成日時」「更新日時」+「撮影日時」を取得

  • 「作成日時」「更新日時」「撮影日時」のうち最も古い日付を取得

  • 最も古い日付のフォルダ(yyyy-MM-dd)に移動(フォルダがない場合、新規作成する)

この記事が気に入ったらサポートをしてみませんか?