v3 version
This commit is contained in:
parent
c4fa4ae57f
commit
0200572011
|
|
@ -37,23 +37,45 @@ foreach ($module in $requiredModules) {
|
|||
|
||||
function Connect-GraphWithDebug {
|
||||
try {
|
||||
# Required scopes for OneDrive access
|
||||
$scopes = @(
|
||||
"Files.Read.All",
|
||||
"Files.ReadWrite.All",
|
||||
"Files.Read",
|
||||
"Files.ReadWrite",
|
||||
"offline_access",
|
||||
"openid",
|
||||
"profile"
|
||||
)
|
||||
|
||||
Write-Host "Connecting to Microsoft Graph..."
|
||||
Connect-MgGraph -Scopes $scopes
|
||||
# Force a new token by disconnecting first
|
||||
Disconnect-MgGraph -ErrorAction SilentlyContinue
|
||||
|
||||
# Get and display current connection info
|
||||
# Try to connect and verify the connection worked
|
||||
Connect-MgGraph -Scopes $scopes
|
||||
$context = Get-MgContext
|
||||
|
||||
if (-not $context -or [string]::IsNullOrEmpty($context.Account)) {
|
||||
Write-Error "Failed to authenticate with Microsoft Graph - no valid context"
|
||||
return $false
|
||||
}
|
||||
|
||||
Write-Host "Connected as: $($context.Account)"
|
||||
Write-Host "Scopes: $($context.Scopes -join ', ')"
|
||||
|
||||
# Verify we can actually access the API
|
||||
try {
|
||||
$testDrive = Get-MgDrive -Filter "driveType eq 'personal'" -ErrorAction Stop | Select-Object -First 1
|
||||
if (-not $testDrive) {
|
||||
Write-Error "Could not access OneDrive after authentication"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error "Failed to verify Graph API access: $_"
|
||||
return $false
|
||||
}
|
||||
|
||||
return $true
|
||||
}
|
||||
catch {
|
||||
|
|
@ -92,19 +114,6 @@ function Get-DriveItems {
|
|||
|
||||
Write-Host "Found $($items.Count) items in specified folder"
|
||||
|
||||
# Debug output for first few items
|
||||
$items | Select-Object -First 50000 | ForEach-Object {
|
||||
Write-Host "`nItem: $($_.Name)"
|
||||
Write-Host "Type: $($_.File.MimeType)"
|
||||
Write-Host "ID: $($_.Id)"
|
||||
|
||||
# Additional debug info for photos
|
||||
if ($_.Photo) {
|
||||
Write-Host "Photo metadata found!"
|
||||
$_.Photo | Format-List | Out-String | Write-Host
|
||||
}
|
||||
}
|
||||
|
||||
return $items
|
||||
}
|
||||
catch {
|
||||
|
|
@ -142,6 +151,14 @@ function Test-DownloadItem {
|
|||
}
|
||||
|
||||
Write-Host "Downloading to: $fileName"
|
||||
|
||||
# Try to refresh token before download
|
||||
$context = Get-MgContext
|
||||
if (-not $context -or $context.ExpiresOn -le (Get-Date)) {
|
||||
Write-Host "Token expired or missing, reconnecting..." -ForegroundColor Yellow
|
||||
Connect-GraphWithDebug | Out-Null
|
||||
}
|
||||
|
||||
Get-MgDriveItemContent -DriveId $drive.Id -DriveItemId $ItemId -OutFile $fileName
|
||||
|
||||
if (Test-Path $fileName) {
|
||||
|
|
@ -152,6 +169,20 @@ function Test-DownloadItem {
|
|||
}
|
||||
catch {
|
||||
Write-Error "Download failed: $_"
|
||||
Write-Host "Attempting to reconnect and retry..." -ForegroundColor Yellow
|
||||
|
||||
try {
|
||||
Connect-GraphWithDebug | Out-Null
|
||||
Get-MgDriveItemContent -DriveId $drive.Id -DriveItemId $ItemId -OutFile $fileName
|
||||
|
||||
if (Test-Path $fileName) {
|
||||
Write-Host "Successfully downloaded on retry: $fileName" -ForegroundColor Green
|
||||
return $true
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error "Retry download failed: $_"
|
||||
}
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
|
@ -161,55 +192,47 @@ function Get-LivePhotoBundle {
|
|||
[Parameter(Mandatory)]
|
||||
$item,
|
||||
[Parameter(Mandatory)]
|
||||
$drive,
|
||||
[Parameter(Mandatory)]
|
||||
$AccessToken
|
||||
$drive
|
||||
)
|
||||
|
||||
try {
|
||||
if ($item.File.MimeType -eq "image/heic") {
|
||||
Write-Host "Found HEIC file: $($item.Name)" -ForegroundColor Cyan
|
||||
Write-Host "`nDetailed HEIC Analysis:" -ForegroundColor Cyan
|
||||
Write-Host "------------------------"
|
||||
Write-Host "File Name: $($item.Name)"
|
||||
Write-Host "File Size: $($item.Size) bytes"
|
||||
|
||||
# Try to download video directly using the same item ID
|
||||
$baseName = [System.IO.Path]::GetFileNameWithoutExtension($item.Name)
|
||||
|
||||
# Get the video component using the direct video format API
|
||||
$videoPath = Join-Path $SaveTo "$baseName.mov"
|
||||
$tmpFile = Join-Path $SaveTo "tmp-file.mov"
|
||||
|
||||
if (-not (Test-Path $videoPath)) {
|
||||
Write-Host "Attempting to download video component..."
|
||||
# Use the same video download URL format as the original script
|
||||
$videoUri = "https://api.onedrive.com/v1.0/drive/items/$($item.Id)/content?format=video"
|
||||
Write-Host "Attempting direct video download: $videoUri"
|
||||
|
||||
# Use exactly the same endpoint and headers as original script
|
||||
$videoUri = "https://api.onedrive.com/v1.0/drive/items/$($item.Id)/content?format=video"
|
||||
Write-Host "Using video endpoint: $videoUri"
|
||||
try {
|
||||
$response = Invoke-MgGraphRequest -Method GET -Uri $videoUri -OutputFilePath $videoPath
|
||||
|
||||
try {
|
||||
# Use exact same headers as original script
|
||||
$headers = @{
|
||||
'Authorization' = "BEARER $AccessToken" # Note: BEARER in uppercase
|
||||
}
|
||||
if ((Test-Path $videoPath) -and (Get-Item $videoPath).Length -gt 0) {
|
||||
Write-Host "Successfully downloaded video component" -ForegroundColor Green
|
||||
return $true
|
||||
} else {
|
||||
Write-Host "Downloaded file appears to be invalid" -ForegroundColor Yellow
|
||||
Remove-Item $videoPath -ErrorAction SilentlyContinue
|
||||
|
||||
Write-Host "Calling OneDrive API for video..."
|
||||
$WebRequest = Invoke-WebRequest -Method "GET" -Uri $videoUri -Header $headers -ErrorAction SilentlyContinue -OutFile $tmpFile -PassThru
|
||||
Write-Host "WebRequest: Done Calling OneDrive API"
|
||||
if ((Test-Path $tmpFile) -and (Get-Item $tmpFile).Length -gt 0) {
|
||||
$fileName = ($WebRequest.Headers.'Content-Disposition'.Split('=',2)[-1]).Trim('"')
|
||||
if ($fileName) {
|
||||
Write-Host "Renaming $tmpFile to $fileName"
|
||||
if (Test-Path $videoPath) {
|
||||
Remove-Item $videoPath
|
||||
}
|
||||
Rename-Item -Path $tmpFile -NewName $fileName
|
||||
return $true
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host "Failed to download video component: $_" -ForegroundColor Red
|
||||
Remove-Item $tmpFile -ErrorAction SilentlyContinue
|
||||
}
|
||||
} else {
|
||||
Write-Host "Video file already exists: $videoPath" -ForegroundColor Yellow
|
||||
return $true
|
||||
}
|
||||
catch {
|
||||
Write-Host "Direct video download failed, trying alternative methods..." -ForegroundColor Yellow
|
||||
Write-Host "Error details:" -ForegroundColor Red
|
||||
Write-Host "Status Code: $($_.Exception.Response.StatusCode.value__)" -ForegroundColor Red
|
||||
Write-Host "Status Description: $($_.Exception.Response.StatusDescription)" -ForegroundColor Red
|
||||
Write-Host "Error Message: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Write-Host "Request URI: $videoUri" -ForegroundColor Red
|
||||
|
||||
# Write full error object for debugging
|
||||
Write-Debug "Full Error Object:"
|
||||
Write-Debug ($_ | Format-List -Force | Out-String)
|
||||
}
|
||||
}
|
||||
return $false
|
||||
|
|
@ -296,57 +319,83 @@ if (!(Test-Path $SaveTo)) {
|
|||
New-Item -ItemType Directory -Force -Path $SaveTo
|
||||
}
|
||||
|
||||
# Get both authentication tokens
|
||||
Write-Host "Getting Graph API token..."
|
||||
if (Connect-GraphWithDebug) {
|
||||
Write-Host "`nGetting OneDrive Photos token..."
|
||||
$photosToken = Get-ODPhotosToken
|
||||
# Get Graph API token with retry
|
||||
$maxRetries = 3
|
||||
$retryCount = 0
|
||||
$connected = $false
|
||||
|
||||
Write-Host "`nQuerying OneDrive items..."
|
||||
$items = Get-DriveItems -FolderPath $PathToScan
|
||||
while (-not $connected -and $retryCount -lt $maxRetries) {
|
||||
$retryCount++
|
||||
Write-Host "`nAttempting Graph API connection (Attempt $retryCount of $maxRetries)..."
|
||||
|
||||
if ($items) {
|
||||
# Get drive reference
|
||||
$drive = Get-MgDrive -Filter "driveType eq 'personal'" | Select-Object -First 1
|
||||
if (-not $drive) {
|
||||
Write-Error "Could not get drive reference"
|
||||
return
|
||||
}
|
||||
if (Connect-GraphWithDebug) {
|
||||
$connected = $true
|
||||
break
|
||||
}
|
||||
|
||||
Write-Host "`nProcessing items for Live Photos..."
|
||||
foreach ($item in $items) {
|
||||
Write-Host "`nChecking item: $($item.Name)"
|
||||
|
||||
# Process only HEIC files
|
||||
if ($item.File.MimeType -eq "image/heic") {
|
||||
Write-Host "Found HEIC file, checking for Live Photo components..."
|
||||
|
||||
# Download the HEIC file if it doesn't exist
|
||||
try {
|
||||
$result = Test-DownloadItem -ItemId $item.Id -SavePath $SaveTo -item $item
|
||||
if ($result) {
|
||||
# Try to get the video component, passing all items and the photos token
|
||||
$hasVideo = Get-LivePhotoBundle -item $item -drive $drive -AccessToken $photosToken.'AccessToken-OneDrive.ReadWrite'
|
||||
if ($hasVideo) {
|
||||
Write-Host "Successfully processed Live Photo bundle for: $($item.Name)" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "No Live Photo video component found for: $($item.Name)" -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host "Error processing $($item.Name): $_" -ForegroundColor Red
|
||||
}
|
||||
|
||||
# Add a small delay between items
|
||||
Start-Sleep -Milliseconds 500
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`nCompleted processing Live Photos"
|
||||
} else {
|
||||
Write-Host "No items found to process"
|
||||
if ($retryCount -lt $maxRetries) {
|
||||
Write-Host "Connection failed. Waiting 5 seconds before retry..."
|
||||
Start-Sleep -Seconds 5
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $connected) {
|
||||
Write-Error "Failed to connect to Graph API after $maxRetries attempts. Exiting."
|
||||
return
|
||||
}
|
||||
|
||||
# Get both authentication tokens
|
||||
Write-Host "`nGetting OneDrive Photos token..."
|
||||
$photosToken = Get-ODPhotosToken
|
||||
if (-not $photosToken) {
|
||||
Write-Error "Failed to get OneDrive Photos token. Exiting."
|
||||
return
|
||||
}
|
||||
|
||||
# Get drive reference first
|
||||
$drive = Get-MgDrive -Filter "driveType eq 'personal'" | Select-Object -First 1
|
||||
if (-not $drive) {
|
||||
Write-Error "Could not get drive reference"
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "`nQuerying OneDrive items..."
|
||||
$items = Get-DriveItems -FolderPath $PathToScan
|
||||
if (-not $items) {
|
||||
Write-Error "No items found or error occurred while fetching items"
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "`nProcessing items for Live Photos..."
|
||||
foreach ($item in $items) {
|
||||
Write-Host "`nChecking item: $($item.Name)"
|
||||
|
||||
# Process only HEIC files
|
||||
if ($item.File.MimeType -eq "image/heic") {
|
||||
Write-Host "Found HEIC file, checking for Live Photo components..."
|
||||
|
||||
# Download the HEIC file if it doesn't exist
|
||||
try {
|
||||
$result = Test-DownloadItem -ItemId $item.Id -SavePath $SaveTo -item $item
|
||||
if ($result) {
|
||||
# Try to get the video component, passing all items and the photos token
|
||||
$hasVideo = Get-LivePhotoBundle -item $item -drive $drive
|
||||
if ($hasVideo) {
|
||||
Write-Host "Successfully processed Live Photo bundle for: $($item.Name)" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "No Live Photo video component found for: $($item.Name)" -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host "Error processing $($item.Name): $_" -ForegroundColor Red
|
||||
}
|
||||
|
||||
# Add a small delay between items
|
||||
Start-Sleep -Milliseconds 500
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`nCompleted processing Live Photos"
|
||||
|
||||
Write-Host "`nDebug script completed"
|
||||
Loading…
Reference in New Issue