Sawubona!
Lesi sihloko sizochaza ukusetshenziswa kokusebenzelana kwe-PowerShell ne-Google API ukuze kusetshenziswe abasebenzisi be-G Suite.
Sisebenzisa amasevisi ambalwa angaphakathi nawefu enhlanganweni yonkana. Ngokwengxenye enkulu, ukugunyazwa kuzo kwehla ku-Google noma ku-Active Directory, lapho esingakwazi khona ukugcina ikhophi; ngakho-ke, lapho isisebenzi esisha sihamba, udinga ukudala/ukunika amandla i-akhawunti kulawa masistimu amabili. Ukuze senze inqubo ngokuzenzakalelayo, sinqume ukubhala iskripthi esiqoqa ulwazi futhi siluthumele kuzo zombili izinsiza.
Ngena
Lapho sidweba izidingo, sinqume ukusebenzisa abalawuli abangabantu bangempela ukuze bagunyazwe; lokhu kwenza kube lula ukuhlaziya izenzo uma kwenzeka izinguquko ezinkulu zengozi noma zamabomu.
I-Google APIs isebenzisa iphrothokholi ye-OAuth 2.0 ukuze kuqinisekiswe nokugunyazwa. Izimo zokusebenzisa nezincazelo ezinemininingwane eyengeziwe zingatholakala lapha:
Ngikhethe umbhalo osetshenziselwa ukugunyazwa kuzinhlelo zokusebenza zedeskithophu. Kukhona futhi inketho yokusebenzisa i-akhawunti yesevisi, engadingi ukunyakaza okungadingekile kumsebenzisi.
Isithombe esingezansi siyincazelo yohlelo lwesimo esikhethiwe ekhasini le-Google.
- Okokuqala, sithumela umsebenzisi ekhasini lokuqinisekisa I-akhawunti ye-Google, sicacisa izinhlaka ze-GET:
- i-id yohlelo lokusebenza
- izindawo lapho uhlelo lokusebenza ludinga ukufinyelela kuzo
- ikheli lapho umsebenzisi ezoqondiswa kabusha khona ngemva kokuqeda inqubo
- indlela esizobuyekeza ngayo ithokheni
- Ikhodi yokuphepha
- ifomethi yokudlulisa ikhodi yokuqinisekisa
- Ngemva kokuqedwa kokugunyazwa, umsebenzisi uzoqondiswa kabusha ekhasini elishiwo esicelweni sokuqala, ngephutha noma ikhodi yokugunyaza ephasiswe amapharamitha we-GET.
- Isicelo (isikripthi) sizodinga ukuthola le mingcele futhi, uma ithole ikhodi, yenza isicelo esilandelayo ukuze uthole amathokheni
- Uma isicelo silungile, i-Google API iyabuya:
- Ithokheni yokufinyelela esingenza ngayo izicelo
- Isikhathi sokuqinisekisa sale tokheni
- Ithokheni yokuvuselela iyadingeka ukuvuselela ithokheni yokufinyelela.
Okokuqala udinga ukuya kukhonsoli ye-Google API:
Ukwenza kube lula ukufunda i-algorithm yeskripthi, ungabonisa izinyathelo zokuqala kumsebenzi ohlukile ozobuyisela Ukufinyelela futhi uvuselele amathokheni ohlelo lokusebenza:
$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
Setha i-ID yeklayenti kanye nemfihlo yeklayenti etholwe kuzici ze-OAuth zokuhlonza iklayenti, futhi isiqinisekisi sekhodi siwuchungechunge lwezinhlamvu ezingu-43 kuya kwezingu-128 okufanele zenziwe ngokungahleliwe kusuka ezinhlamvini ezingagodliwe: [AZ] / [az] / [0-9 ] / "-" / "." / "_" / "~".
Le khodi izobe idluliselwa futhi. Isusa ukuba sengozini lapho umhlaseli engakwazi ukuvimba impendulo ebuyiswa njengokuqondisa kabusha ngemva kokugunyazwa komsebenzisi.
Ungathumela okokuqinisekisa ikhodi esicelweni samanje ngombhalo ocacile (okwenza kungasho lutho - lokhu kulungele kuphela amasistimu angasekeli i-SHA256), noma ngokudala i-hashi usebenzisa i-algorithm ye-SHA256, okumele ifakwe ikhodi ku-BASE64Url (ehlukile kusuka ku-Base64 ngezinhlamvu ezimbili zetafula) nokukhipha iziphetho zomugqa womlingiswa: =.
Okulandelayo, sidinga ukuqala ukulalela i-http emshinini wendawo ukuze sithole impendulo ngemva kokugunyazwa, ezobuyiswa njengokuqondisa kabusha.
Imisebenzi yokuphatha yenziwa kuseva ekhethekile, asikwazi ukukhipha ukuthi kungenzeka ukuthi abalawuli abambalwa basebenzise iskripthi ngesikhathi esisodwa, ngakho-ke izokhetha ngokungahleliwe ichweba lomsebenzisi wamanje, kodwa ngibalule izimbobo ezichazwe ngaphambilini ngoba kumele futhi zengezwe njengokuthenjwa kukhonsoli ye-API.
access_type=okungaxhunyiwe ku-inthanethi kusho ukuthi uhlelo lokusebenza lungabuyekeza ithokheni ephelelwe yisikhathi ngokwalo ngaphandle kokuxhumana komsebenzisi nesiphequluli,
response_type=ikhodi isetha ifomethi yokuthi ikhodi izobuyiswa kanjani (ireferensi yendlela yokugunyaza endala, lapho umsebenzisi ekopishe ikhodi esuka esipheqululini eya kusikripthi),
ububanzi ikhombisa ububanzi kanye nohlobo lokufinyelela. Kumelwe zihlukaniswe izikhala noma %20 (ngokuvumelana ne-URL Encoding). Uhlu lwezindawo zokufinyelela ezinezinhlobo zingabonakala lapha:
Ngemva kokuthola ikhodi yokugunyazwa, uhlelo lokusebenza luzobuyisela umlayezo oseduze kusiphequluli, liyeke ukulalela echwebeni bese lithumela isicelo se-POST ukuze uthole ithokheni. Sikhombisa kuyo i-id eshiwo ngaphambilini kanye nemfihlo evela ku-console API, ikheli lapho umsebenzisi ezoqondiswa kabusha futhi anike_athayiphe ngokuvumelana nokucaciswa kwephrothokholi.
Ngokuphendula, sizothola ithokheni Yokufinyelela, isikhathi sayo sokufaneleka ngemizuzwana, kanye nethokheni Yokuvuselela, esingabuyekeza ngayo ithokheni Yokufinyelela.
Uhlelo lokusebenza kufanele lugcine amathokheni endaweni evikelekile eneshalofu ende, ngakho-ke kuze kube yilapho sihoxisa ukufinyelela okutholiwe, isicelo ngeke sibuyisele ithokheni yokuvuselela. Ekugcineni, ngengeze isicelo sokuhoxisa ithokheni; uma isicelo singaqedwanga ngempumelelo futhi ithokheni yokuvuselela ingabuyiswanga, izoqala inqubo futhi (sikubheke njengokungaphephile ukugcina amathokheni endaweni endaweni, futhi asikwenzi lokho. 'ngifuna ukwenza izinto zibe nzima nge-cryptography noma ukuvula isiphequluli njalo).
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
}
Njengoba usubonile, lapho uhoxisa ithokheni, kusetshenziswa i-Invoke-WebRequest. Ngokungafani ne-Invoke-RestMethod, ayibuyiseli idatha etholiwe ngefomethi esebenzisekayo futhi ibonisa isimo sesicelo.
Okulandelayo, umbhalo ukucela ukuthi ufake igama nesibongo somsebenzisi, ukhiqize ukungena + kwe-imeyili.
Izicelo
Izicelo ezilandelayo zizoba - okokuqala, udinga ukuhlola ukuthi ngabe umsebenzisi onokungena okufanayo usevele ekhona yini ukuze uthole isinqumo sokudala okusha noma ukunika amandla esamanje.
Nginqume ukusebenzisa zonke izicelo ngefomethi yomsebenzi owodwa ngokukhetha, ngisebenzisa iswishi:
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'])
}
}
}
}
Esicelweni ngasinye, udinga ukuthumela unhlokweni Wokugunyazwa oqukethe uhlobo lwethokheni kanye nethokheni yokufinyelela ngokwayo. Njengamanje, uhlobo lwethokheni luhlala luyi-Bearer. Ngoba sidinga ukuhlola ukuthi ithokheni aliphelelwanga isikhathi futhi silibuyekeze ngemva kwehora kusukela ngesikhathi likhishwa ngalo, ngibalule isicelo somunye umsebenzi obuyisela ithokheni Yokufinyelela. Ingxenye yekhodi efanayo isekuqaleni kweskripthi lapho ithola ithokheni Yokufinyelela yokuqala:
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
}
Ihlola ukungena ngemvume ukuthi kukhona:
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
}
I-imeyili:isicelo se-$query sizocela i-API ukuthi ibheke umsebenzisi onaleyo imeyili ngqo, okuhlanganisa neziteketiso. Ungasebenzisa futhi i-wildcard: =, :, :{PREFIX}*.
Ukuze uthole idatha, sebenzisa indlela yesicelo se-GET, ukufaka idatha (ukudala i-akhawunti noma ukwengeza ilungu eqenjini) - THUMELA, ukuze ubuyekeze idatha ekhona - PUT, ukususa irekhodi (ngokwesibonelo, ilungu eqenjini) - SUSA.
Umbhalo uzophinda ucele inombolo yocingo (uchungechunge olungagunyaziwe) kanye nokufakwa eqenjini lokusabalalisa lesifunda. Inquma ukuthi iyiphi iyunithi yenhlangano umsebenzisi okufanele abe nayo ngokusekelwe ohlwini olukhethiwe lwe-Active Directory OU futhi iqhamuke nephasiwedi:
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"
Bese eqala ukukhohlisa i-akhawunti:
$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
}
Imisebenzi yokubuyekeza nokudala i-akhawunti ine-syntax efanayo; akuzona zonke izinkambu ezengeziwe ezidingekayo; esigabeni esinezinombolo zocingo, udinga ukucacisa uhlu olungaqukatha irekhodi elilodwa elinenombolo kanye nohlobo lwayo.
Ukuze singatholi iphutha lapho wengeza umsebenzisi eqenjini, singaqala sihlole ukuthi ingabe useyilungu laleli qembu ngokuthola uhlu lwamalungu eqembu noma ukwakheka okuvela kumsebenzisi ngokwakhe.
Ukubuza ngobulungu beqembu bomsebenzisi othile ngeke kuphindeke futhi kuzobonisa ubulungu obuqondile kuphela. Ukufaka umsebenzisi eqenjini lomzali osevele lineqembu lengane umsebenzisi ayilungu lalo kuzophumelela.
isiphetho
Okusele nje ukuthumela umsebenzisi iphasiwedi ye-akhawunti entsha. Senza lokhu nge-SMS, futhi sithumela ulwazi olujwayelekile ngeziyalezo kanye nokungena ngemvume ku-imeyili yomuntu siqu, leyo, kanye nenombolo yocingo, eyanikezwa umnyango wokuqasha. Ngenye indlela, ungonga imali futhi uthumele iphasiwedi yakho engxoxweni eyimfihlo yocingo, engabuye ibhekwe njengento yesibili (ama-MacBooks azoba okuhlukile).
Ngiyabonga ngokufunda kuze kube sekugcineni. Ngizojabula ukubona iziphakamiso zokuthuthukisa isitayela sokubhala izindatshana futhi ngifise ukuthi ubambe amaphutha ambalwa lapho ubhala imibhalo =)
Uhlu lwezixhumanisi ezingase zibe usizo ngokwetimu noma ziphendule imibuzo nje:
I-OAuth 2.0 yezinhlelo zokusebenza zeselula nezedeskithophu Ukusebenzisa i-OAuth 2.0 yezinhlelo zokusebenza zeseva yewebhu Ukhiye Wobufakazi Bokushintshaniswa Kwekhodi ngamaKlayenti Omphakathi we-OAuth Khiqiza Izinhlamvu Ezingahleliwe nge-PowerShell Ithebula le-ASCII Nencazelo I-PowerShell: Ukuthola inani le-hashi leyunithi yezinhlamvu Encode/Decode Base64Url I-Base64 encoding vs Base64url encoding I-Invoke-RestMethod ku-PowerShell 5.1 Ayitholi ithokheni yokuvuselela nakuba i-access_type ingaxhunyiwe ku-inthanethi ku-step1 Mayelana Nabasebenzisi Bokuqhathanisa I-Directory API: Ama-Akhawunti Womsebenzisi Sesha abasebenzisi Directory API: Amaqembu Iphutha Lokuphatha le-Invoke-RestMethod - Powershell
Source: www.habr.com