[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)に移動(フォルダがない場合、新規作成する)