Fausia Google Users mai le PowerShell e ala ile API

Привет!

O lenei tusiga o le a faʻamatalaina le faʻatinoga o fesoʻotaʻiga PowerShell ma le Google API e faʻaogaina ai tagata G Suite.

Matou te fa'aogaina le tele o auaunaga i totonu ma ao i totonu o le fa'alapotopotoga. Mo le tele o vaega, faʻatagaina i latou e sau i lalo i Google poʻo Active Directory, i le va e le mafai ona matou tausia se kopi; e tusa ai, pe a alu se tagata faigaluega fou, e te manaʻomia le fatuina / faʻatagaina se teugatupe i nei faiga e lua. Ina ia otometi le faagasologa, na matou filifili e tusi se tusitusiga e aoina ai faʻamatalaga ma lafo i auaunaga uma e lua.

Faatagaina

Pe a faʻatulagaina manaʻoga, na matou filifili e faʻaoga tagata moni mo le faʻatagaina; e faʻafaigofieina le auiliiliga o gaioiga pe a tupu faʻafuaseʻi poʻo suiga tetele.

Google API e fa'aogaina le OAuth 2.0 protocol mo le fa'amaoni ma le fa'atagaina. Fa'aoga mataupu ma nisi fa'amatalaga auiliili e mafai ona maua iinei: Fa'aaogā le OAuth 2.0 e fa'aoga ai Google API.

Na ou filifilia le faʻamatalaga e faʻaaogaina mo le faʻatagaina i luga o le komepiuta talosaga. O loʻo i ai foʻi se filifiliga e faʻaaoga ai se tala o auaunaga, lea e le manaʻomia ai ni gaioiga le manaʻomia mai le tagata faʻaoga.

O le ata o loʻo i lalo o se faʻamatalaga faʻapitoa o le ata filifilia mai le itulau Google.

Fausia Google Users mai le PowerShell e ala ile API

  1. Muamua, matou te lafoina le tagata faʻaoga i le Google Account authentication page, faʻamaonia GET tapulaʻa:
    • id talosaga
    • vaega e mana'omia e le talosaga ona maua
    • le tuatusi o le a toe fa'afo'i i ai le tagata fa'aoga pe a mae'a le fa'agasologa
    • le auala o le a matou faʻafouina ai le faʻailoga
    • Code Puipuiga
    • fa'ailoga fa'ailoga fa'ailoga fa'ailoga

  2. A maeʻa le faʻatagaina, o le a toe faʻafeiloaʻi le tagata faʻaoga i le itulau o loʻo faʻamaonia i le talosaga muamua, ma se mea sese poʻo se tulafono faʻatagaina na pasia e GET parakalafa
  3. O le talosaga (script) o le a manaʻomia le mauaina o nei taʻiala ma, afai e maua le code, fai le talosaga lenei e maua ai faʻailoga
  4. Afai e sa'o le talosaga, e toe fo'i mai le Google API:
    • Avanoa fa'ailoga e mafai ona matou faia ai talosaga
    • Ole taimi aoga ole fa'ailoga lea
    • Toe fa'afou fa'ailoga e mana'omia e fa'afou ai le Access token.

Muamua e tatau ona e alu i le Google API console: Fa'ailoga - Google API Console, filifili le talosaga e mana'omia ma i le vaega o Fa'ailoga e fai ai se tagata fa'asinomaga OAuth. O iina (pe mulimuli ane, i meatotino o le faʻamatalaga na faia) e tatau ona e faʻamaonia tuatusi e faʻatagaina ai le toe faʻafeiloaʻi. I la matou tulaga, o nei mea o le a tele faʻamatalaga localhost ma vaʻaiga eseese (vaʻai i lalo).

Ina ia sili atu ona faigofie le faitau o le script algorithm, e mafai ona e faʻaalia laasaga muamua i se isi galuega e toe faʻafoʻi ai le Avanoa ma faʻafouina faʻailoga mo le talosaga:

$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

Matou te setiina le Client ID ma le Client Secret na maua i le OAuth client identifier properties, ma o le code verifier o se manoa o le 43 i le 128 mataitusi e tatau ona faʻatupu faʻafuaseʻi mai mataitusi e le faʻasaoina: [AZ] / [az] / [0-9 ] / "-" / "." / "_" / "~".

O le a toe fa'asalalauina lea fa'ailoga. E aveesea ai le fa'aletonu e mafai ai e se tagata osofa'i ona fa'alavelaveina se tali na toe fa'afo'i mai pe a uma le fa'atagaina o tagata fa'aoga.
E mafai ona e tuʻuina atu se faʻamaonia code i le talosaga o loʻo i ai nei i tusitusiga manino (lea e leai se uiga - e talafeagai mo faiga e le lagolagoina SHA256), poʻo le fatuina o se hash e faʻaaoga ai le SHA256 algorithm, lea e tatau ona faʻailoga i BASE64Url (eseese. mai Base64 e lua mataitusi laulau) ma aveese le fa'ai'uga laina uiga: =.

Le isi, e manaʻomia ona amata faʻalogo i le http i luga o le masini faʻapitonuʻu ina ia maua ai se tali pe a uma le faʻatagaina, lea o le a toe faʻafoʻi mai o se toe faʻafeiloaʻi.

O galuega faʻafoe e faia i luga o se 'auʻaunaga faʻapitoa, e le mafai ona tatou faʻamaonia le avanoa e faʻatautaia ai e le tele o pule le tusitusiga i le taimi e tasi, o lea o le a filifili faʻafuaseʻi ai se taulaga mo le tagata o loʻo i ai nei, ae na ou faʻamaonia ports muamua ona e tatau foi ona faaopoopo e pei ona faatuatuaina i le API faamafanafana.

access_type=le initaneti o lona uiga e mafai e le talosaga ona faʻafouina se faʻailoga ua maeʻa na o ia lava e aunoa ma le faʻaogaina o tagata faʻaoga ma le browser,
response_type=code setiina le faatulagaga o le auala o le a toe faafoi ai le code (o se faʻamatalaga i le auala tuai faʻatagaina, pe a kopiina e le tagata faʻaoga le code mai le browser i totonu o le tusitusiga),
lautele fa'ailoa mai le lautele ma le ituaiga avanoa. E tatau ona tuueseese i avanoa po'o le %20 (e tusa ai ma le URL Encoding). O se lisi o nofoaga avanoa ma ituaiga e mafai ona vaʻaia iinei: OAuth 2.0 Va'aiga mo Google APIs.

A maeʻa ona maua le tulafono faʻatagaina, o le a toe faʻafoʻi e le talosaga se feʻau vavalalata i le masini, taofi le faʻalogo i luga o le taulaga ma lafo se talosaga POST e maua ai le faʻailoga. Matou te faʻaalia i totonu le id na faʻamaonia muamua ma mealilo mai le faʻamafanafanaga API, le tuatusi lea o le a toe faʻafeiloaʻi ai le tagata faʻaoga ma le foaʻi_type e tusa ai ma le faʻasalalauga faʻapitoa.

I le tali atu, o le a matou mauaina se Access token, lona taimi aoga i sekone, ma se Refresh token, lea e mafai ai ona matou faʻafouina le Access token.

O le talosaga e tatau ona teuina faʻailoga i se nofoaga malupuipuia ma se faʻataga umi, o lea seʻia oʻo ina matou faʻaumatia le avanoa na maua, o le a le toe faʻafoʻi e le talosaga le faʻailoga toe faʻafouina. I le faaiuga, sa ou faaopoopo i ai se talosaga e faalēaogā le faailoga; afai e leʻi maeʻa lelei le talosaga ma e leʻi toe faʻafoʻi mai le faʻailoga toe faʻafouina, o le a toe amata le faʻagasologa (matou te manatu e le saogalemu le teuina o faʻailoga i le lotoifale i luga o le laina, ma matou te faia. 'le mana'o e fa'afaigata mea i cryptography pe tatala so'o le su'ega).

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 pei ona uma ona e matauina, pe a soloia se faailoga, Invoke-WebRequest e faʻaaogaina. E le pei o Invoke-RestMethod, e le toe faʻafoʻi mai faʻamaumauga na maua i se faʻaoga faʻaoga ma faʻaalia le tulaga o le talosaga.

O le isi, o le tusitusiga e fai atu ia te oe e ulufale i le igoa muamua ma le igoa mulimuli o le tagata, fatuina se saini + imeli.

Talosaga

O isi talosaga o le a - muamua lava, e tatau ona e siaki pe o se tagata faʻaoga e tutusa le saini ua uma ona i ai ina ia maua ai se filifiliga i le fatuina o se mea fou poʻo le faʻatagaina o le taimi nei.

Na ou filifili e faʻatino uma talosaga i le faatulagaga o le tasi galuega ma se filifiliga, faʻaaoga le ki:

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 talosaga ta'itasi, e mana'omia le tu'uina atu o se ulutala Fa'atagaga o lo'o iai le ituaiga fa'ailoga ma le Access token lava ia. I le taimi nei, o le ituaiga faʻailoga e masani lava o Bearer. Aua matou te manaʻomia le siakiina e leʻi maeʻa le faʻailoga ma faʻafouina pe a maeʻa le itula mai le taimi na tuʻuina atu ai, na ou faʻamaonia se talosaga mo se isi galuega e toe faʻafoʻi mai ai le Access token. O le fasitusi lava lea e tasi o loʻo i le amataga o le tusitusiga pe a mauaina le faʻailoga muamua Access:

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
}

Siaki le saini mo le iai:

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
}

Ole imeli:$query request ole a ole atu ile API e su'e se tagata e fa'aoga tonu lena imeli, e aofia ai igoa ole igoa. E mafai fo'i ona e fa'aoga wildcard: =, :, :{PREFIX}*.

Mo le mauaina o faʻamatalaga, faʻaaoga le GET talosaga auala, e faʻapipiʻi ai faʻamatalaga (faia o se teugatupe pe faʻaopoopo se sui i se kulupu) - POST, faʻafouina faʻamatalaga o loʻo i ai - PUT, e tape se faʻamaumauga (mo se faʻataʻitaʻiga, se sui mai se vaega) - AVE.

Ole tusitusiga ole a ole atu foi mo se numera telefoni (se manoa e le'i fa'amaonia) ma mo le fa'aofiina i totonu o se vaega fa'asoa fa'aitulagi. E filifili po'o fea fa'alapotopotoga fa'alapotopotoga e tatau ona fa'atatau i le Active Directory OU ua filifilia ma maua mai ai se fa'aupuga:

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"

Ona amata lea ona ia pulea le tala:

$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 galuega mo le faʻafouina ma le fatuina o se tala e iai se faʻasologa tutusa; e le manaʻomia uma isi fanua; i le vaega ma numera telefoni, e tatau ona e faʻamaonia se laina e mafai ona aofia ai le tasi faʻamaumauga ma le numera ma lona ituaiga.

Ina ia le maua se mea sese pe a faʻaopoopo se tagata faʻaoga i se vaega, e mafai ona tatou siaki muamua pe o ia o se sui o lenei vaega e ala i le mauaina o se lisi o sui o le vaega poʻo se fatuga mai le tagata faʻaoga lava ia.

O le fesiligia o le sui auai o se tagata fa'apitoa o le a le toe fa'afoliga ma o le a na'o le fa'aali sa'o lava. E fa'aaofia ai se tagata fa'aoga i se vaega matua ua uma ona i ai se kulupu a tamaiti o lo'o avea le tagata fa'aoga ma sui o le a manuia.

iʻuga

Pau lava le mea o loʻo totoe o le tuʻuina atu lea i le tagata faʻaoga le upu faʻamaonia mo le tala fou. Matou te faia lenei mea e ala i SMS, ma auina atu faʻamatalaga lautele ma faʻatonuga ma saini i se imeli a le tagata lava ia, lea, faatasi ai ma se numera telefoni, na tuʻuina atu e le matagaluega faʻafaigaluega. I se isi itu, e mafai ona e faʻasaoina tupe ma lafo lau faʻaupuga i se talatalanoaga faalilolilo, lea e mafai foi ona manatu o le mea lona lua (MacBooks o se tuusaunoaga).

Faafetai mo le faitau e oo i le iuga. O le a ou fiafia e vaʻai i fautuaga mo le faʻaleleia o le faiga o le tusiaina o tala ma manaʻo e te maua ni nai mea sese pe a tusia ni tusitusiga =)

Lisi o feso'ota'iga e ono aoga fa'atatau pe na'o tali fesili:

puna: www.habr.com

Faaopoopo i ai se faamatalaga