Ke hana ʻana i nā mea hoʻohana Google mai PowerShell ma o API

Alohaʻoe!

E wehewehe kēia ʻatikala i ka hoʻokō ʻana o ka pilina PowerShell me ka Google API e hoʻopunipuni i nā mea hoʻohana G Suite.

Hoʻohana mākou i kekahi mau lawelawe kūloko a me ke ao a puni ka hui. No ka hapa nui, hiki mai ka mana i loko o Google a i ʻole Active Directory, ma waena o ka mea ʻaʻole hiki iā mākou ke mālama i kahi kope; no laila, ke haʻalele kahi limahana hou, pono ʻoe e hana a hiki i kahi moʻokāki ma kēia mau ʻōnaehana ʻelua. No ka hoʻokaʻawale ʻana i ke kaʻina hana, ua hoʻoholo mākou e kākau i kahi palapala e hōʻiliʻili i ka ʻike a hoʻouna ʻia i nā lawelawe ʻelua.

ʻO kaʻaeʻana

Ke kākau nei i nā koi, ua hoʻoholo mākou e hoʻohana i nā luna hoʻomalu kanaka maoli no ka ʻae ʻia; hoʻomaʻamaʻa kēia i ka nānā ʻana o nā hana i ka wā o nā loli nui a i ʻole ka manaʻo.

Hoʻohana nā API Google i ka protocol OAuth 2.0 no ka hōʻoia a me ka ʻae. Hiki ke loaʻa i nā hihia hoʻohana a me nā wehewehe kikoʻī hou aku ma aneʻi: Ke hoʻohana nei iā OAuth 2.0 e kiʻi i nā API Google.

Ua koho au i ka palapala i hoʻohana ʻia no ka ʻae ʻana i nā noi papa. Aia kekahi koho e hoʻohana i kahi moʻokāki lawelawe, ʻaʻole koi i nā neʻe pono ʻole mai ka mea hoʻohana.

ʻO ke kiʻi ma lalo nei he wehewehe kikoʻī o ke ʻano i koho ʻia mai ka ʻaoʻao Google.

Ke hana ʻana i nā mea hoʻohana Google mai PowerShell ma o API

  1. ʻO ka mea mua, hoʻouna mākou i ka mea hoʻohana i ka ʻaoʻao hōʻoia moʻokāki Google, e kuhikuhi ana i nā ʻāpana GET:
    • id noi
    • nā wahi e pono ai ke komo i ka polokalamu
    • ka helu wahi e hoʻihoʻi ʻia ai ka mea hoʻohana ma hope o ka pau ʻana o ke kaʻina hana
    • ke ala e hoʻonui ai mākou i ka hōʻailona
    • Code Palekana
    • hōʻano hōʻoia hōʻoia

  2. Ma hope o ka pau ʻana o ka ʻae ʻana, e hoʻihoʻi ʻia ka mea hoʻohana i ka ʻaoʻao i kuhikuhi ʻia ma ka noi mua, me ka hewa a i ʻole ka palapala ʻae i kau ʻia e nā ʻāpana GET
  3. Pono ka palapala noi (script) e loaʻa i kēia mau ʻāpana a, inā loaʻa ke code, e hana i kēia noi e loaʻa nā hōʻailona.
  4. Inā pololei ka noi, e hoʻi ka Google API:
    • Hiki iā mākou ke hana i nā noi
    • ʻO ka manawa kūpono o kēia hōʻailona
    • Pono ka hōʻailona hōʻano hou e hōʻano hou i ka hōʻailona Access.

Pono mua ʻoe e hele i ka Google API console: Palapala hōʻoia - Google API Console, koho i ka noi makemake a ma ka ʻāpana Credentials e hana i kahi mea hoʻohana OAuth identifier. Ma laila (a i ʻole ma hope, i nā waiwai o ka mea i hoʻokumu ʻia) pono ʻoe e kuhikuhi i nā ʻōlelo i ʻae ʻia ka redirection. I kā mākou hihia, e lilo kēia i mau helu localhost me nā awa like ʻole (e ʻike i lalo).

I mea e maʻalahi ai ka heluhelu ʻana i ka algorithm script, hiki iā ʻoe ke hōʻike i nā ʻanuʻu mua i kahi hana ʻokoʻa e hoʻihoʻi i ka Access a me ka hōʻano hou i nā hōʻailona no ka noi:

$client_secret = 'Our Client Secret'
$client_id = 'Our Client ID'
function Get-GoogleAuthToken {
  if (-not [System.Net.HttpListener]::IsSupported) {
    "HttpListener is not supported."
    exit 1
  }
  $codeverifier = -join ((65..90) + (97..122) + (48..57) + 45 + 46 + 95 + 126 |Get-Random -Count 60| % {[char]$_})
  $hasher = new-object System.Security.Cryptography.SHA256Managed
  $hashByteArray = $hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($codeverifier))
  $base64 = ((([System.Convert]::ToBase64String($hashByteArray)).replace('=','')).replace('+','-')).replace('/','_')
  $ports = @(10600,15084,39700,42847,65387,32079)
  $port = $ports[(get-random -Minimum 0 -maximum 5)]
  Write-Host "Start browser..."
  Start-Process "https://accounts.google.com/o/oauth2/v2/auth?code_challenge_method=S256&code_challenge=$base64&access_type=offline&client_id=$client_id&redirect_uri=http://localhost:$port&response_type=code&scope=https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/admin.directory.group"
  $listener = New-Object System.Net.HttpListener
  $listener.Prefixes.Add("http://localhost:"+$port+'/')
  try {$listener.Start()} catch {
    "Unable to start listener."
    exit 1
  }
  while (($code -eq $null)) {
    $context = $listener.GetContext()
    Write-Host "Connection accepted" -f 'mag'
    $url = $context.Request.RawUrl
    $code = $url.split('?')[1].split('=')[1].split('&')[0]
    if ($url.split('?')[1].split('=')[0] -eq 'error') {
      Write-Host "Error!"$code -f 'red'
      $buffer = [System.Text.Encoding]::UTF8.GetBytes("Error!"+$code)
      $context.Response.ContentLength64 = $buffer.Length
      $context.Response.OutputStream.Write($buffer, 0, $buffer.Length)
      $context.Response.OutputStream.Close()
      $listener.Stop()
      exit 1
    }
    $buffer = [System.Text.Encoding]::UTF8.GetBytes("Now you can close this browser tab.")
    $context.Response.ContentLength64 = $buffer.Length
    $context.Response.OutputStream.Write($buffer, 0, $buffer.Length)
    $context.Response.OutputStream.Close()
    $listener.Stop()
  }
  Return Invoke-RestMethod -Method Post -Uri "https://www.googleapis.com/oauth2/v4/token" -Body @{
    code = $code
    client_id = $client_id
    client_secret = $client_secret
    redirect_uri = 'http://localhost:'+$port
    grant_type = 'authorization_code'
    code_verifier   = $codeverifier
  }
  $code = $null

Hoʻonoho mākou i ka Client ID a me ka mea huna mea kūʻai mai i loaʻa i loko o ka OAuth client identifier properties, a ʻo ka hōʻoia code he string o 43 a 128 mau huaʻōlelo pono e hana ʻia mai nā huaʻōlelo i mālama ʻole ʻia: [AZ] / [az] / [0-9] / "-" / "." / "_" / "~".

E hoʻouna hou ʻia kēia code. Hoʻopau ia i ka nāwaliwali kahi e hiki ai i ka mea hoʻouka ke kea i kahi pane i hoʻihoʻi ʻia ma ke ʻano he redirect ma hope o ka ʻae ʻana o ka mea hoʻohana.
Hiki iā ʻoe ke hoʻouna i kahi hōʻoia code ma ka noi o kēia manawa ma kahi kikokikona maʻemaʻe (ʻo ia ka mea ʻole - kūpono kēia no nā ʻōnaehana i kākoʻo ʻole iā SHA256), a i ʻole ma ka hana ʻana i kahi hash me ka hoʻohana ʻana i ka algorithm SHA256, pono e hoʻopili ʻia ma BASE64Url (ʻokoʻa. mai Base64 e nā huaʻōlelo papaʻaina ʻelua) a me ka wehe ʻana i nā hopena laina ʻano: =.

A laila, pono mākou e hoʻomaka e hoʻolohe i ka http ma ka mīkini kūloko i mea e loaʻa ai kahi pane ma hope o ka ʻae ʻia, e hoʻihoʻi ʻia ma ke ʻano he redirect.

Hana ʻia nā hana hoʻokele ma kahi kikowaena kūikawā, ʻaʻole hiki iā mākou ke hoʻoholo i ka hiki ke holo i kekahi mau luna hoʻokele i ka palapala i ka manawa like, no laila e koho maʻamau ia i kahi awa no ka mea hoʻohana o kēia manawa, akā ua kuhikuhi wau i nā awa i koho mua ʻia no ka mea. pono e hoʻohui ʻia e like me ka hilinaʻi ʻana i ka console API.

access_type=pahemo 'o ia ho'i, hiki i ka palapala noi ke ho'ohou i kahi hō'ailona i pau i kona iho me ka launa 'ole o ka mea ho'ohana me ka polokalamu kele pūnaewele,
pane_type=code hoʻonohonoho i ke ʻano o ka hoʻihoʻi ʻia ʻana o ke code (kahi kuhikuhi i ke ala ʻae kahiko, i ka wā i kope ai ka mea hoʻohana i ke code mai ka polokalamu kele pūnaewele i ka palapala),
nui hōʻike i ka laulā a me ke ʻano o ke komo ʻana. Pono lākou e hoʻokaʻawale ʻia e nā hakahaka a i ʻole %20 (e like me ka URL Encoding). Hiki ke ʻike ʻia kahi papa inoa o nā wahi komo me nā ʻano: ʻO ka OAuth 2.0 no nā API Google.

Ma hope o ka loaʻa ʻana o ke code ʻae, e hoʻihoʻi ka noi i kahi leka kokoke i ka polokalamu kele pūnaewele, e hoʻōki i ka hoʻolohe ʻana ma ke awa a hoʻouna i kahi noi POST e kiʻi i ka hōʻailona. Hōʻike mākou i loko o ia i ka id a me ka mea huna i hōʻike mua ʻia mai ka console API, ka helu wahi e hoʻihoʻi ʻia ai ka mea hoʻohana a hāʻawi ʻia e like me ka kikoʻī protocol.

Ma ka pane, e loaʻa iā mākou kahi hōʻailona Access, kona manawa kūpono i kekona, a me kahi hōʻailona Refresh, kahi e hiki ai iā mākou ke hōʻano hou i ka token Access.

Pono ka palapala noi e mālama i nā hōʻailona ma kahi palekana me ka lōʻihi o ke ola, no laila a hiki i ka wā e hoʻopau ai mākou i ka loaʻa ʻana, ʻaʻole e hoʻihoʻi ka palapala noi i ka hōʻailona hōʻano hou. I ka hopena, ua hoʻohui au i kahi noi e hoʻopau i ka hōʻailona; inā ʻaʻole i hoʻopau maikaʻi ʻia ka noi a ʻaʻole i hoʻihoʻi ʻia ka hōʻailona hōʻoluʻolu, e hoʻomaka hou ke kaʻina hana (ua manaʻo mākou ʻaʻole palekana ka mālama ʻana i nā hōʻailona ma ka ʻāina, a ʻaʻole mākou. 'aʻole makemake e hoʻopili i nā mea me ka cryptography a i ʻole e wehe pinepine i ka polokalamu kele pūnaewele).

do {
  $token_result = Get-GoogleAuthToken
  $token = $token_result.access_token
  if ($token_result.refresh_token -eq $null) {
    Write-Host ("Session is not destroyed. Revoking token...")
    Invoke-WebRequest -Uri ("https://accounts.google.com/o/oauth2/revoke?token="+$token)
  }
} while ($token_result.refresh_token -eq $null)
$refresh_token = $token_result.refresh_token
$minute = ([int]("{0:mm}" -f ([timespan]::fromseconds($token_result.expires_in))))+((Get-date).Minute)-2
if ($minute -lt 0) {$minute += 60}
elseif ($minute -gt 59) {$minute -=60}
$token_expire = @{
  hour = ([int]("{0:hh}" -f ([timespan]::fromseconds($token_result.expires_in))))+((Get-date).Hour)
  minute = $minute
}

E like me kāu i ʻike mua ai, i ka wā e hoʻopau ai i kahi hōʻailona, ​​hoʻohana ʻia ʻo Invoke-WebRequest. ʻAʻole like me Invoke-RestMethod, ʻaʻole ia e hoʻihoʻi i ka ʻikepili i loaʻa i kahi ʻano hoʻohana a hōʻike i ke kūlana o ka noi.

A laila, noi ka palapala iā ʻoe e hoʻokomo i ka inoa mua a me ka inoa hope o ka mea hoʻohana, e hana ana i kahi login + leka uila.

Nā noi

ʻO nā noi hou aʻe - ʻo ka mea mua, pono ʻoe e nānā inā aia kahi mea hoʻohana me ka loina like i mea e loaʻa ai ka hoʻoholo i ka hana ʻana i kahi mea hou a i ʻole ka hiki ʻana i ka mea o kēia manawa.

Ua hoʻoholo wau e hoʻokō i nā noi āpau ma ke ʻano o hoʻokahi hana me kahi koho, me ka hoʻohana ʻana i ka hoʻololi:

function GoogleQuery {
  param (
    $type,
    $query
  )
  switch ($type) {
    "SearchAccount" {
      Return Invoke-RestMethod -Method Get -Uri "https://www.googleapis.com/admin/directory/v1/users" -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body @{
        domain = 'rocketguys.com'
        query  = "email:$query"
      }
    }
    "UpdateAccount" {
      $body = @{
        name  = @{
          givenName = $query['givenName']
          familyName = $query['familyName']
        }
        suspended = 'false'
        password = $query['password']
        changePasswordAtNextLogin = 'true'
        phones = @(@{
          primary = 'true'
          value = $query['phone']
          type = "mobile"
        })
        orgUnitPath = $query['orgunit']
      }
      Return Invoke-RestMethod -Method Put -Uri ("https://www.googleapis.com/admin/directory/v1/users/"+$query['email']) -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body (ConvertTo-Json $body) -ContentType 'application/json; charset=utf-8'
    }
    
    "CreateAccount" {
      $body = @{
        primaryEmail = $query['email']
        name  = @{
          givenName = $query['givenName']
          familyName = $query['familyName']
        }
        suspended = 'false'
        password = $query['password']
        changePasswordAtNextLogin = 'true'
        phones = @(@{
          primary = 'true'
          value = $query['phone']
          type = "mobile"
        })
        orgUnitPath = $query['orgunit']
      }
      Return Invoke-RestMethod -Method Post -Uri "https://www.googleapis.com/admin/directory/v1/users" -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body (ConvertTo-Json $body) -ContentType 'application/json; charset=utf-8'
    }
    "AddMember" {
      $body = @{
        userKey = $query['email']
      }
      $ifrequest = Invoke-RestMethod -Method Get -Uri "https://www.googleapis.com/admin/directory/v1/groups" -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body $body
      $array = @()
      foreach ($group in $ifrequest.groups) {$array += $group.email}
      if ($array -notcontains $query['groupkey']) {
        $body = @{
          email = $query['email']
          role = "MEMBER"
        }
        Return Invoke-RestMethod -Method Post -Uri ("https://www.googleapis.com/admin/directory/v1/groups/"+$query['groupkey']+"/members") -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body (ConvertTo-Json $body) -ContentType 'application/json; charset=utf-8'
      } else {
        Return ($query['email']+" now is a member of "+$query['groupkey'])
      }
    }
  }
}

I kēlā me kēia noi, pono ʻoe e hoʻouna i kahi poʻomanaʻo Manaʻo i loaʻa ke ʻano token a me ka token Access ponoʻī. I kēia manawa, ʻo ke ʻano token ka mea lawe mau. No ka mea pono mākou e nānā ʻaʻole i pau ka hōʻailona a hōʻano hou iā ia ma hope o hoʻokahi hola mai ka manawa i hoʻopuka ʻia ai, ua kuhikuhi wau i kahi noi no kahi hana ʻē aʻe e hoʻihoʻi i kahi hōʻailona Access. Aia ka ʻāpana helu like ma ka hoʻomaka o ka palapala i ka wā e loaʻa ai ka hōʻailona Access mua:

function Get-GoogleToken {
  if (((Get-date).Hour -gt $token_expire.hour) -or (((Get-date).Hour -ge $token_expire.hour) -and ((Get-date).Minute -gt $token_expire.minute))) {
  Write-Host "Token Expired. Refreshing..."
    $request = (Invoke-RestMethod -Method Post -Uri "https://www.googleapis.com/oauth2/v4/token" -ContentType 'application/x-www-form-urlencoded' -Body @{
      client_id = $client_id
      client_secret = $client_secret
      refresh_token = $refresh_token
      grant_type = 'refresh_token'
    })
    $token = $request.access_token
    $minute = ([int]("{0:mm}" -f ([timespan]::fromseconds($request.expires_in))))+((Get-date).Minute)-2
    if ($minute -lt 0) {$minute += 60}
    elseif ($minute -gt 59) {$minute -=60}
    $script:token_expire = @{
      hour = ([int]("{0:hh}" -f ([timespan]::fromseconds($request.expires_in))))+((Get-date).Hour)
      minute = $minute
    }
  }
  return $token
}

Ke nānā nei i ke komo ʻana no ke ola ʻana:

function Check_Google {
  $query = (GoogleQuery 'SearchAccount' $username)
  if ($query.users -ne $null) {
    $user = $query.users[0]
    Write-Host $user.name.fullName' - '$user.PrimaryEmail' - suspended: '$user.Suspended
    $GAresult = $user
  }
  if ($GAresult) {
      $return = $GAresult
  } else {$return = 'gg'}
  return $return
}

E noi ka leka uila:$query noi i ka API e ʻimi i mea hoʻohana me kēlā leka uila, me nā inoa inoa. Hiki iā ʻoe ke hoʻohana i ka wildcard: =, :, :{PREFIX}*.

No ka loaʻa ʻana o ka ʻikepili, e hoʻohana i ke ʻano noi noi GET, e hoʻokomo i ka ʻikepili (hana i kahi moʻokāki a hoʻohui i kahi lālā i kahi hui) - POST, e hoʻonui i ka ʻikepili i loaʻa - PUT, e holoi i kahi moʻolelo (no ka laʻana, he lālā mai kahi hui) - HELE.

E noi pū ka palapala i kahi helu kelepona (kahi kaula i hoʻopaʻa ʻole ʻia) a no ka hoʻokomo ʻana i loko o kahi pūʻulu māhele āpana. Hoʻoholo ʻo ia i ka hui hui e pono ai ka mea hoʻohana ma muli o ka Active Directory OU i koho ʻia a loaʻa mai kahi ʻōlelo huna:

do {
  $phone = Read-Host "Телефон в формате +7хххххххх"
} while (-not $phone)
do {
    $moscow = Read-Host "В Московский офис? (y/n) "
} while (-not (($moscow -eq 'y') -or ($moscow -eq 'n')))
$orgunit = '/'
if ($OU -like "*OU=Delivery,OU=Users,OU=ROOT,DC=rocket,DC=local") {
    Write-host "Будет создана в /Team delivery"
    $orgunit = "/Team delivery"
}
$Password =  -join ( 48..57 + 65..90 + 97..122 | Get-Random -Count 12 | % {[char]$_})+"*Ba"

A laila hoʻomaka ʻo ia e hoʻopunipuni i ka moʻolelo:

$query = @{
  email = $email
  givenName = $firstname
  familyName = $lastname
  password = $password
  phone = $phone
  orgunit = $orgunit
}
if ($GMailExist) {
  Write-Host "Запускаем изменение аккаунта" -f mag
  (GoogleQuery 'UpdateAccount' $query) | fl
  write-host "Не забудь проверить группы у включенного $Username в Google."
} else {
  Write-Host "Запускаем создание аккаунта" -f mag
  (GoogleQuery 'CreateAccount' $query) | fl
}
if ($moscow -eq "y"){
  write-host "Добавляем в группу moscowoffice"
  $query = @{
    groupkey = '[email protected]'
    email = $email
  }
  (GoogleQuery 'AddMember' $query) | fl
}

ʻO nā hana no ka hoʻonui ʻana a me ka hana ʻana i kahi moʻokāki he syntax like; ʻaʻole koi ʻia nā kahua ʻē aʻe a pau; ma ka ʻāpana me nā helu kelepona, pono ʻoe e kuhikuhi i kahi ʻano i hiki ke loaʻa i hoʻokahi moʻolelo me ka helu a me kona ʻano.

I ʻole e loaʻa kahi hewa i ka hoʻohui ʻana i kahi mea hoʻohana i kahi hui, hiki iā mākou ke nānā mua inā he lālā ʻo ia o kēia hui ma ka loaʻa ʻana o kahi papa inoa o nā lālā hui a i ʻole ka haku ʻana mai ka mea hoʻohana iā ia iho.

ʻO ka nīnau ʻana i ka lālā hui o kahi mea hoʻohana kikoʻī ʻaʻole e hoʻihoʻi hou ʻia a e hōʻike wale i ka lālā pololei. Me ka mea hoʻohana i loko o kahi hui makua i loaʻa i kahi hui keiki i lālā ka mea hoʻohana e kūleʻa.

hopena

ʻO ka mea i koe e hoʻouna i ka mea hoʻohana i ka ʻōlelo huna no ka moʻokāki hou. Hana mākou i kēia ma o SMS, a hoʻouna i ka ʻike maʻamau me nā ʻōlelo aʻoaʻo a me ka hoʻopaʻa inoa ʻana i kahi leka uila pilikino, a me kahi helu kelepona, i hāʻawi ʻia e ka ʻoihana hoʻolimalima. Ma ke ʻano he ʻokoʻa, hiki iā ʻoe ke mālama i ke kālā a hoʻouna i kāu ʻōlelo huna i kahi kamaʻilio telegram huna, hiki ke noʻonoʻo ʻia ʻo ia ke kumu ʻelua (ʻo MacBooks he ʻokoʻa).

Mahalo iā ʻoe no ka heluhelu ʻana a hiki i ka hopena. E hauʻoli wau i ka ʻike ʻana i nā manaʻo no ka hoʻomaikaʻi ʻana i ke ʻano o ka kākau ʻana i nā ʻatikala a makemake ʻoe e hopu i nā hewa liʻiliʻi ke kākau ʻana i nā palapala =)

Ka papa inoa o nā loulou i hoʻohana ʻia a pane wale i nā nīnau:

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka