Skip to content

Instantly share code, notes, and snippets.

@ConnorGriffin
Last active May 27, 2024 08:11
Show Gist options
  • Save ConnorGriffin/dc804357bb10ff7522d0e21ddfdf9398 to your computer and use it in GitHub Desktop.
Save ConnorGriffin/dc804357bb10ff7522d0e21ddfdf9398 to your computer and use it in GitHub Desktop.
GDrive Upload PowerShell Script
# Set the Google Auth parameters. Fill in your RefreshToken, ClientID, and ClientSecret
$params = @{
Uri = 'https://accounts.google.com/o/oauth2/token'
Body = @(
"refresh_token=$RefreshToken", # Replace $RefreshToken with your refresh token
"client_id=$ClientID", # Replace $ClientID with your client ID
"client_secret=$ClientSecret", # Replace $ClientSecret with your client secret
"grant_type=refresh_token"
) -join '&'
Method = 'Post'
ContentType = 'application/x-www-form-urlencoded'
}
$accessToken = (Invoke-RestMethod @params).access_token
# Change this to the file you want to upload
$SourceFile = 'C:\Path\To\File'
# Get the source file contents and details, encode in base64
$sourceItem = Get-Item $sourceFile
$sourceBase64 = [Convert]::ToBase64String([IO.File]::ReadAllBytes($sourceItem.FullName))
$sourceMime = [System.Web.MimeMapping]::GetMimeMapping($sourceItem.FullName)
# If uploading to a Team Drive, set this to 'true'
$supportsTeamDrives = 'false'
# Set the file metadata
$uploadMetadata = @{
originalFilename = $sourceItem.Name
name = $sourceItem.Name
description = $sourceItem.VersionInfo.FileDescription
#parents = @('teamDriveid or folderId') # Include to upload to a specific folder
#teamDriveId = ‘teamDriveId’ # Include to upload to a specific teamdrive
}
# Set the upload body
$uploadBody = @"
--boundary
Content-Type: application/json; charset=UTF-8
$($uploadMetadata | ConvertTo-Json)
--boundary
Content-Transfer-Encoding: base64
Content-Type: $sourceMime
$sourceBase64
--boundary--
"@
# Set the upload headers
$uploadHeaders = @{
"Authorization" = "Bearer $accessToken"
"Content-Type" = 'multipart/related; boundary=boundary'
"Content-Length" = $uploadBody.Length
}
# Perform the upload
$response = Invoke-RestMethod -Uri "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&supportsTeamDrives=$supportsTeamDrives" -Method Post -Headers $uploadHeaders -Body $uploadBody
@ConnorGriffin
Copy link
Author

ConnorGriffin commented Sep 3, 2023

@Pheggas Could you post an error maybe? I am guessing it has something to do with needing to escape some characters in $sourceItem.Name, but I'm not setup to test right now.

@Pheggas
Copy link

Pheggas commented Sep 3, 2023

@ConnorGriffin Thank you for quick response. In any way, i fixed it by specifying -LiteralPath in Get-Item command so it wouldn't grap square brackets in filename as wildcard.

@Pheggas
Copy link

Pheggas commented Sep 4, 2023

Hey, it's me again. I'm currently having issues with uploading files to folders that are shared with me, instead of folders that i own. In my drive, it is okay and upload is successful but as soon as i want to upload to folder that is shared with me, it throws 404, file not found:

Invoke-RestMethod : {
  "error": {
    "code": 404,
    "message": "File not found: 13To6qyCukFwe0G9[redacted]KG9Fn.",
    "errors": [
      {
        "message": "File not found: 13To6qyCukFwe0G9[redacted]KG9Fn.",
        "domain": "global",
        "reason": "notFound",
        "location": "fileId",
        "locationType": "parameter"
      }
    ]
  }
}
At C:\Users\Pheggas\Desktop\yt-dlp\test.ps1:58 char:13
+ $response = Invoke-RestMethod -Uri "https://www.googleapis.com/upload ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
   eption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

@ConnorGriffin
Copy link
Author

ConnorGriffin commented Sep 4, 2023

@Pheggas I can't really say what's going on. If you provided the parentId in the upload metadata, and you have rights to upload to that folder, then I'm not sure.

I wrapped up some of the code from this Gist in to a module, you can poke around the code in there and see if anything is different. I still use this in some stuff occasionally, but I haven't looked at the code in long time. https://github.com/ConnorGriffin/PS-GDrive/blob/master/PS-GDrive/Public/New-GDriveItem.ps1

$uploadMetadata = @{
    originalFilename = $sourceItem.Name
    parents = @($parentId)
    description = $sourceItem.VersionInfo.FileDescription
    useContentAsIndexableText = $UseContentAsIndexableText
}

@1e0nn
Copy link

1e0nn commented Sep 14, 2023

Hey, it's me again. I'm currently having issues with uploading files to folders that are shared with me, instead of folders that i own. In my drive, it is okay and upload is successful but as soon as i want to upload to folder that is shared with me, it throws 404, file not found:

Invoke-RestMethod : {
  "error": {
    "code": 404,
    "message": "File not found: 13To6qyCukFwe0G9[redacted]KG9Fn.",
    "errors": [
      {
        "message": "File not found: 13To6qyCukFwe0G9[redacted]KG9Fn.",
        "domain": "global",
        "reason": "notFound",
        "location": "fileId",
        "locationType": "parameter"
      }
    ]
  }
}
At C:\Users\Pheggas\Desktop\yt-dlp\test.ps1:58 char:13
+ $response = Invoke-RestMethod -Uri "https://www.googleapis.com/upload ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
   eption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Hello, i noticed the same thing. When you are in your shared folder, you need to take the ID in the end of the URL https://drive.google.com/drive/folders/1GeOflixv5rTkMUnwMmcD and paste it here:

$uploadMetadata = @{
originalFilename = $sourceItem.Name
name = $sourceItem.Name
description = $sourceItem.VersionInfo.FileDescription
parents = @(1GeOflixv5rTkMUnwMmcD) #the id which is in the end of the url
}

@danmer8888
Copy link

Hello,
Faced the problem uploading large file >2g

The error information returned by PowerShell is: 'Exception calling "ToBase64String" with "1" argument(s): "Exception of type 'System.OutOfMemoryException' was thrown
as i understand problem caused by using 'ReadAllBytes'

Thanks a lot)
with small files this code works well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment