スマートフォンからパソコンに動画や写真を移すと、一つのフォルダに数千ものファイルが溜まってしまい、目的のファイルを探すのが大変になることはありませんか?
この問題を解決するため、AIのGeminiに依頼して、大量のファイルを撮影日ごとに自動でフォルダ分けするPowerShellスクリプトを作成してもらいました。
このスクリプトを使えば、乱雑になりがちなフォルダ内がすっきりと整理され、過去のデータも簡単に見つけられるようになります。
# -----------------------------------------------------------------------------
# 説明: 画像ファイルを撮影日時のフォルダに整理するスクリプト
# -----------------------------------------------------------------------------
# 1. 画像が保存されているフォルダのパスを指定してください
$targetFolder = "C:\Users\YourUser\Pictures\Camera Roll" # 実際のフォルダパスに書き換えてください
# 2. 処理対象とするファイルの拡張子 (必要に応じて追加・削除してください)
$imageExtensions = @(".jpg", ".jpeg", ".png", ".heic", ".cr2", ".nef", ".arw", ".mov", ".mp4")
# -------------------------- ここから下は変更不要 --------------------------
# フォルダの存在チェック
if (-not (Test-Path -Path $targetFolder)) {
Write-Error "エラー: 指定されたフォルダが見つかりません。パスを確認してください: $targetFolder"
return
}
Write-Host "📁 処理を開始します。対象フォルダ: $targetFolder" -ForegroundColor Green
try {
# Shellオブジェクトを使用してファイルの詳細情報にアクセスします
$shell = New-Object -ComObject Shell.Application
$folder = $shell.NameSpace($targetFolder)
# 「撮影日時」の項目が何番目にあるかを探します (環境により異なるため)
$dateTakenIndex = -1
for ($i = 0; $i -lt 300; $i++) {
$header = $folder.GetDetailsOf($null, $i)
if ($header -eq "撮影日時" -or $header -eq "Date taken") {
$dateTakenIndex = $i
break
}
}
# フォルダ内の対象ファイルを一つずつ処理
Get-ChildItem -Path $targetFolder -File | Where-Object { $imageExtensions -contains $_.Extension.ToLower() } | ForEach-Object {
$file = $_
$dateTaken = $null
# 撮影日時を取得
if ($dateTakenIndex -ne -1) {
$folderItem = $folder.ParseName($file.Name)
if ($folderItem) {
# GetDetailsOfは文字列を返す
$dateValue = $folder.GetDetailsOf($folderItem, $dateTakenIndex)
# 文字列からDateTimeオブジェクトへの変換を試みる
if (-not [string]::IsNullOrWhiteSpace($dateValue)) {
# 日付文字列に含まれることがある特殊文字を除去
$cleanedDateString = $dateValue -replace '[\u200E\u200F\u202A-\u202E]',''
try {
$dateTaken = [datetime]::Parse($cleanedDateString)
} catch {}
}
}
}
# 撮影日時が取得できなかった場合は、ファイルの最終更新日時を使用
if ($null -eq $dateTaken) {
$dateTaken = $file.LastWriteTime
Write-Warning "[$($file.Name)] の撮影日時が取得できませんでした。代わりに更新日時 (${dateTaken}) を使用します。"
}
# 移動先のフォルダ名を「yyyyMMdd」形式で作成
$subFolderName = $dateTaken.ToString("yyyyMMdd")
$destinationFolder = Join-Path -Path $targetFolder -ChildPath $subFolderName
# 移動先フォルダがなければ作成
if (-not (Test-Path -Path $destinationFolder)) {
Write-Host "新しいフォルダを作成します: $subFolderName" -ForegroundColor Cyan
New-Item -Path $destinationFolder -ItemType Directory -Force | Out-Null
}
# ファイルを移動
$destinationPath = Join-Path -Path $destinationFolder -ChildPath $file.Name
Move-Item -Path $file.FullName -Destination $destinationPath
Write-Host "'$($file.Name)' -> '$subFolderName'"
}
}
catch {
Write-Error "予期せぬエラーが発生しました: $_"
}
finally {
# COMオブジェクトを解放
if ($shell) {
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($shell) | Out-Null
Remove-Variable shell -ErrorAction SilentlyContinue
}
}
Write-Host "✅ すべての処理が完了しました。" -ForegroundColor Green
実行完了すると8桁の表現(例 20250716)のフォルダ別にファイルが移動されます。利用にあたっては、自己責任でお願いします。 #gemini #powershell
