Consolidating Only Photos and Videos from Google Takeout: Automatically Sorting Them into an Out Folder with PowerShell

PowerShellカテゴリを表すパンダのイラスト PowerShell

About This Article
This article is organized based on actual results tested in Windows PowerShell 5.1, leveraging generative AI. Rather than a theoretical sample, this script was debugged and verified using actual Google Takeout data.

Verification Status: ✅ Verified on Real Hardware Running Windows PowerShell 5.1
Detecting 2,645 images and 104 videos (2,749 items and 15.81 GB in total), we confirmed that the copy process and progress display work correctly in the revised v4 version.

When backing up photos with Google Takeout, ZIP files, extracted folders, and JSON files are often mixed together, leaving you wanting to consolidate "only the photos and videos in one place" afterward.

While you can do this manually, verifying thousands of items is a daunting task.

Therefore, this time, we created a PowerShell script that automatically gathers:Images into OutImages and videos into OutVideos.

The key feature is that instead of simply copying, it displays how many items are left, how many gigabytes have been processed, and even an estimated time remaining.This ensures that even when processing large videos, you are less likely to feel like the script has frozen.

First, How to Use It

We made the usage as simple as possible.

Place this script in the location where your Google Takeout ZIP files or extracted folders are located.

GoogleTakeout
├─ takeout-001.zip
├─ takeout-002.zip
├─ takeout-003
│  └─ Takeout
│     └─ Google フォト
└─ Collect-GoogleTakeoutMedia-v4-beginner.ps1

Open PowerShell in that folder and run the following command.

.Collect-GoogleTakeoutMedia-v4-beginner.ps1

That is all the basic operation requires.

Running it will automatically create Out.

GoogleTakeout
├─ takeout-001.zip
├─ takeout-002.zip
├─ takeout-003
├─ Collect-GoogleTakeoutMedia-v4-beginner.ps1
│
└─ Out
   ├─ Images     ← 写真・画像
   ├─ Videos     ← 動画
   └─ media-copy-YYYYMMDD-HHMMSS.log
                  ↑ エラーなどの記録

The Process in Three Main Steps

Before looking at the code, understanding the flow of the process is all you need.

flowchart TD
    A[Google Takeoutのフォルダー] --> B[STEP 1 普通のフォルダーを調べる]
    B --> C[STEP 2 ZIPの中を調べる]
    C --> D[画像・動画の全件数と容量を集計]
    D --> E[STEP 3 Outへコピー]
    E --> F[Images]
    E --> G[Videos]
    E --> H[ログ]

STEP 1: Examine Regular Folders

First, inspect the extracted Google Takeout folders one by one.

No copying is done at this stage.

.jpg.png.heicFiles like are recorded to the list as images, and files like are recorded as videos. JSON files included with Google Takeout are excluded..mp4.mov

The concept is simple: it checks the "file extension" at the end of the filename.

$ImageExtensions = @(
    '.jpg','.jpeg','.png','.gif','.bmp','.tif','.tiff','.webp',
    '.heic','.heif','.avif'
)

$VideoExtensions = @(
    '.mp4','.mov','.m4v','.avi','.mkv','.webm',
    '.3gp','.mts','.m2ts','.mpg','.mpeg','.wmv'
)

For beginners, this simply means creating lists in advance of:"extensions to treat as images" and "extensions to treat as videos"

STEP 2: Inspect ZIPs Without Fully Extracting Them

Google Takeout data sometimes remains in ZIP archives.

In this script, instead of extracting ZIP files entirely before searching, we use .NET ZIP features via PowerShell to check their contents directly.

Add-Type -AssemblyName System.IO.Compression.FileSystem
$archive = [System.IO.Compression.ZipFile]::OpenRead($zipPath)

Then, if there are images or videos inside the ZIP, we extract only the necessary items later.

This reduces the extra free disk space required to extract entire ZIP archives.

Furthermore, if both an extracted folder and a ZIP file with the same name exist, such as

takeout-001.zip
takeout-001

, the ZIP file is skipped.This prevents duplicate collection of the same photos.

Calculating the Total Number of Items First

Once the search is complete, the overall picture is displayed before actual copying begins.

Our actual hardware verification yielded the following results.

--- 検索結果 ---
画像 : 2,645 件
動画 :   104 件
合計 : 2,749 件 / 15.81 GB

Instead of waiting blindly for a process of unknown size, you know the size of the goal right from the beginning.

STEP 3: Copying to the Out Folder

This is where the actual copying takes place.

Images are saved to , and videos are saved to .

OutImages

OutVideos

However, rather than copying large videos all at once, they are read and written in 4 MiB chunks.

$buffer = New-Object byte[] 4194304

while (($read = $InputStream.Read($buffer, 0, $buffer.Length)) -gt 0) {
    $outStream.Write($buffer, 0, $read)
    $script:ProcessedBytes += $read
    Show-CopyProgress -CurrentName $DisplayName
}

This is the key to preventing the script from appearing frozen.

Because the processed capacity increases even in the middle of large files, progress updates can be shown.

Displaying "How Much Time is Left?"

During copying, information like the following is displayed.

1200/2749 完了
残り 1549 件
6.8 GB / 15.81 GB
残り目安 18分

It doesn't just say "1,200 items finished."

While images might be a few megabytes, videos can be several gigabytes. Therefore, the remaining time is estimated based on the processed data size rather than just the item count.

This approach is also easy to apply to routine administrative tasks involving large volumes of files.

Attaching .part to Files During Copying

is a safety measure we implemented..part

For instance, when copying a video, it does not immediately create

movie.mp4

.

It is first copied as

movie.mp4.part

.

Only when it has copied successfully to the very end is the extension changed to

movie.mp4

.

$partPath = $Destination + '.part'

# コピー処理


# ...

Move-Item -LiteralPath $partPath -Destination $Destination -Force

This prevents interrupted videos from being mistaken for successfully completed ones.

Original Google Takeout data is not deleted.

Not Overwriting Even If Photos Have the Same NameIMG_0001.JPGIt is possible that identical filenames exist across different folders, such as

.

If they have the same name and size, they are considered already copied and skipped.

IMG_0001__a1b2c3d4.JPG

If they have the same name but different sizes, they are saved as separate files with a short distinguishing identifier attached, like .

When performing a task where you simply want to "consolidate everything into a single folder," avoiding overwrites is crucial.

Encountering an Error at 15 GB During Real-World Execution

This was something we only discovered by running it in practice.

In the initial version, when calculating the remaining capacity using the total capacity of 15.81 GB, Windows PowerShell 5.1 threw the following error.

Int32 型の値が大きすぎるか、または小さすぎます。

The cause was attempting to treat a large byte count as a 32-bit integer.

Therefore, in the revised version, capacities are explicitly handled as 64-bit integers using [long].

[long]$remainingBytes = $script:TotalBytes - $script:ProcessedBytes
if ($remainingBytes -lt 0) {
    $remainingBytes = 0L
}

This is something that is difficult to notice with small sample datasets.

It works fine for a few gigabytes, but fails for the first time on 15 GB of real data.

This part may be the most valuable reason for having "tried it out in practice" in this article.

Usable Without Understanding All the Code

From a PowerShell beginner's perspective, unfamiliar terms like appear.FileStreamArrayListZipFile

However, you do not need to understand everything right away.

The complete script provided here divides the process into the following eight parts with Japanese comments included:

  1. Initial settings

  2. Preparation to determine whether an item is a photo or video

  3. Counters to track progress

  4. A module to copy a single file

  5. STEP 1: Inspect folders

  6. STEP 2: Inspect ZIP files

  7. STEP 3: Perform actual copying

  8. Display final results

For now, understanding this general flow is enough.

置く
 ↓
実行する
 ↓
中を調べる
 ↓
件数を数える
 ↓
Outへコピーする
 ↓
結果を見る

When You Do Not Want to Inspect ZIP Files

If you want to process only extracted folders, append -NoZip.

.Collect-GoogleTakeoutMedia-v4-beginner.ps1 -NoZip

You can also specify a different location.

.Collect-GoogleTakeoutMedia-v4-beginner.ps1 `
    -SourceRoot "D:GoogleTakeout"

Conclusion

What we wanted to accomplish this time is technically "recursive searching," "ZIP reading," and "stream copying," but from a user's perspective, it is much simpler.

They want to gather only photos and videos from Google Takeout, know whether the process is hanging, and find out how much time is left.

We added the necessary functions to PowerShell step by step to achieve this.

By actually testing it with 2,749 items totaling 15.81 GB of data, we uncovered large numeric errors in PowerShell 5.1 and successfully verified operation using the revised v4 script.

It goes beyond just "writing code";running it on real data, fixing the errors that occur, and shaping it into a form that beginners can use constitute a complete, unified sample.

Document information

Article title
Consolidating Only Photos and Videos from Google Takeout: Automatically Sorting Them into an Out Folder with PowerShell
Published
Updated
Source
https://papanda925.com/?p=15472&lang=en

License: Text and original figures for which this site holds the relevant rights are available under CC BY 4.0 , unless otherwise noted. This article may include content created or edited with generative AI. If code has a separate license notice or a linked GitHub repository license, that license takes precedence for the code. Quotations, third-party materials, images, and trademarks are excluded from this license. Usage policy

Copied title and URL