Uploading and Downloading from Google Drive via API with PowerShell and OAuth 2
My organization is currently in the process of migrating from Office 365 to G Suite, as well as migrating to Team Drives from a traditional SMB file server. This has resulted in a need for an easy method to interact with Google Drive using PowerShell, as I have a number of scripts that store and read data on SMB file shares. Thanks to Montel Edwards for getting me started with his post.
I also highly recommend checking out the PSGsuite module from Nate Ferrell. It may already accomplish what you’re looking for. And if not, contribute to it!
Create Project and OAuth 2 Tokens
The article from Montel Edwards linked above has instructions for this piece. The README for GMGoogleDrive also has some great instructions. You’ll need to have a project with access to the Google Drive API, and a refresh token, client ID, and client secret.
Get Access Token
Download from Drive
Downloading from Drive can be done two different ways:
Exporting Google Apps formats to standard formats.
Downloading binary data as-is.
We can pull the file metadata and then look at the MIME type to determine which method to use.
First we have to provide the fileId, the destinationPath, and set the authentication headers.
We can now use this data to get the file metadata, determine which format to download the file in, and then download or export the file.
This will download the file to $destinationPath with the name of the file in Google Drive.
Upload to Drive
Get the source file, encode in Base64 and get the MIME type.
Set the file metadata. Additional properties can be added as needed. Reference the files/create
documentation for additional properties.
Build the multipart upload body from the base64 data and the file metadata.
Set the upload headers and perform the upload.
Uploading to a Specific Folder
To upload to a specific folder rather than to the root of your Google Drive, you need to specify a parent ID in the file metadata.
The API documentation says that parents should be an array, but it seems to error out if you provide more than one value. I don’t
fully understand the use case for multiple parents, but for simple uploads having 1 works just fine.
The folder ID can be seen in your address bar when browsing Google Drive. For example: https://drive.google.com/drive/folders/1hUL97Xd6tEiR-44fV7PYQ9BZaulA3ASg
Uploading to a Team Drive
If you would like to upload to a Team Drive rather than to your ‘My Drive’, you have to modify the $uploadMetadata and add &supportsTeamDrives=true to the upload URI. Similar to the ‘Uploading to a Specific Folder’
scenario, we must provide a parent ID. In this case the parent ID is either the team drive ID (to upload to the root of the team drive), or a folder ID (to upload to a folder within the team drive). We also have to
provide a teamDriveId, which can be found in your address bar, just like the folder ID.
When performing the upload, we change the -Uri parameter to include the parameter &supportsTeamDrives=true.
These could very easily be converted to functions, but the intent was to provide a framework on which to build, not a complete solution.