OneDrive Upload script and documentation issue

Michael Russo 0 Reputation points
2024-08-20T01:56:31.1733333+00:00

My powershell script is below. Basically, the script successfully loops through a large file, right until the end, where the final content range fails to upload with an error.

function Start-UploadFolderToOneDrive {
    param (
        $baseDirectory,              # = "C:\Path\To\Local\Folder"
        $oneDriveUser,               # = "******@example.com.au"
        $accessToken                 # Ensure you pass the correct access token
    )

    $headers = @{
        Authorization = "Bearer $accessToken"
        "Content-Type" = "application/json"
    }

    ## Get all subdirectories
    $directories = Get-ChildItem -Path $baseDirectory -Recurse -Directory

    ## Create all the folders on OneDrive first
    foreach ($directory in $directories) {
        $relativePath = $directory.FullName.Substring($baseDirectory.Length).TrimStart('\').Replace('\', '/')
        $createFolderURL = "https://graph.microsoft.com/v1.0/users/$($oneDriveUser)/drive/root:/$($relativePath):/children"
        
        $folderName = $directory.Name
        $uploadFolderRequestBody = @{
            name = "$folderName"
            folder = @{}
            "@microsoft.graph.conflictBehavior" = "fail"
        } | ConvertTo-Json

        Write-Host "URI: $createFolderURL"
        Invoke-RestMethod -Headers $headers -Method Post -Body $uploadFolderRequestBody -ContentType "application/json" -Uri $createFolderURL
    }

    ## Upload the files
    $files = Get-ChildItem -Path $baseDirectory -Recurse -File
    foreach ($file in $files) {
        $relativePath = $file.FullName.Substring($baseDirectory.Length).TrimStart('\').Replace('\', '/')
        $uploadSessionURL = "https://graph.microsoft.com/v1.0/users/$($oneDriveUser)/drive/root:/$($relativePath):/createUploadSession"
    
        Write-Host "Upload URL: $uploadSessionURL"
        $uploadSession = (Invoke-RestMethod -Uri $uploadSessionURL -Headers $headers -Method Post).uploadUrl
    
        Write-Host "Upload Session: $uploadSession"
        ## Upload files in chunks
        $ChunkSize = 62259200  # 60 MB
        $fileStream = [System.IO.File]::OpenRead($file.FullName)
        $buffer = New-Object -TypeName Byte[] -ArgumentList $ChunkSize
        $position = 0
        $moreData = $true
    
        while ($moreData) {
            $bytesRead = $fileStream.Read($buffer, 0, $buffer.Length)
            if ($bytesRead -ne $buffer.Length) {
                $moreData = $false
                $output = $buffer[0..($bytesRead - 1)]
            } else {
                $output = $buffer
            }
    
            $contentLength = $output.Length
            $Header = @{
                'Content-Length'    = $contentLength
                'Content-Range'     = "bytes $position-$($position + $output.Length - 1)/$($fileStream.Length)"
            }

            Write-Host "Uploading bytes $position-$($position + $output.Length - 1) of $($fileStream.Length)"
            try {
                Invoke-RestMethod -Method Put -Uri $uploadSession -Body $output -Headers $Header
            }
            catch {
                Write-Host "Content Length: $contentLength"
                Write-Host "Content Range: bytes $position-$($position + $output.Length - 1)/$($fileStream.Length)"
                Write-Error "Failed to upload chunk at position $position : $_"
                break
            }
    
            $position += $output.Length
        }
    
        $fileStream.Close()
    }
}


At the last loop of uploading a file that exceeds 60MB in size, I get this error:

Log: Uploading bytes 62259200-99412612 of 99412613

Log: Content Length: 37153413

Log: Content Range: bytes 62259200-99412612/99412613

Error:

Start-UploadFolderToOneDrive : Failed to upload chunk at position 62259200 : Bytes to be written to the stream exceed the Content-Length bytes size specified.

I've checked and the file stream appears to be 37153413, which I think it correct.

Can someone sense check this for me?

Also, there appears to be a potential misprint in the "Completing a file" section of

https://learn.microsoft.com/en-us/graph/api/driveitem-createuploadsession?view=graph-rest-1.0

The example provided is:

PUT https://sn3302.up.1drv.com/up/fe6987415ace7X4e1eF866337
Content-Length: 21
Content-Range: bytes 101-127/128

But I'm wondering if that content length should actually be 27? In any case, the whole article appears to use a confusing combination of byte-size, kilobyte-size and VHD-example size references.

Thanks.

Microsoft Security | Microsoft Graph
0 comments No comments
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.