Úsáideoirí Google á gcruthú ó PowerShell trí API

Dia duit!

Déanfaidh an t-alt seo cur síos ar chur i bhfeidhm idirghníomhaíocht PowerShell le API Google chun úsáideoirí G Suite a ionramháil.

Bainimid úsáid as roinnt seirbhísí inmheánacha agus scamall ar fud na heagraíochta. Den chuid is mó, is chuig Google nó Active Directory a thagann údarú iontu, agus ní féidir linn macasamhail a choinneáil eatarthu; dá réir sin, nuair a fhágann fostaí nua, ní mór duit cuntas a chruthú/a chumasú sa dá chóras seo. Chun an próiseas a uathoibriú, bheartaíomar script a scríobh a bhailíonn faisnéis agus a sheolann chuig an dá sheirbhís í.

Údarú

Agus na ceanglais á dtarraingt suas againn, bheartaíomar fíor-riaraitheoirí daonna a úsáid le haghaidh údarú; simplíonn sé seo an anailís ar ghníomhaíochtaí i gcás athruithe ollmhóra de thaisme nó d’aon ghnó.

Úsáideann APIanna Google prótacal OAuth 2.0 le haghaidh fíordheimhnithe agus údaraithe. Tá cásanna úsáide agus tuairiscí níos mionsonraithe le fáil anseo: Ag baint úsáide as OAuth 2.0 chun rochtain a fháil ar APIanna Google.

Roghnaigh mé an script a úsáidtear le haghaidh údarú i bhfeidhmchláir deisce. Tá rogha ann freisin cuntas seirbhíse a úsáid, rud nach dteastaíonn gluaiseachtaí neamhriachtanach ón úsáideoir.

Tá cur síos scéimreach sa phictiúr thíos ar an gcás roghnaithe ón leathanach Google.

Úsáideoirí Google á gcruthú ó PowerShell trí API

  1. Ar dtús, cuirimid an t-úsáideoir chuig an leathanach fíordheimhnithe Cuntas Google, ag sonrú paraiméadair GET:
    • id iarratais
    • réimsí a dteastaíonn rochtain ón bhfeidhmchlár orthu
    • an seoladh chuig a atreorófar an t-úsáideoir tar éis an nós imeachta a chríochnú
    • an bealach a dhéanfaimid an comhartha a nuashonrú
    • Cód slándála
    • formáid tarchuir cód fíoraithe

  2. Tar éis an t-údarú a chur i gcrích, déanfar an t-úsáideoir a atreorú chuig an leathanach a shonraítear sa chéad iarratas, agus earráid nó cód údaraithe arna rith ag paraiméadair GET
  3. Beidh ar an bhfeidhmchlár (script) na paraiméadair seo a fháil agus, má fhaightear an cód, an t-iarratas seo a leanas a dhéanamh chun comharthaí a fháil
  4. Má tá an t-iarratas ceart, seolfaidh API Google:
    • Comhartha rochtana lenar féidir linn iarratais a dhéanamh
    • Tréimhse bhailíochta an chomhartha seo
    • Tá comhartha athnuachana ag teastáil chun an comhartha Rochtana a athnuachan.

Ar dtús is gá duit dul chuig consól Google API: Dintiúir - Google API Console, roghnaigh an t-iarratas atá ag teastáil agus sa roinn Dintiúir cruthaigh aitheantóir OAuth cliant. Ann (nó níos déanaí, in airíonna an aitheantóra cruthaithe) ní mór duit na seoltaí a bhfuil atreorú ceadaithe chucu a shonrú. Inár gcás, beidh siad seo ina roinnt iontrálacha localhost le calafoirt éagsúla (féach thíos).

Chun é a dhéanamh níos áisiúla an t-algartam scripte a léamh, is féidir leat na chéad chéimeanna a thaispeáint i bhfeidhm ar leith a thabharfaidh rochtain ar ais agus comharthaí don fheidhmchlár a athnuachan:

$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

Shocraigh muid an ID Cliant agus Rúnda an Chliaint a fhaightear in airíonna aitheantóra an chliaint OAuth, agus is é an fíoraitheoir cód teaghrán de 43 go 128 carachtar a chaithfear a ghiniúint go randamach ó charachtair neamhchoimeádta: [AZ] / [az] / [0-9] /"-"/"." / "_" / "~".

Tarchuirfear an cód seo arís ansin. Cuireann sé deireadh leis an leochaileacht ina bhféadfadh ionsaitheoir freagairt a cuireadh ar ais mar atreorú tar éis údarú úsáideora a thascradh.
Is féidir leat fíoraitheoir cód a sheoladh san iarratas reatha i dtéacs soiléir (rud a fhágann nach bhfuil brí leis - níl sé seo oiriúnach ach do chórais nach dtacaíonn SHA256 leo), nó trí hash a chruthú ag baint úsáide as an algartam SHA256, nach mór a ionchódú i BASE64Url (difriúil ó Base64 le dhá charachtair tábla) agus na deirí líne carachtair a bhaint: =.

Ansin, ní mór dúinn tosú ag éisteacht le http ar an meaisín áitiúil chun freagra a fháil tar éis údarú, a sheolfar ar ais mar atreorú.

Déantar tascanna riaracháin ar fhreastalaí speisialta, ní féidir linn a chur as an áireamh go mbeidh roinnt riarthóirí ag rith an script ag an am céanna, mar sin roghnóidh sé calafort don úsáideoir reatha go randamach, ach shonraigh mé poirt réamhshainithe toisc ní mór iad a chur leis freisin mar iontaofa sa chonsól API.

access_type=as líne Ciallaíonn sé seo gur féidir leis an bhfeidhmchlár comhartha imithe in éag a nuashonrú leis féin gan idirghníomhú úsáideora leis an mbrabhsálaí,
response_type=cód socraíonn sé an fhormáid ina dtabharfar an cód ar ais (tagairt don sean-mhodh údaraithe, nuair a chóipeáil an t-úsáideoir an cód ón mbrabhsálaí isteach sa script),
raon feidhme a léiríonn an raon feidhme agus an cineál rochtana. Caithfidh siad a bheith scartha le spásanna nó % 20 (de réir Ionchódú URL). Tá liosta de na limistéir rochtana le cineálacha le feiceáil anseo: OAuth 2.0 Scóipeanna le haghaidh APIanna Google.

Tar éis an cód údaraithe a fháil, cuirfidh an t-iarratas teachtaireacht gar ar ais chuig an mbrabhsálaí, stopfaidh sé ag éisteacht ar an gcalafort agus seolfaidh sé iarratas POST chun an comhartha a fháil. Léirímid ann an t-aitheantas agus an rún a shonraítear roimhe seo ón API consól, an seoladh a ndéanfar an t-úsáideoir a atreorú chuige agus deontas_type de réir sonraíocht an phrótacail.

Mar fhreagra air sin, gheobhaidh muid comhartha Rochtana, a thréimhse bailíochta i soicindí, agus comhartha Athnuachana, lena bhféadfaimid an comhartha Rochtana a nuashonrú.

Ní mór don fheidhmchlár comharthaí a stóráil in áit shlán le seilfré fada, mar sin go dtí go gcúlghairfimid an rochtain a fuarthas, ní thabharfar an comhartha athnuachana ar ais chuig an iarratas. Ag an deireadh, chuir mé iarratas leis an chomhartha a chúlghairm; murar críochnaíodh an t-iarratas go rathúil agus nár cuireadh an comhartha athnuachana ar ais, cuirfear tús leis an nós imeachta arís (mheasamar go raibh sé neamhshábháilte comharthaí a stóráil go háitiúil ar an teirminéal, agus rinneamar 'gan iarraidh rudaí casta a dhéanamh le cripteagrafaíocht nó an brabhsálaí a oscailt go minic).

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 thug tú faoi deara cheana féin, agus chomhartha á chúlghairm, úsáidtear Invoke-WebRequest. Murab ionann agus Invoke-RestMethod, ní chuireann sé na sonraí a fuarthas ar ais i bhformáid inúsáidte agus taispeánann sé stádas an iarratais.

Ansin, iarrann an script ort céadainm agus sloinne an úsáideora a chur isteach, ag giniúint logáil isteach + ríomhphost.

Iarratais

Is iad na chéad iarratais eile - ar an gcéad dul síos, ní mór duit a sheiceáil an bhfuil úsáideoir leis an logáil isteach céanna ann cheana féin chun cinneadh a fháil maidir le ceann nua a chruthú nó an ceann reatha a chumasú.

Chinn mé gach iarratas a chur i bhfeidhm i bhformáid feidhm amháin le rogha, ag baint úsáide as lasc:

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 ngach iarratas, ní mór duit ceanntásc Údaraithe a sheoladh ina mbeidh an cineál dearbháin agus an comhartha Rochtana féin. Faoi láthair, tá an cineál chomhartha i gcónaí Iompróir. Mar ní mór dúinn a sheiceáil nach bhfuil an comhartha imithe in éag agus é a nuashonrú tar éis uair an chloig ón nóiméad a eisíodh é, shonraigh mé iarratas ar fheidhm eile a thugann comhartha Rochtana ar ais. Tá an píosa céanna cód ag tús na scripte nuair a fhaightear an chéad chomhartha Rochtana:

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
}

Ag seiceáil an bhfuil logáil isteach 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
}

Iarrfaidh an t-iarratas ríomhphoist:$query ar an API úsáideoir a lorg leis an ríomhphost sin go díreach, lena n-áirítear ailiasanna. Is féidir leat saoróg a úsáid freisin: =, :, :{RÉAMHRÁ}*.

Chun sonraí a fháil, bain úsáid as modh iarratais GET, chun sonraí a chur isteach (cuntas a chruthú nó ball a chur le grúpa) - POST, chun sonraí atá ann cheana a nuashonrú - PUT, chun taifead a scriosadh (mar shampla, ball ó ghrúpa) - Scrios.

Iarrfaidh an script freisin uimhir theileafóin (teaghrán neamhbhailíochtaithe) agus le cur san áireamh i ngrúpa dáileacháin réigiúnach. Socraíonn sé cén aonad eagraíochtúil ar cheart a bheith ag an úsáideoir bunaithe ar an Eolaire Gníomhach OU roghnaithe agus tagann pasfhocal:

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 ansin tosaíonn sé ag ionramháil an chuntais:

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

Tá comhréir comhchosúil ag na feidhmeanna chun cuntas a nuashonrú agus a chruthú; níl gach réimse breise ag teastáil; sa rannán le huimhreacha gutháin, ní mór duit eagar a shonrú a bhféadfaidh suas le taifead amháin a bheith ann leis an uimhir agus a chineál.

Chun nach bhfaighimid earráid agus úsáideoir á chur le grúpa, is féidir linn a sheiceáil ar dtús an bhfuil sé ina bhall den ghrúpa seo cheana féin trí liosta de bhaill an ghrúpa nó comhdhéanamh a fháil ón úsáideoir féin.

Ní bheidh ceist a chur faoi bhallraíocht ghrúpa úsáideora ar leith agus ní thaispeánfar ach ballraíocht dhíreach. Má chuirtear úsáideoir san áireamh i ngrúpa tuismitheora a bhfuil grúpa leanaí acu cheana féin a bhfuil an t-úsáideoir ina bhall de, éireoidh leis.

Conclúid

Níl fágtha ach an focal faire don chuntas nua a sheoladh chuig an úsáideoir. Déanaimid é seo trí SMS, agus cuirimid eolas ginearálta le treoracha agus logáil isteach chuig ríomhphost pearsanta, a chuir an rannóg earcaíochta, mar aon le huimhir theileafóin, ar fáil. Mar mhalairt air sin, is féidir leat airgead a shábháil agus do phasfhocal a sheoladh chuig comhrá teileagram rúnda, ar féidir a mheas freisin mar an dara fachtóir (Beidh MacBooks eisceacht).

Go raibh maith agat as léamh go dtí an deireadh. Beidh áthas orm moltaí a fheiceáil chun stíl scríbhneoireachta alt a fheabhsú agus ba mhaith liom níos lú earráidí a ghlacadh agus scripteanna á scríobh =)

Liosta de naisc a d’fhéadfadh a bheith úsáideach go téamach nó a d’fhéadfadh ceisteanna a fhreagairt:

Foinse: will.com

Add a comment