v2, use old api endpoint
This commit is contained in:
parent
5109e1ec3b
commit
c4fa4ae57f
|
|
@ -20,10 +20,19 @@ param (
|
|||
[string] $TenantId
|
||||
)
|
||||
|
||||
# Check for Microsoft.Graph module and install if needed
|
||||
if (-not (Get-Module -ListAvailable -Name Microsoft.Graph)) {
|
||||
Write-Host "Installing Microsoft.Graph module..."
|
||||
Install-Module Microsoft.Graph -Scope CurrentUser -Force
|
||||
# Check for and install required Microsoft.Graph modules
|
||||
$requiredModules = @(
|
||||
'Microsoft.Graph.Authentication',
|
||||
'Microsoft.Graph.Files',
|
||||
'Microsoft.Graph.Users.Actions'
|
||||
)
|
||||
|
||||
foreach ($module in $requiredModules) {
|
||||
if (-not (Get-Module -ListAvailable -Name $module)) {
|
||||
Write-Host "Installing $module module..."
|
||||
Install-Module $module -Scope CurrentUser -Force
|
||||
}
|
||||
Import-Module $module -Force
|
||||
}
|
||||
|
||||
function Connect-GraphWithDebug {
|
||||
|
|
@ -32,7 +41,9 @@ function Connect-GraphWithDebug {
|
|||
$scopes = @(
|
||||
"Files.Read.All",
|
||||
"Files.ReadWrite.All",
|
||||
"offline_access"
|
||||
"offline_access",
|
||||
"openid",
|
||||
"profile"
|
||||
)
|
||||
|
||||
Write-Host "Connecting to Microsoft Graph..."
|
||||
|
|
@ -150,7 +161,9 @@ function Get-LivePhotoBundle {
|
|||
[Parameter(Mandatory)]
|
||||
$item,
|
||||
[Parameter(Mandatory)]
|
||||
$drive
|
||||
$drive,
|
||||
[Parameter(Mandatory)]
|
||||
$AccessToken
|
||||
)
|
||||
|
||||
try {
|
||||
|
|
@ -158,88 +171,45 @@ function Get-LivePhotoBundle {
|
|||
Write-Host "Found HEIC file: $($item.Name)" -ForegroundColor Cyan
|
||||
$baseName = [System.IO.Path]::GetFileNameWithoutExtension($item.Name)
|
||||
|
||||
# Get current auth context and token
|
||||
$context = Get-MgContext
|
||||
if (-not $context) {
|
||||
throw "No authentication context found"
|
||||
}
|
||||
# Get the video component using the direct video format API
|
||||
$videoPath = Join-Path $SaveTo "$baseName.mov"
|
||||
$tmpFile = Join-Path $SaveTo "tmp-file.mov"
|
||||
|
||||
$token = $context.AccessToken
|
||||
Write-Host "Using token: $($token.Substring(0, 10))..." -ForegroundColor Gray
|
||||
|
||||
# Get the item details with special fields
|
||||
$itemEndpoint = "https://graph.microsoft.com/v1.0/drives/$($drive.Id)/items/$($item.Id)"
|
||||
Write-Host "Getting item details..."
|
||||
|
||||
$headers = @{
|
||||
'Authorization' = "Bearer $token"
|
||||
'Accept' = 'application/json'
|
||||
}
|
||||
|
||||
# First try to get item metadata
|
||||
try {
|
||||
$response = Invoke-MgGraphRequest -Uri $itemEndpoint -Method GET
|
||||
Write-Host "Got item metadata"
|
||||
if (-not (Test-Path $videoPath)) {
|
||||
Write-Host "Attempting to download video component..."
|
||||
|
||||
# Try to get the video component using Graph API
|
||||
$videoEndpoint = "$itemEndpoint/content"
|
||||
$videoPath = Join-Path $SaveTo "$baseName.mov"
|
||||
# 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"
|
||||
|
||||
if (-not (Test-Path $videoPath)) {
|
||||
Write-Host "Attempting to download video component..."
|
||||
|
||||
# Try different content types
|
||||
$videoHeaders = @{
|
||||
'Authorization' = "Bearer $token"
|
||||
'Accept' = 'video/quicktime'
|
||||
'Prefer' = 'respond-async'
|
||||
try {
|
||||
# Use exact same headers as original script
|
||||
$headers = @{
|
||||
'Authorization' = "BEARER $AccessToken" # Note: BEARER in uppercase
|
||||
}
|
||||
|
||||
# Try with special query parameters
|
||||
$queryParams = @(
|
||||
"select=video",
|
||||
"expand=video",
|
||||
"format=mov"
|
||||
)
|
||||
|
||||
foreach ($param in $queryParams) {
|
||||
$tryUrl = "${videoEndpoint}?$param"
|
||||
Write-Host "Trying URL: $tryUrl"
|
||||
|
||||
try {
|
||||
Invoke-MgGraphRequest -Uri $tryUrl -Headers $videoHeaders -Method GET -OutputFilePath $videoPath
|
||||
if ((Test-Path $videoPath) -and (Get-Item $videoPath).Length -gt 0) {
|
||||
Write-Host "Successfully downloaded video component" -ForegroundColor Green
|
||||
return $true
|
||||
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
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host "Attempt failed with $param : $_" -ForegroundColor Yellow
|
||||
Remove-Item $videoPath -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
# If all attempts failed, try one last time with direct Graph API call
|
||||
try {
|
||||
$finalEndpoint = "$itemEndpoint/video"
|
||||
Write-Host "Trying final endpoint: $finalEndpoint"
|
||||
Invoke-MgGraphRequest -Uri $finalEndpoint -Method GET -OutputFilePath $videoPath
|
||||
if ((Test-Path $videoPath) -and (Get-Item $videoPath).Length -gt 0) {
|
||||
Write-Host "Successfully downloaded video using final attempt" -ForegroundColor Green
|
||||
Rename-Item -Path $tmpFile -NewName $fileName
|
||||
return $true
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host "Final attempt failed: $_" -ForegroundColor Red
|
||||
Remove-Item $videoPath -ErrorAction SilentlyContinue
|
||||
}
|
||||
} else {
|
||||
Write-Host "Video file already exists: $videoPath" -ForegroundColor Yellow
|
||||
return $true
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host "Failed to get item metadata: $_" -ForegroundColor Red
|
||||
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
|
||||
}
|
||||
}
|
||||
return $false
|
||||
|
|
@ -250,23 +220,70 @@ function Get-LivePhotoBundle {
|
|||
}
|
||||
}
|
||||
|
||||
# Add this helper function to get a Photos-specific token if needed
|
||||
# Remove the old Get-ODPhotosToken function and use this updated version
|
||||
function Get-ODPhotosToken {
|
||||
param(
|
||||
[string]$ClientId = "073204aa-c1e0-4e66-a200-e5815a0aa93d" # OneDrive Photos client ID
|
||||
[string]$ClientId = "073204aa-c1e0-4e66-a200-e5815a0aa93d",
|
||||
[string]$Scope = "OneDrive.ReadWrite,offline_access,openid,profile",
|
||||
[string]$RedirectURI = "https://photos.onedrive.com/auth/login"
|
||||
)
|
||||
|
||||
$scopes = "OneDrive.ReadWrite offline_access"
|
||||
$redirectUri = "https://photos.onedrive.com/auth/login"
|
||||
|
||||
# Get token using device code flow
|
||||
$deviceCode = Get-MgDeviceCode -ClientId $ClientId -Scopes $scopes
|
||||
|
||||
Write-Host "Please visit: $($deviceCode.VerificationUri)"
|
||||
Write-Host "Enter code: $($deviceCode.UserCode)"
|
||||
|
||||
$token = Get-MgToken -DeviceCode $deviceCode -ErrorAction Stop
|
||||
return $token.AccessToken
|
||||
try {
|
||||
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
|
||||
[Reflection.Assembly]::LoadWithPartialName("System.Drawing") | Out-Null
|
||||
[Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null
|
||||
|
||||
$URIGetAccessToken = "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?client_id=$ClientId&nonce=uv.$(New-Guid).Guid&response_mode=form_post&scope=$Scope&response_type=code&redirect_URI=$RedirectURI"
|
||||
|
||||
$form = New-Object Windows.Forms.Form
|
||||
$form.Text = "Authenticate to OneDrive"
|
||||
$form.Size = New-Object Drawing.Size @(700,600)
|
||||
$form.Width = 660
|
||||
$form.Height = 775
|
||||
|
||||
$web = New-Object System.Windows.Forms.WebBrowser
|
||||
$web.IsWebBrowserContextMenuEnabled = $true
|
||||
$web.Width = 600
|
||||
$web.Height = 700
|
||||
$web.Location = "25, 25"
|
||||
$web.ScriptErrorsSuppressed = $true
|
||||
|
||||
$DocComplete = {
|
||||
if ($web.Url.AbsoluteUri -match "access_token=|error|code=|logout|/auth/login") {
|
||||
$form.Close()
|
||||
}
|
||||
}
|
||||
|
||||
$web.Add_DocumentCompleted($DocComplete)
|
||||
$form.Controls.Add($web)
|
||||
$web.Navigate($URIGetAccessToken)
|
||||
|
||||
Write-Host "Please login in the opened browser window..."
|
||||
$form.ShowDialog() | Out-Null
|
||||
|
||||
$Authentication = New-Object PSObject
|
||||
# Get tokens from cookies
|
||||
$web.Document.Cookie -split ';' | ForEach-Object {
|
||||
$cookie = $_ -split '='
|
||||
if ($cookie.Count -eq 2) {
|
||||
$cookieValue = [uri]::UnescapeDataString($cookie[1])
|
||||
$Authentication | Add-Member NoteProperty $cookie[0].Trim() $cookieValue
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $Authentication.'AccessToken-OneDrive.ReadWrite') {
|
||||
Write-Error "Failed to get authentication token. Please try again."
|
||||
return $null
|
||||
}
|
||||
|
||||
Write-Host "Successfully obtained authentication token"
|
||||
return $Authentication
|
||||
|
||||
}
|
||||
catch {
|
||||
Write-Error "Error in Get-ODPhotosToken: $_"
|
||||
return $null
|
||||
}
|
||||
}
|
||||
|
||||
# Main execution
|
||||
|
|
@ -279,13 +296,14 @@ if (!(Test-Path $SaveTo)) {
|
|||
New-Item -ItemType Directory -Force -Path $SaveTo
|
||||
}
|
||||
|
||||
# Connect to Graph API
|
||||
# Get both authentication tokens
|
||||
Write-Host "Getting Graph API token..."
|
||||
if (Connect-GraphWithDebug) {
|
||||
Write-Host "`nGetting OneDrive Photos token..."
|
||||
$photosToken = Get-ODPhotosToken
|
||||
|
||||
Write-Host "`nQuerying OneDrive items..."
|
||||
$items = Get-DriveItems -FolderPath $PathToScan
|
||||
|
||||
# print the items to the console
|
||||
# $items | Format-List | Out-String | Write-Host
|
||||
|
||||
if ($items) {
|
||||
# Get drive reference
|
||||
|
|
@ -307,8 +325,8 @@ if (Connect-GraphWithDebug) {
|
|||
try {
|
||||
$result = Test-DownloadItem -ItemId $item.Id -SavePath $SaveTo -item $item
|
||||
if ($result) {
|
||||
# Try to get the video component
|
||||
$hasVideo = Get-LivePhotoBundle -item $item -drive $drive
|
||||
# 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 {
|
||||
|
|
|
|||
Loading…
Reference in New Issue