все заметки

PowerShell script для скачивания фото/видео с iphone

2021.08.11 (редактировано: 2024.08.31)

Зачем?

При подключении iPhone к ПК мы можем скачать медиа файлы, но там сумбур и ад.
Данный скрипт скачивает и переменовывает файлы по времени создания, как в Android.
А так же проверяет на наличие уже ранее скаченных файлов.

v0.0.3

  • Copy Files (Images/Videos) from iPhone to PC via MTP (Media Transfer Protocol)
  • Copy Files Created After `date`
  • Rename Files to "yyyyMMdd_HHmmss.ext" (android style)

как использовать?

Открываем PowerShell ISE

  • .\sync-iphone.ps1
  • .\sync-iphone.ps1 -After 2021-07-01
  • .\sync-iphone.ps1 -After last

важно!

Должна быть включена опция, иначе происходит постоянный дисконнект:

iPhone Settings -> Photos -> Keep Originals

проблема

Функция GetFolder работает не ахти, не может выдавать сразу список всех объектов
Запускаем скрипт каждые две секунды
while ($true) {.\sync-iphone.ps1; start-sleep 2}

sync-iphone.ps1

param([string]$After = "")\n\n$Destination = $((Get-Location).Path + "\")\n$Filter = ".jpg", ".png", ".mp4", ".mov", ".heic", ".heif"\n\n$Shell = New-Object -ComObject Shell.Application\n\nfunction GetFiles($Path) {\n\n\t$Objects = $Shell.NameSpace($Path).self.GetFolder()\n\n\tforeach($Object in $Objects.Items()) {\n\n\t\t# recursive\n\t\tif ($Object.IsFolder) {\n\t\t\tWrite-Output $Object.Name\n\t\t\tGetFiles($Object)\n\t\t} else {\n\t\t\t\n\t\t\tif ($Filter -match $Object.ExtendedProperty("System.FileExtension") -and $Object.ExtendedProperty("System.DateCreated").ToString("yyyy-MM-dd") -ge $After) {\n\n\t\t\t\t$Group = $Object.ExtendedProperty("System.DateCreated").ToString("yyyyMM")\n\t\t\t\t$Group = $($Destination + "\" + $Group + "\")\n\n\t\t\t\tif (-Not (Test-Path -Path $Group)) {\n\t\t\t\t\tNew-Item -ItemType "directory" -Path $Group\n\t\t\t\t}\n\n\t\t\t\tif ($Object.Name -match "^img_") {\n\t\t\t\t\t$Pre = "";\n\t\t\t\t} else {\n\t\t\t\t\t$Pre = "x-"\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t# android style filename\n\t\t\t\t$NewName = $Pre + $Object.ExtendedProperty("System.DateCreated").ToString("yyyyMMdd_HHmmss") + $Object.ExtendedProperty("System.FileExtension")\n\n\t\t\t\tif (Test-Path -Path $($Group + $NewName)) {\n\t\t\t\t\tif ($Object.ExtendedProperty("System.Size") -eq (Get-Item $($Group + $NewName)).Length) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t# if target file exist but sizes are not equivalent\n\t\t\t\t\t$NewName = $Pre + $Object.ExtendedProperty("System.DateCreated").ToString("yyyyMMdd_HHmmss") + "-" + $Object.ExtendedProperty("System.Size") + $Object.ExtendedProperty("System.FileExtension")\n\t\t\t\t\tif (Test-Path -Path $($Group + $NewName)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t# current copying\n\t\t\t\t#\n\t\t\t\t# If `Hide extensions for known file types` then $Object.Name return filename without extension\n\t\t\t\t# $Object.ExtendedProperty("System.FileName") - contains full name all time\n\t\t\t\tWrite-Output $($Object.ExtendedProperty("System.FileName") + " (" + $Object.ExtendedProperty("System.Size") + ") -> " + $NewName)\n\n\t\t\t\t$Shell.NameSpace($Group).self.GetFolder.CopyHere($Object)\n\n\t\t\t\t# file was copied?\n\t\t\t\tif (Test-Path $($Group + $Object.ExtendedProperty("System.FileName"))) {\n\t\t\t\t\tRename-Item -Path $($Group + $Object.ExtendedProperty("System.FileName")) -NewName $NewName\n\t\t\t\t} else {\n\t\t\t\t\tWrite-Output $("Error copy: " + $($Group + $Object.ExtendedProperty("System.FileName")))\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t}\n}\n\n# MTP devices list\n$Phones = $shell.NameSpace(0x11).self.GetFolder.items() | where { $_.Type -match "^portable" -and $_.Name -match "iphone" }\n\nif (-Not $Phones) {\n\tWrite-Output "No Iphone"\n\texit\n}\n\nforeach ($Phone in $Phones) {\n\n\t$Destination += $Phone.Name\n\n\tif (-Not (Test-Path -Path $Destination)) {\n\t\tNew-Item -ItemType "directory" -Path $Destination\n\t} elseif ($After -eq "") {\n\n\t} elseif (-Not ($After -match "^\d{4}-\d{2}-\d{2}$")) {\n\t\t$After = (Get-Item $Destination).LastWriteTime.ToString("yyyy-MM-dd")\n\t}\n\n\t# set current timestamp for sync directory\n\t(Get-Item $Destination).LastWriteTime = Get-Date\n\tGetFiles($Phone.Path)\n}\n\n

gist.github.com