Advertisement
DePhoegon

MTP Device Transfer

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