日付毎にファイルをサブフォルダに移動

スマートフォンからパソコンに動画や写真を移すと、一つのフォルダに数千ものファイルが溜まってしまい、目的のファイルを探すのが大変になることはありませんか?

この問題を解決するため、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

Geminiを使ったファイル整理方法

Google AIであるGeminiを使って未整理のフォルダのファイルを種類別にフォルダに分類するスクリプトを作成してみました。

古いHDDの大掃除が完了!✨ 中身がごちゃごちゃで手付かずでしたが、Geminiに『ファイルを種類別に仕分けるスクリプト作って!』とお願いしたら、一瞬で解決しました。

ExcelはExcelフォルダ、画像は画像フォルダへ自動で仕分けてくれるので、要らないファイルを見つけるのがすごく楽に! これ、月別整理や重複ファイル削除にも応用できそう。AI活用、すごい便利! #データ整理 #Gemini #PowerShell

次のコードはPowerShellで動作します。(ファイルは 拡張子.ps1で保存してください。UTF-8のBOM付で保存します。)wordや、excel、動画やパワーポイントのフォルダーに分類してファイルを移動します。

# 1. 基本設定
# スクリプトを置いた場所を基準に動作します
$basePath = Get-Location
$sourceFolderName = "整理したいファイルのフォルダを指定"
$sourceFolderPath = Join-Path $basePath $sourceFolderName

# 移動先のフォルダ名を定義します (フォルダ名は自由に変更できます)
$destFolders = @{
    excel      = @(".xlsx", ".xls", ".xlsm", "csv")
    movie      = @(".mp4", ".mov", ".avi", ".wmv", ".mkv")
    picture    = @(".jpg", ".jpeg", ".png", ".gif", ".bmp", ".heic", ".raw") # "picuture"を"picture"に修正しました
    pdf        = @(".pdf")
    powerpoint = @(".pptx", ".ppt")
    word       = @(".docx", ".doc")
    etc        = "その他" # ここで定義されていない拡張子のファイルが移動されるフォルダ
}

# 2. 移動先フォルダの作成
# 定義したフォルダが存在しない場合に作成します
Write-Host "--- フォルダの準備 ---" -ForegroundColor Yellow
foreach ($folder in $destFolders.Keys) {
    $path = Join-Path $basePath $folder
    if (-not (Test-Path $path)) {
        New-Item -ItemType Directory -Path $path
        Write-Host "作成しました: $path"
    }
}

# 3. ファイルの移動処理
Write-Host "`n--- ファイルの移動を開始します ---" -ForegroundColor Yellow
# サブフォルダ内もすべて検索 (-Recurse) し、ファイルのみを対象 (-File)
$files = Get-ChildItem -Path $sourceFolderPath -Recurse -File

foreach ($file in $files) {
    $extension = $file.Extension.ToLower()
    $moved = $false

    # 各カテゴリの拡張子に一致するかチェック
    foreach ($category in $destFolders.Keys) {
        if ($category -ne "etc" -and $destFolders[$category] -contains $extension) {
            $destinationFolder = Join-Path $basePath $category
            $moved = $true
            break # 一致したらループを抜ける
        }
    }

    # どのカテゴリにも一致しなかった場合、etcフォルダに設定
    if (-not $moved) {
        $destinationFolder = Join-Path $basePath "etc"
    }

    # 移動先でのファイルパスを決定 (同名ファイル対策)
    $destinationFile = Join-Path $destinationFolder $file.Name
    $counter = 1
    # もし移動先に同名のファイルが存在したら、ファイル名に番号を付けて重複を回避
    while (Test-Path $destinationFile) {
        $newName = "{0}_{1}{2}" -f $file.BaseName, $counter, $file.Extension
        $destinationFile = Join-Path $destinationFolder $newName
        $counter++
    }

    # ファイルを移動
    try {
        Move-Item -Path $file.FullName -Destination $destinationFile -ErrorAction Stop
        Write-Host "移動: $($file.Name)  ->  $($destinationFolder)" -ForegroundColor Green
    }
    catch {
        Write-Host "エラー: $($file.FullName) の移動に失敗しました。" -ForegroundColor Red
        Write-Host $_.Exception.Message -ForegroundColor Red
    }
}

# 4. 空になったサブフォルダの削除 (任意)
# 下記のコメントアウトを解除すると、ファイルがなくなった後の空のフォルダをすべて削除します
# Get-ChildItem -Path $sourceFolderPath -Recurse -Directory | Where-Object { (Get-ChildItem -Path $_.FullName -Recurse -File).Count -eq 0 } | Remove-Item -Recurse -Force
# Write-Host "`n--- 空のフォルダを削除しました ---" -ForegroundColor Yellow


Write-Host "`n--- すべての処理が完了しました ---" -ForegroundColor Yellow

Geminiを使うと瞬時に便利なスクリプトを作成してくれるので大変便利です。

次のフォルダーに分類されます。

#GEMINI #PowerShell #AI