{"id":17381809,"url":"https://github.com/MVKozlov/GMGoogleDrive","last_synced_at":"2025-02-27T10:30:32.136Z","repository":{"id":20055787,"uuid":"88717616","full_name":"MVKozlov/GMGoogleDrive","owner":"MVKozlov","description":"Google Drive REST Api module for Powershell","archived":false,"fork":false,"pushed_at":"2024-07-22T12:23:50.000Z","size":246,"stargazers_count":40,"open_issues_count":0,"forks_count":11,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-07-22T14:22:47.188Z","etag":null,"topics":["google","google-api","google-drive","googledrive","powershell","powershell-module","rest"],"latest_commit_sha":null,"homepage":null,"language":"PowerShell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MVKozlov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-04-19T07:59:45.000Z","updated_at":"2024-07-22T12:21:25.000Z","dependencies_parsed_at":"2023-02-17T15:15:45.962Z","dependency_job_id":"7774e60e-bed8-4357-bb76-e9182b75ed6d","html_url":"https://github.com/MVKozlov/GMGoogleDrive","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MVKozlov%2FGMGoogleDrive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MVKozlov%2FGMGoogleDrive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MVKozlov%2FGMGoogleDrive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MVKozlov%2FGMGoogleDrive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MVKozlov","download_url":"https://codeload.github.com/MVKozlov/GMGoogleDrive/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219842823,"owners_count":16556564,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["google","google-api","google-drive","googledrive","powershell","powershell-module","rest"],"created_at":"2024-10-16T07:01:54.570Z","updated_at":"2024-10-16T07:04:50.502Z","avatar_url":"https://github.com/MVKozlov.png","language":"PowerShell","funding_links":[],"categories":["PowerShell"],"sub_categories":[],"readme":"# GMGoogleDrive\n\nGoogle Drive REST Api module for Powershell\nwith Google Sheets API support\n\n## Table of Contents\n\n- [GoogleDrive Setup](#googledrive-setup)\n- [Usage](#usage)\n- [Error Handling](#error-handling)\n- [Automate things](#automate-things)\n- [Using a service account](#using-a-service-account)\n\n---\n\n### GoogleDrive Setup\n\nGoogle Drive is a free service for file storage files. In order to use this storage you need a Google (or Google Apps) user which will own the files, and a Google API client.\n\n 1. Go to the [Google Developers console](https://console.developers.google.com/project) and create a new project.\n    - Now you should be on the [Project Dashboard](https://console.cloud.google.com/home/dashboard)\n 2. Go to **APIs \u0026 Services** \u003e **APIs** and enable **Drive API** and **Sheets API**.\n\n#### Using Web client OAuth 2.0\n\n 1. Click **Credentials**\n 2. Create **OAuth Client ID** Credentials\n 3. Select **Web Application** as product type\n 4. Configure the **Authorized Redirect URI** to https://developers.google.com/oauthplayground _must not have a ending “/” in the URI_\n 5. Save your **Client ID** and **Secret** or full OAuth string\n 6. Now you will have a `Client ID`, `Client Secret`, and `Redirect URL`.\n 7. You can convert oauth string to oauth `PSObject` for future use\n\n    ``` powershell\n    $oauth_json = '{\"web\":{\"client_id\":\"10649365436h34234f34hhqd423478fsdfdo.apps.googleusercontent.com\",\n      \"client_secret\":\"h78H78h7*H78h87\",\n      \"redirect_uris\":[\"https://developers.google.com/oauthplayground\"]}}' | ConvertFrom-Json\n    ```\n\n 8. Request Authroization Code  \n\n      - by powershell\n\n      ``` powershell\n      $code = Request-GDriveAuthorizationCode -ClientID $oauth_json.web.client_id `\n        -ClientSecret $oauth_json.web.client_secret\n      ```\n\n      - or manually\n        1. Browse to https://developers.google.com/oauthplayground\n        2. Click the gear in the right-hand corner and select “_Use your own OAuth credentials_\"\n        3. Fill in OAuth Client ID and OAuth Client secret\n        4. Authorize the API scopes\n            - https://www.googleapis.com/auth/drive\n            - https://www.googleapis.com/auth/drive.file\n            - https://www.googleapis.com/auth/spreadsheets\n        5. Save `Authorization Code` or directly **Exchange authorization code** for tokens\n        6. Save `Refresh token`, it can not be requested again without new Authorization code\n 9. Get refresh Token\n\n      - by powershell\n\n      ``` powershell\n      $refresh = Request-GDriveRefreshToken -ClientID $oauth_json.web.client_id `\n        -ClientSecret $oauth_json.web.client_secret `\n        -AuthorizationCode $code\n      ```\n\n      - manually\n\n        you already have it if you do **8.5** + **8.6**\n\n 10. `Authentication Token` - mandatory parameter for almost every `GDrive` cmdlets, and it need to be refreshed every hour, so you should get it (and can refresh it) at the beginning of your actual work with google drive\n\n      ``` powershell\n      $access = Get-GDriveAccessToken -ClientID $oauth_json.web.client_id `\n        -ClientSecret $oauth_json.web.client_secret `\n        -RefreshToken $refresh.refresh_token\n      ```\n\n#### Using a service account\n\nUsing a service account allows you to upload data to folders that are shared with the service account.\n\nIn Google Workspace enterprise environments, it is also possible to grant impersonation rights to the service account. With these rights, the service account can act as a user (without OAuth consent screen).\n\nPlease check the Google documentation:\n\n- [Create a service account](https://developers.google.com/workspace/guides/create-credentials#create_a_service_account)\n- [Assign impersonation rights (domain-wide delegation)](https://developers.google.com/workspace/guides/create-credentials#optional_set_up_domain-wide_delegation_for_a_service_account)\n\nGoogle offers two types of service user files .json and .p12. Both types are implemented in this module.\n\n``` PowerShell\nGet-GDriveAccessToken `\n  -Path D:\\service_account.json -JsonServiceAccount `\n  -ImpersonationUser \"user@domain.com\"\n```\n\n``` PowerShell\n$keyData = Get-Content -AsByteStream -Path D:\\service_account.p12\nGet-GDriveAccessToken `\n  -KeyData $KeyData `\n  -KeyId 'd41d8cd98f0b24e980998ecf8427e' `\n  -ServiceAccountMail test-account@980998ecf8427e.iam.gserviceaccount.com `\n  -ImpersonationUser \"user@domain.com\"\n```\n\n### Usage\n\n``` powershell\n# Upload new file\nAdd-GDriveItem -AccessToken $access.access_token -InFile D:\\SomeDocument.doc -Name SomeDocument.doc\n# Search existing file\nFind-GDriveItem -AccessToken $access.access_token -Query 'name=\"test.txt\"'\n# Update existing file contents\nSet-GDriveItemContent -AccessToken $access.access_token -ID $file.id -StringContent 'test file'\n# Get ParentFolderID and Modified Time for file\nGet-GDriveItemProperty -AccessToken $access.access_token -ID $file.id -Property parents, modifiedTime\n# and so on :)\n```\n\n### Error Handling\n\nCmdlets exiting at the first error, but, for example if Metadata Upload succeded but content upload failed, _UploadID_ as **ResumeID** returned for resume operations later\n\nIf Error catched, error record can be decoded by Get-GDriveError\n\n``` powershell\n # save error to variable\n try { Get-GDriveItemProperty -AccessToken 'error token' -id 'error id' } catch { $err = $_ }\n # decode error\n Get-GDriveError $err\n```\n\n### Automate things\n\nFor automatic usage (for example from task scheduler) you must save your credentials secure way.\n\nFor this task you can use these functions (if you do not need something even more secure):\n\n``` powershell\nfunction Protect-String {\n\u003c#\n  .SYNOPSIS\n    Convert String to textual form of SecureString\n  .PARAMETER String\n    String to convert\n  .OUTPUTS\n    String\n  .NOTES\n    Author: MVKozlov\n#\u003e\nparam(\n  [Parameter(Mandatory=$true, ValueFromPipeline=$true)]\n  [string]$String\n)\nPROCESS {\n  $String | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString\n}\n}\n\nfunction Unprotect-String {\n\u003c#\n  .SYNOPSIS\n    Convert SecureString to string\n  .PARAMETER String\n    String to convert (textual form of SecureString)\n  .PARAMETER SecureString\n    SecureString to convert\n  .OUTPUTS\n    String\n  .NOTES\n    Author: MVKozlov\n#\u003e\n[CmdletBinding(DefaultParameterSetName='s')]\nparam(\n  [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0, ParameterSetName='s')]\n  [string]$String,\n  [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0, ParameterSetName='ss')]\n  [SecureString]$SecureString\n)\nPROCESS {\n  if ($String) {\n    $SecureString = $String | ConvertTo-SecureString\n  }\n  if ($SecureString) {\n    (New-Object System.Net.NetworkCredential '', ($SecureString)).Password\n  }\n}\n}\n```\n\nFirst you manually launch powershell on machine that will run you script and under needed user.\nThen you construct your GDrive credentials object and save it securely:\n\n``` powershell\n[PSCustomObject]@{\n  ClientID = 'clientid'\n  ClientSecret = 'clientsecret'\n  RefreshToken = 'refreshtoken'\n} | ConvertTo-Json | Protect-String | Set-Content -Path C:\\Path\\somefile\n```\n\nAnd in your automatic script you get saved data, decode it and use:\n\n``` powershell\n$Credentials = Get-Content -Path C:\\path\\somefile | Unprotect-String | ConvertFrom-JSon\n\ntry {\n  Write-Host \"Getting Access token\"\n  $Token = Get-GDriveAccessToken -ClientID $Credentials.ClientID `\n  -ClientSecret $Credentials.ClientSecret -RefreshToken $Credentials.RefreshToken\n  Write-Host \"Token expires at $([DateTime]::Now.AddSeconds($Token.expires_in))\"\n}\ncatch {\n  Write-Warning \"Error getting Access token $_\"\n  Get-GDriveError $_\n}\nif ($Token) {\n  $Summary = Get-GDriveSummary -AccessToken $Token.access_token -ErrorAction Stop\n  # [...]\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMVKozlov%2FGMGoogleDrive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMVKozlov%2FGMGoogleDrive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMVKozlov%2FGMGoogleDrive/lists"}