DePhoegon

MTP Device Transfer

Jul 1st, 2025 (edited)
1,364
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PowerShell 4.51 KB | Source Code | 0 0
  1. param(
  2.     [Parameter(Mandatory)]
  3.     [string]$PhoneName,
  4.  
  5.     [Parameter(Mandatory)]
  6.     [string]$DestinationFolder
  7. )
  8.  
  9. # Timestamped log file in root of destination
  10. $timestamp = Get-Date -Format 'yyyy-MM-dd_HH-mm-ss'
  11. $hashLog = Join-Path $DestinationFolder "FileSizeMismatchLog_$timestamp.txt"
  12. New-Item -ItemType File -Path $hashLog -Force | Out-Null
  13.  
  14. # Target folder names
  15. $targetFolders = @("DCIM", "Camera", "Pictures", "Screenshots", "Recordings")
  16.  
  17. # Shell access
  18. $shell   = New-Object -ComObject Shell.Application
  19. $desktop = $shell.Namespace(0)
  20. # 0 {Windows 11}
  21. # 0x11 {Windows 10}
  22. $mtp     = $desktop.Items() | Where-Object { $_.Name -eq $PhoneName }
  23.  
  24. if (-not $mtp) {
  25.     Write-Error "Could not find device '$PhoneName'."
  26.     exit 1
  27. }
  28.  
  29. # Get storage roots: Internal + SD card etc.
  30. $volumes = $mtp.GetFolder.Items() | Where-Object { $_.IsFolder }
  31.  
  32. if (-not $volumes) {
  33.     Write-Error "No accessible storage volumes found on device."
  34.     exit 1
  35. }
  36.  
  37. function Test-FileSizeIntegrity {
  38.     param (
  39.         [object]$ShellItem,
  40.         [string]$DestinationFilePath,
  41.         [string]$RelativePath
  42.     )
  43.  
  44.     if (-not (Test-Path $DestinationFilePath)) {
  45.         Add-Content $hashLog "`r`n❌ Missing file:`r`nDEST: $DestinationFilePath`r`nSRC Item: $RelativePath`r`n"
  46.         return
  47.     }
  48.  
  49.     $mtpSize   = [int64]$ShellItem.Size
  50.     $localSize = (Get-Item $DestinationFilePath).Length
  51.  
  52.     $sizeDiff = [math]::Abs($mtpSize - $localSize)
  53.  
  54.     if ($sizeDiff -le 4096) {  # allow up to 4KB padding tolerance
  55.         Write-Host ("✅ Size matched: $RelativePath → $mtpSize bytes (MTP) / $localSize bytes (Local)")
  56.     } else {
  57.         $logEntry = @"
  58.        ❌ Size mismatch:
  59.        PATH:   $RelativePath
  60.        MTP:    $mtpSize bytes
  61.        LOCAL:  $localSize bytes
  62.        FILE:   $DestinationFilePath
  63.  
  64. "@
  65.         Add-Content $hashLog $logEntry
  66.         Write-Warning "⚠ Size mismatch for $RelativePath → $mtpSize bytes (MTP) / $localSize bytes (Local)"
  67.     }
  68. }
  69.  
  70. function Copy-MatchingFolders {
  71.     param($folder, $currentDepth, $maxDepth, $outPath)
  72.  
  73.     foreach ($item in $folder.Items()) {
  74.         if (-not $item.IsFolder) { continue }
  75.  
  76.         $name = $item.Name
  77.         $targetPath = Join-Path $outPath $name
  78.  
  79.         if ($targetFolders -contains $name) {
  80.             Write-Host "📁 Copying entire folder '$name' to '$targetPath'"
  81.             if (-not (Test-Path $targetPath)) {
  82.                 New-Item -ItemType Directory -Path $targetPath | Out-Null
  83.             }
  84.  
  85.             $sourceItems = $item.GetFolder.Items()
  86.             foreach ($subitem in $sourceItems) {
  87.                 $shell.Namespace($targetPath).CopyHere($subitem, 16)
  88.                 Start-Sleep -Milliseconds 100
  89.             }
  90.  
  91.             # After all files are copied — run integrity checks once
  92.             try {
  93.                 $shellItems = $item.GetFolder.Items() | Where-Object { -not $_.IsFolder }
  94.                 foreach ($child in $shellItems) {
  95.                     $destFilePath = Join-Path $targetPath $child.Name
  96.                     $relativePath = $child.Name
  97.                     Test-FileSizeIntegrity -ShellItem $child -DestinationFilePath $destFilePath -RelativePath $relativePath
  98.                 }
  99.             } catch {
  100.                 Write-Warning "⚠ Could not perform post-copy integrity check for '$name'"
  101.             }
  102.             continue
  103.         }
  104.  
  105.  
  106.         if ($currentDepth -lt $maxDepth) {
  107.             try {
  108.                 Copy-MatchingFolders -folder $item.GetFolder -currentDepth ($currentDepth + 1) -maxDepth $maxDepth -outPath $outPath
  109.             } catch {
  110.                 Write-Warning "⚠ Could not access subfolder '$name'"
  111.             }
  112.         }
  113.     }
  114. }
  115.  
  116. # Walk all volumes (e.g. Internal, SD card)
  117. foreach ($volume in $volumes) {
  118.     $volumeName = $volume.Name
  119.     $volumeFolder = $volume.GetFolder
  120.     $volumeOutput = Join-Path $DestinationFolder $volumeName
  121.  
  122.     Write-Host "`n🔎 Scanning '$volumeName'..."
  123.     if (-not (Test-Path $volumeOutput)) {
  124.         New-Item -ItemType Directory -Path $volumeOutput | Out-Null
  125.     }
  126.  
  127.     Copy-MatchingFolders -folder $volumeFolder -currentDepth 1 -maxDepth 2 -outPath $volumeOutput
  128. }
  129. if ((Get-Content $hashLog).Length -eq 0) {
  130.     Remove-Item $hashLog -Force
  131.     Write-Host "`n✅ No file size mismatches detected. Log file removed."
  132. } else {
  133.     Write-Host "`n⚠ File size mismatches recorded in: $hashLog"
  134. }
  135. Write-Host "`n✅ All matching folders copied from all available device storage to '$DestinationFolder'"
Tags: MTP KPD DePhoegon
Advertisement
Add Comment
Please, Sign In to add comment