A’ cruthachadh Google Users bho PowerShell tro API

Hello!

Bheir an artaigil seo cunntas air buileachadh eadar-obrachadh PowerShell le API Google gus luchd-cleachdaidh G Suite a làimhseachadh.

Bidh sinn a’ cleachdadh grunn sheirbheisean a-staigh agus sgòthan air feadh na buidhne. Airson a’ mhòr-chuid, tha ùghdarras annta a’ tighinn sìos gu Google no Active Directory, eadar nach urrainn dhuinn mac-samhail a chumail; a rèir sin, nuair a dh’ fhalbhas neach-obrach ùr, feumaidh tu cunntas a chruthachadh/comasachadh anns an dà shiostam seo. Gus am pròiseas a dhèanamh fèin-ghluasadach, chuir sinn romhainn sgriobt a sgrìobhadh a chruinnicheas fiosrachadh agus a chuir chun an dà sheirbheis.

Ùghdarrachadh

Nuair a bhios sinn a’ dealbhadh nan riatanasan, chuir sinn romhainn fìor luchd-rianachd daonna a chleachdadh airson cead; bidh seo a’ sìmpleachadh mion-sgrùdadh air gnìomhan ma thachras atharrachaidhean mòra gun fhiosta no a dh’aona ghnothach.

Bidh Google APIs a’ cleachdadh protocol OAuth 2.0 airson dearbhadh agus ùghdarras. Gheibhear cùisean cleachdaidh agus tuairisgeulan nas mionaidiche an seo: A’ cleachdadh OAuth 2.0 gus faighinn gu Google APIs.

Thagh mi an sgriobt a thathas a’ cleachdadh airson ùghdarrachadh ann an tagraidhean deasg. Tha roghainn ann cuideachd cunntas seirbheis a chleachdadh, nach fheum gluasadan neo-riatanach bhon neach-cleachdaidh.

Tha an dealbh gu h-ìosal na thuairisgeul sgeamach den t-suidheachadh taghte bho dhuilleag Google.

A’ cruthachadh Google Users bho PowerShell tro API

  1. An toiseach, bidh sinn a’ cur an neach-cleachdaidh gu duilleag dearbhaidh Cunntas Google, a’ sònrachadh paramadairean GET:
    • id tagraidh
    • raointean air a bheil feum aig an tagradh
    • an seòladh chun an tèid an neach-cleachdaidh ath-stiùireadh às deidh crìoch a chur air a’ mhodh-obrach
    • mar a bheir sinn ùrachadh air an tòcan
    • Còd tèarainteachd
    • cruth tar-chuir còd dearbhaidh

  2. Às deidh an cead a chrìochnachadh, thèid an neach-cleachdaidh ath-stiùireadh chun duilleag a chaidh a shònrachadh sa chiad iarrtas, le mearachd no còd ceadachaidh air a dhol seachad le paramadairean GET
  3. Feumaidh an tagradh (sgriobt) na paramadairean sin fhaighinn agus, ma gheibhear an còd, dèan an t-iarrtas a leanas gus comharran fhaighinn
  4. Ma tha an t-iarrtas ceart, tillidh API Google:
    • Comharra ruigsinneachd leis an urrainn dhuinn iarrtasan a dhèanamh
    • Ùine dligheachd a’ chomharra seo
    • Tha feum air tòcan ùrachaidh gus an tòcan Ruigsinneachd ùrachadh.

An toiseach feumaidh tu a dhol gu consol API Google: Teisteanasan - Google API Console, tagh an tagradh a tha thu ag iarraidh agus anns an roinn Teisteanasan cruthaich aithnichear OAuth teachdaiche. An sin (no nas fhaide air adhart, ann an feartan an aithnichear cruthaichte) feumaidh tu na seòlaidhean a shònrachadh dha bheil ath-stiùireadh ceadaichte. Anns a ’chùis againn, bidh iad sin nan grunn inntrigidhean localhost le diofar phuirt (faic gu h-ìosal).

Gus a dhèanamh nas goireasaiche an algairim sgriobt a leughadh, faodaidh tu na ciad cheumannan ann an gnìomh air leth a thaisbeanadh a thilleas Cothrom agus ùrachadh comharran airson an aplacaid:

$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

Shuidhich sinn an ID Cliant agus an Dìomhaireachd Client a fhuaireadh ann an togalaichean aithnichear teachdaiche OAuth, agus tha an dearbhadair còd na shreath de 43 gu 128 caractar a dh’ fheumar a chruthachadh air thuaiream bho charactaran nach deach a ghlèidheadh: [AZ] / [az] / [0-9] /"-"/"." / "_" / "~".

Thèid an còd seo a chraoladh a-rithist an uairsin. Tha e a’ cur às don so-leòntachd anns am b’ urrainn do neach-ionnsaigh freagairt a thilleadh mar ath-sheòladh às deidh cead neach-cleachdaidh.
Faodaidh tu dearbhadair còd a chuir anns an iarrtas làithreach ann an teacsa soilleir (a tha ga dhèanamh gun bhrìgh - chan eil seo freagarrach ach airson siostaman nach eil a’ toirt taic do SHA256), no le bhith a’ cruthachadh hash a’ cleachdadh an algairim SHA256, a dh’ fheumar a chòdachadh ann am BASE64Url (diofar bho Base64 le dà charactar bùird) agus a’ toirt air falbh crìochnachaidhean loidhne nan caractaran: =.

An ath rud, feumaidh sinn tòiseachadh ag èisteachd ri http air an inneal ionadail gus freagairt fhaighinn às deidh cead, a thèid a thilleadh mar ath-sheòladh.

Bithear a’ coileanadh gnìomhan rianachd air frithealaiche sònraichte, chan urrainn dhuinn a bhith a’ cumail a-mach gum bi grunn luchd-rianachd a’ ruith an sgriobt aig an aon àm, agus mar sin taghaidh e air thuaiream port airson an neach-cleachdaidh gnàthach, ach shònraich mi puirt ro-mhìnichte oir feumaidh iad cuideachd a bhith air an cur ris mar earbsa ann an consol API.

access_type = far loidhne a’ ciallachadh gun urrainn don aplacaid tòcan a dh’ fhalbh ùrachadh leis fhèin gun eadar-obrachadh cleachdaiche leis a’ bhrobhsair,
response_type=còd a’ suidheachadh cruth mar a thèid an còd a thilleadh (iomradh air an t-seann dòigh ceadachaidh, nuair a rinn an neach-cleachdaidh leth-bhreac den chòd bhon bhrobhsair a-steach don sgriobt),
farsaingeachd a’ comharrachadh farsaingeachd agus seòrsa ruigsinneachd. Feumaidh iad a bhith air an sgaradh le beàrnan neo %20 (a rèir còdachadh URL). Tha liosta de raointean inntrigidh le seòrsaichean rim faicinn an seo: OAuth 2.0 Scopes airson Google APIs.

Às deidh dha an còd ceadachaidh fhaighinn, tillidh an tagradh teachdaireachd dlùth chun bhrobhsair, stadaidh e ag èisteachd air a’ phort agus cuiridh e iarrtas POST gus an comharra fhaighinn. Bidh sinn a’ nochdadh ann an id agus dìomhaireachd a chaidh a shònrachadh roimhe seo bhon consol API, an seòladh chun an tèid an neach-cleachdaidh ath-stiùireadh agus grant_type a rèir sònrachadh a’ phròtacal.

Mar fhreagairt, gheibh sinn tòcan Ruigsinneachd, an ùine dligheachd ann an diogan, agus tòcan Ath-nuadhachaidh, leis an urrainn dhuinn an tòcan Cothrom ùrachadh.

Feumaidh an tagradh comharran a stòradh ann an àite tèarainte le beatha sgeilp fhada, agus mar sin gus an cuir sinn air ais an ruigsinneachd a fhuaireadh, cha till an tagradh an comharra ùrachaidh. Aig an deireadh, chuir mi a-steach iarrtas airson an tòcan a chùl-ghairm; mura deach an tagradh a chrìochnachadh gu soirbheachail agus nach deach an comharra ùrachaidh a thilleadh, tòisichidh e air a’ mhodh-obrach a-rithist (bha sinn den bheachd gu robh e cunnartach comharran a stòradh gu h-ionadail air an inneal-crìochnachaidh, agus cha do rinn sinn sin ' gun a bhith ag iarraidh rudan iom-fhillte le cryptography no am brabhsair fhosgladh gu tric).

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
}

Mar a mhothaich thu mu thràth, nuair a thathar a’ toirt air ais tòcan, thèid Invoke-WebRequest a chleachdadh. Eu-coltach ri Invoke-RestMethod, cha bhith e a’ tilleadh an dàta a fhuaireadh ann an cruth a ghabhas cleachdadh agus a’ sealltainn inbhe an iarrtais.

An uairsin, tha an sgriobt ag iarraidh ort a ’chiad ainm agus an t-ainm mu dheireadh aig an neach-cleachdaidh a chuir a-steach, a’ gineadh logadh a-steach + post-d.

Iarrtasan

Bidh na h-ath iarrtasan - an toiseach, feumaidh tu dèanamh cinnteach a bheil neach-cleachdaidh leis an aon logadh a-steach ann mu thràth gus co-dhùnadh fhaighinn mu bhith a’ cruthachadh fear ùr no a’ comasachadh an tè gnàthach.

Cho-dhùin mi a h-uile iarrtas a chuir an gnìomh ann an cruth aon ghnìomh le taghadh, a’ cleachdadh suidse:

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'])
      }
    }
  }
}

Anns gach iarrtas, feumaidh tu bann-cinn Ùghdarrachaidh a chuir a-steach anns a bheil an seòrsa tòcan agus an tòcan Ruigsinneachd fhèin. An-dràsta, tha an seòrsa tòcan an-còmhnaidh Neach-giùlain. Air sgàth feumaidh sinn dèanamh cinnteach nach eil an tòcan air tighinn gu crìch agus ùrachadh às deidh uair a thìde bhon mhionaid a chaidh a thoirt a-mach, shònraich mi iarrtas airson gnìomh eile a thilleas comharra ruigsinneachd. Tha an aon phìos còd aig toiseach an sgriobt nuair a gheibh thu a’ chiad tòcan Ruigsinneachd:

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
}

A’ sgrùdadh an logadh a-steach airson a bhith ann:

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
}

Iarraidh an t-iarrtas post-d:$query air an API coimhead airson neach-cleachdaidh leis a’ phost-d sin dìreach, a’ gabhail a-steach ailias. Faodaidh tu cuideachd cairt fiadhaich a chleachdadh: =, :, :{ Ro-ràdh}*.

Gus dàta fhaighinn, cleachd an dòigh iarrtas GET, gus dàta a chuir a-steach (a ’cruthachadh cunntas no a’ cur ball ri buidheann) - POST, gus an dàta a th ’ann ùrachadh - PUT, gus clàr a dhubhadh às (mar eisimpleir, ball bho bhuidheann) - LAOIDH.

Iarraidh an sgriobt cuideachd àireamh fòn (sreang neo-dhearbhaichte) agus a bhith air a ghabhail a-steach ann am buidheann sgaoilidh roinneil. Bidh e a’ co-dhùnadh dè an aonad eagrachaidh a bu chòir a bhith aig an neach-cleachdaidh stèidhichte air an Active Directory OU taghte agus thig e suas le facal-faire:

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"

Agus an uairsin tha e a 'tòiseachadh a' làimhseachadh a 'chunntais:

$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
}

Tha co-chòrdadh coltach ris na gnìomhan airson ùrachadh agus cruthachadh cunntas; chan eil feum air a h-uile raon a bharrachd; anns an roinn le àireamhan fòn, feumaidh tu raon a shònrachadh anns am faod suas ri aon chlàr a bhith ann leis an àireamh agus an seòrsa.

Gus nach fhaigh sinn mearachd nuair a chuireas sinn cleachdaiche ri buidheann, is urrainn dhuinn an-toiseach dearbhadh a bheil e na bhall den chuantal seo mu thràth le bhith a’ faighinn liosta de bhuill a’ chuantail no sgrìobhadh bhon chleachdaiche fhèin.

Cha bhith ceist mu bhallrachd buidhne cleachdaiche sònraichte a-rithist agus cha nochd e ach ballrachd dìreach. Le bhith a’ toirt a-steach neach-cleachdaidh ann am buidheann phàrant aig a bheil buidheann cloinne mu thràth a tha an neach-cleachdaidh na bhall dheth, bidh e soirbheachail.

co-dhùnadh

Chan eil air fhàgail ach am facal-faire airson a’ chunntais ùr a chuir chun neach-cleachdaidh. Bidh sinn a’ dèanamh seo tro SMS, agus a’ cur fiosrachadh coitcheann le stiùireadh agus logadh a-steach gu post-d pearsanta, a chaidh, còmhla ri àireamh fòn, a thoirt seachad leis an roinn fastaidh. Mar roghainn eile, faodaidh tu airgead a shàbhaladh agus am facal-faire agad a chuir gu còmhradh telegram dìomhair, a dh'fhaodar a mheas mar an dàrna factar (bidh MacBooks mar eisgeachd).

Tapadh leibh airson an leughadh gu deireadh. Bidh mi toilichte molaidhean fhaicinn airson stoidhle sgrìobhaidh artaigilean a leasachadh agus tha mi airson gum faigh thu nas lugha de mhearachdan nuair a bhios tu a’ sgrìobhadh sgriobtaichean =)

Liosta de cheanglaichean a dh’ fhaodadh a bhith feumail gu cuspaireil no dìreach freagair ceistean:

Source: www.habr.com

Cuir beachd ann