Public/Request-GDriveAuthorizationCode.ps1
<# .SYNOPSIS Request Authorization code to work with GoogleDrive .DESCRIPTION Request Authorization code to work with GoogleDrive If user logged into google account or username/password supplied that can be automatic NOT intended for use in scripts! Only cmdline with UI and real user behind the keyboard .PARAMETER ClientID OAuth2 Client ID .PARAMETER ClientSecret OAuth2 Client Secret .PARAMETER Automatic DANGEROUS! Try to automatically approve access .PARAMETER Credential DANGEROUS! Google account username/password to automatic code request .PARAMETER RefreshToken OAuth2 RefreshToken .EXAMPLE $oauth_json = $oauth | ConvertFrom-Json $code = Request-GDriveAuthorizationCode -ClientID $oauth_json.web.client_id -ClientSecret $oauth_json.web.client_secret Request-GDriveRefreshToken -ClientID $oauth_json.web.client_id -ClientSecret $oauth_json.web.client_secret -AuthorizationCode $code .EXAMPLE $oauth_json = $oauth | ConvertFrom-Json $code = Request-GDriveAuthorizationCode -ClientID $oauth_json.web.client_id -ClientSecret $oauth_json.web.client_secret -Automatic Request-GDriveRefreshToken -ClientID $oauth_json.web.client_id -ClientSecret $oauth_json.web.client_secret -AuthorizationCode $code .OUTPUTS None .NOTES Author: Max Kozlov .LINK Get-GDriveAccessToken Request-GDriveRefreshToken Revoke-GDriveToken https://developers.google.com/drive/api/v3/about-auth https://developers.google.com/identity/protocols/OAuth2 https://developers.google.com/identity/protocols/OAuth2InstalledApp https://developers.google.com/identity/protocols/OAuth2WebServer #> function Request-GDriveAuthorizationCode { [CmdletBinding(DefaultParameterSetName='manual')] param( [Parameter(Mandatory, Position=0, ParameterSetName='auto')] [Parameter(Mandatory, Position=0, ParameterSetName='manual')] [string]$ClientID, [Parameter(Mandatory, Position=1, ParameterSetName='auto')] [Parameter(Mandatory, Position=1, ParameterSetName='manual')] [string]$ClientSecret, [Parameter(Mandatory, ParameterSetName='auto')] [switch]$Automatic, [Parameter(ParameterSetName='auto')] [PSCredential][System.Management.Automation.Credential()]$Credential, [string]$RedirectUri = 'https://developers.google.com/oauthplayground' ) If ($PSBoundParameters['Debug']) { $DebugPreference = 'Continue' } $scope = [System.Uri]::EscapeDataString($GDriveAuthScope) $Uri = '{0}?access_type={1}&response_type={2}&prompt={3}&client_id={4}&redirect_uri={5}&scope={6}&include_granted_scopes={7}' -f $GDriveAccountsTokenUri, 'offline', 'code', 'consent', $ClientID, [System.Uri]::EscapeDataString($RedirectUri), $scope, 'true' Write-Verbose $Uri Write-Debug "ErrorActionPreference $ErrorActionPreference" try { $ie = New-Object -ComObject InternetExplorer.Application } catch { throw "Unsupported. Can't load InternetExplorer COM Application: ($_.Exception)" } $ie.Navigate($Uri) #code variant #while ($ie.ReadyState -ne 4) #$ie.Document.getElementById("email").value = $username if ($PSBoundParameters.ContainsKey('Debug') -or (-not $Automatic)) { Write-Debug 'Not automatic access' $ie.Visible = $true $Automatic = $false } if ($PSBoundParameters.ContainsKey('Credential') -and -Not ($Credential)) { $Credential = Get-Credential } if ($Credential) { $Username = $Credential.UserName $Password = $Credential.GetNetworkCredential().Password } else { $Username = $Password = $null } $loginstate = 0 $forms = $email = $emailbutton = $passwd = $passwdbutton = $accessbutton = $null do { try { do { Start-Sleep -Milliseconds 500 } while ($ie.Busy -eq $true) $forms = $ie.Document | Select-Object -ExpandProperty forms $formparent = $forms | ForEach-Object { $_.parentNode.parentNode } $formnext = $formparent.nextSibling $child = $formnext.firstChild while ($null -ne $child) { $btnattr = $child.attributes | Where-Object { $_.nodeName -eq 'role' -and $_.nodeValue -eq 'button' } if ($null -ne $btnattr) { if ($loginstate -eq 0) { $emailbutton = $child } elseif ($loginstate -eq 1) { $passwdbutton = $child } elseif ($loginstate -eq 2) { $accessbutton = $child } break; } $child = $child.firstChild } $forms.Item(0) | Foreach-Object { $object = $_ Write-Debug "Found $($object.id)" switch ($_.id) { 'identifierId' { Write-Debug 'identifierId field found' $email = $object } 'Email' { Write-Debug 'Email field found' $email = $object } 'next' { Write-Debug 'Email next button found' $emailbutton = $object } 'Passwd' { Write-Debug 'Passwd field found' $passwd = $object } 'signIn' { Write-Debug 'Signin button found' $passwdbutton = $object } 'submit_approve_access' { Write-Debug 'Approve access button found' $accessbutton = $object } 'logincaptcha' { Write-Warning 'Captcha found !' $ie.Visible = $true $Automatic = $false } '' { if ($object.type -eq 'password') { Write-Debug 'Password field found' $passwd = $object } } } } # foreach Write-Debug "loginstate $loginstate" if ($ie.Document.url -match "^$RedirectUri") { Write-Debug "Exiting IE cycle" $loginstate = 4 } elseif ($email -and $emailbutton) { $loginstate = 1 if ($UserName) { Write-Debug 'Username present' if ($Automatic) { Write-Debug 'Next Click' $email.Value = $UserName try { $emailbutton.Click() } catch { Write-Debug "Email click Error $_" } } } else { Write-Debug 'Username not present' Write-Warning 'Username not found, turn off Automatic' $ie.Visible = $true $Automatic = $false } } elseif ($passwd -and $passwdbutton) { $loginstate = 2 if ($Password) { Write-Debug 'Password present' if ($Automatic) { Write-Debug 'Passwd Click' $passwd.Value = $Password try { $passwdbutton.Click() } catch { Write-Debug "Password click Error $_" } } } else { Write-Debug 'Password not present' Write-Warning 'Password not found, turn off Automatic' $ie.Visible = $true $Automatic = $false } } elseif ($accessbutton) { $loginstate = 3 if ($Automatic) { Write-Debug 'Approve Click' try { $accessbutton.Click() } catch { Write-Debug "Approve click Error $_" } } } } catch { $loginstate = -1 $err = $_ break } $forms = $email = $emailbutton = $passwd = $passwdbutton = $accessbutton = $null } until ($loginstate -eq 4) if ($loginstate -eq -1) { Write-Error $err } else { $url = $ie.Document.url if ($Automatic) { $ie.Quit() } $ie = $null [System.GC]::Collect(); [System.GC]::WaitForPendingFinalizers(); [System.GC]::Collect() if ($url -match "/?code=") { $code = $url -replace '.*/?code=' -replace '[&#].*' $code } else { Write-Error ($url -replace '.*/?error=' -replace '[&#].*') -Category PermissionDenied } } } |