áá±áá¹áá¬ááŸáá·áºááŒá¬ážááá¯ááºáá«á!
G Suite á¡áá¯á¶ážááŒá¯áá°áá»á¬ážááᯠááá¯ááºááœááºááẠGoogle API ááŸáá·áº PowerShell á¡ááŒááºá¡ááŸááºáá¯á¶á·ááŒááºááŸá¯ááᯠá€áá±á¬ááºážáá«ážááœáẠáá±á¬áºááŒáá«áááºá
áá»áœááºá¯ááºááá¯á·ááẠá¡ááœá²á·á¡á
ááºážá¡ááŸá¶á·ááŸá áá¬áááœááºážááŸáá·áº cloud áááºáá±á¬ááºááŸá¯áá»á¬ážá
áœá¬ááᯠá¡áá¯á¶ážááŒá¯áá«áááºá á¡áá»á¬ážá
á¯á¡ááœááºá áááºážááá¯á·ááœáẠááœáá·áºááŒá¯áá»ááºááẠáá¯á¶áá°ááᯠáááááºážááááºážááá¯ááºááá·áºááŒá¬ážááœáẠGoogle ááá¯á·ááá¯áẠActive Directory áᶠáááºážáááºáá¬áááºá ááá¯á·ááŒá±á¬áá·áº áááºáááºážá¡áá
áºá០ááœááºááœá¬ážááá·áºá¡áá«á áááºááẠá€á
áá
áºááŸá
áºáá¯ááœáẠá¡áá±á¬áá·áºáá
áºáᯠáááºáá®áž/ááœáá·áºááẠááá¯á¡ááºáá«áááºá áá¯ááºáááºážá
ááºááᯠá¡ááá¯á¡áá»á±á¬ááºáá¯ááºáá±á¬ááºááẠáá»áœááºá¯ááºááá¯á·ááẠá¡áá»ááºá¡áááºáá»á¬ážááᯠá
á¯áá±á¬ááºážááŒá®áž áááºáá±á¬ááºááŸá¯ááŸá
áºáá¯áá¯á¶ážáᶠáá±ážááá¯á·ááá·áº áá¬ááºááœáŸááºážáá
áºáá¯ááᯠáá±ážáá¬ážááẠáá¯á¶ážááŒááºáá²á·áááºá
á¡ááœáá·áºá¡á¬áá¬áá±ážááŒááºáž
ááá¯á¡ááºáá»ááºáá»á¬ážááᯠáá±ážááœá²ááá·áºá¡áá«á ááœáá·áºááŒá¯áá»ááºá¡ááœáẠá á áºááŸááºáá±á¬ áá°áá¬ážá á®áá¶ááá·áºááœá²áá°áá»á¬ážááᯠá¡áá¯á¶ážááŒá¯ááẠáá¯á¶ážááŒááºáá²á·áááºá áááºážááẠááá±á¬áºáá ááá¯á·ááá¯áẠáááºááœááºáá»ááºááŸáááŸá ááŒá®ážáá¬ážáá±á¬ á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááŒá áºáá±á«áºááá·áºá¡áá« áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááᯠááœá²ááŒááºážá áááºááŒá¬ááŒááºážá¡á¬áž ááá¯ážááŸááºážá á±áááºá
Google API áá»á¬ážááẠá
á
áºááŸááºááŒá±á¬ááºážááŸáá·áº ááœáá·áºááŒá¯áá»ááºá¡ááœáẠOAuth 2.0 áááá¯ááá¯áá±á¬ááᯠá¡áá¯á¶ážááŒá¯áááºá á¡áá¯á¶ážááŒá¯ááŸá¯ááá
á¹á
áá»á¬ážááŸáá·áº á¡áá±ážá
áááºáá±á¬áºááŒáá»ááºáá»á¬ážááᯠá€áá±áá¬ááœáẠááœá±á·ááá¯ááºáááº-
desktop á¡ááá®áá±ážááŸááºážáá»á¬ážááœáẠááœáá·áºááŒá¯áá»ááºá¡ááœááºá¡áá¯á¶ážááŒá¯áá±á¬ script ááᯠáá«ááœá±ážáá»ááºáá²á·áááºá á¡áá¯á¶ážááŒá¯áá°áá¶ááŸáááá¯á¡ááºáá±á¬ááŸá¯ááºááŸá¬ážááŸá¯áá»á¬ážáááá¯á¡ááºáá±á¬áááºáá±á¬ááºááŸá¯á¡áá±á¬áá·áºááá¯á¡áá¯á¶ážááŒá¯áááºááœá±ážáá»ááºááœáá·áºáááºážááŸááááºá
á¡á±á¬ááºáá±á¬áºááŒáá«áá¯á¶ááẠGoogle á á¬áá»ááºááŸá¬á០ááœá±ážáá»ááºáá¬ážáá±á¬ áá¬ááºáááºážáá¯á¶á á¶á ááá¯ááºáá±á¬áºáá¯á¶ááŒá áºáááºá
- ááááŠážá
áœá¬á áá»áœááºá¯ááºááá¯á·ááẠá¡áá¯á¶ážááŒá¯áá°ááᯠGET áá±á¬ááºáá»á¬ážááᯠáááºááŸááºáá±ážááŒááºážááŒáá·áº Google á¡áá±á¬áá·áº á¡áá±á¬ááºá¡áá¬ážá
áá
á
áºááŒááºážá
á¬áá»ááºááŸá¬ááá¯á· áá±ážááá¯á·áááº-
- áá»áŸá±á¬ááºááœáŸá¬ ID
- á¡ááá®áá±ážááŸááºážááá¯á·áááºáá±á¬ááºááẠááá¯á¡ááºááá·áºáá±áá¬áá»á¬áž
- áá¯ááºáá¯á¶ážáá¯ááºáááºážááᯠááŒá®ážááŒá±á¬ááºááŒá®ážáá±á¬áẠá¡áá¯á¶ážááŒá¯áá°ááᯠááŒááºááœáŸááºážááá·áºááááºá á¬
- ááá¯áááºááᯠá¡ááºááááºáá¯ááºáááºáž
- áá¯á¶ááŒá¯á¶áá±ážáá¯ááºáá¶áá«ááº
- á¡áááºááŒá¯áá¯áẠáá¯ááºááœáŸáá·áºááŸá¯áá¯á¶á á¶
- ááœáá·áºááŒá¯áá»ááºááŒá®ážá á®ážááŒá®ážáá±á¬ááºá á¡áá¯á¶ážááŒá¯áá°á¡á¬áž ááááá±á¬ááºážááá¯áá»ááºááœáẠáááºááŸááºáá¬ážááá·áº á á¬áá»ááºááŸá¬ááá¯á· á¡ááŸá¬ážá¡ááœááºážáá áºáᯠááá¯á·ááá¯áẠááœáá·áºááŒá¯áá»ááºáá¯ááºááᯠGET áá±á¬ááºáá»á¬ážááŸáá áºááá·áº áá»á±á¬áºááŒááºááœá¬ážáááºááŒá áºáááºá
- á¡ááá®áá±ážááŸááºáž (script) ááẠá¡ááá¯áá« ááá·áºáááºáá»ááºáá»á¬ážááᯠáááºáá¶áááŸáááẠááá¯á¡ááºáááºááŒá áºááŒá®ážá áá¯ááºááᯠáááºáá¶áááŸááá«á ááá¯áááºáá»á¬ážááá°ááẠá¡á±á¬ááºáá«áá±á¬ááºážááá¯áá»ááºááᯠááŒá¯áá¯ááºáá«á
- áá±á¬ááºážááá¯áá»ááºááŸááºáááºáá«áá Google API á០ááŒááºááá¯á·áááº-
- áá»áœááºá¯ááºááá¯á· áá±á¬ááºážááá¯ááŸá¯áá»á¬áž ááŒá¯áá¯ááºááá¯ááºááá·áº ááá¯áááºááᯠá¡áá¯á¶ážááŒá¯ááœáá·áº
- á€ááá¯áááºáááá¬ážáááºáá¬á
- Access token ááᯠááŒááºáááºá áááºááẠááá¯áááºááᯠááŒááºáááºá áááºááẠááá¯á¡ááºáááºá
ááááŠážá
áœá¬ áááºááẠGoogle API ááœááºááá¯ážááºááá¯á· ááœá¬ážáááºááá¯á¡ááºáááº-
script algorithm ááá¯áááºááẠááá¯ááá¯á¡áááºááŒá±á á±áááºá áááºááẠá¡ááá®áá±ážááŸááºážá¡ááœáẠAccess and refresh tokens ááᯠááŒááºáá±ážááá·áº áá®ážááŒá¬ážáá¯ááºáá±á¬ááºááŸá¯áá áºáá¯ááœáẠáááá¡ááá·áºáá»á¬ážááᯠáááºááŒáááá¯ááºáááº-
$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
áá»áœááºá¯ááºááá¯á·ááẠOAuth áááá¯ááºážááá·áºáááºááŸááºááŸá¯ááá¯ááºáᬠáá¯ááºááá¹áááá»á¬ážááœááºáááŸááá±á¬ áá±á¬ááºááẠID ááŸáá·áº áá±á¬ááºáááºáá»áŸáá¯á·ááŸááºáá»ááºááᯠáááºááŸááºáá²á·ááŒá®ážá áá¯ááºá¡áááºááŒá¯áá°ááẠáá®ážááá·áºááá¬ážáá±á¬á¡áá¹ááá¬áá»á¬ážá០áá»áááºážáá¯ááºáá±ážááááºááŒá áºááŒá®áž á á¬áá¯á¶ážáá± 43 á០128 áá¯á¶ážáá«ááŸááááº- [AZ] / [az] / [0-9] /"-"/"á /"_"/"~"á
ááá¯á·áá±á¬áẠá€áá¯ááºááᯠáááºáá¶áá±ážááá¯á·áá«áááºá áááºážááẠá¡áá¯á¶ážááŒá¯áá°ááœáá·áºááŒá¯áá»ááºááŒá®ážáá±á¬áẠááŒááºáááºáááºážááœáŸááºááŸá¯á¡ááŒá
Ạááá¯ááºááá¯ááºáá°á០ááŒááºáá¬áá±á¬áá¯á¶á·ááŒááºááŸá¯ááᯠááŒá¬ážááŒááºááá·áºáá¬ážááá¯ááºááá·áº á¡á¬ážáááºážáá»ááºááᯠáááºááŸá¬ážáá±ážáááºá
áááºááẠáááºááŸááá±á¬ááºážááá¯ááŸá¯ááœáẠáá¯ááºá¡áááºááŒá¯áá°á¡á¬áž ááŸááºážáááºážáá±á¬á
á¬áá¬ážááŒáá·áº áá±ážááá¯á·ááá¯ááºááẠ(áááºážááẠá¡áááá¹áá«ááºáá²á·á
á±ááẠ- áááºážááẠSHA256 ááá¯ááá¶á·ááá¯ážáá±á¬á
áá
áºáá»á¬ážá¡ááœááºáá¬ááá·áºáá»á±á¬áºáááº) ááá¯á·ááá¯áẠBASE256Url ááœáẠáá¯ááºáá¯ááºáá¬ážááááºááŒá
áºááŒá®áž BASE64Url (ááœá²ááŒá¬ážááẠBase64 á០ááá¬ážá¡áá¹ááᬠááŸá
áºáá¯ááŒáá·áº) ááŸáá·áº áá¬ááºáá±á¬ááºáá»ááºážá¡áá¯á¶ážáááºáá»á¬ážááᯠáááºááŸá¬ážááŒááºáž- =á
áááºáááºáá ááœáá·áºááŒá¯áá»ááºááŒá®ážáá±á¬áẠáá¯á¶á·ááŒááºáá»ááºáá áºáá¯áááŸááááºá¡ááœááºá ááŒááºáááºáááºážááœáŸááºááŸá¯áá áºáá¯á¡ááŒá ẠááŒááºáá±ážááá·áº áá¯á¶á·ááŒááºáá»ááºááá¯áááŸááááºá¡ááœáẠááŒááºááœááºážá ááºááœáẠhttp ááᯠá áááºáá¬ážáá±á¬ááºááẠááá¯á¡ááºáááºá
á á®áá¶ááá·áºááœá²áá±ážááá¯ááºáá¬áá¬áááºáá»á¬ážááᯠá¡áá°ážáá¬áá¬áá áºáá¯áá±á«áºááœáẠáá¯ááºáá±á¬ááºáááºá á á®áá¶ááá·áºááœá²áá°á¡áá»á¬ážá¡ááŒá¬ážááẠáá áºáá»áááºáááºážááœáẠscript ááᯠrun ááá·áºááŒá áºááá¯ááºááŒá±ááᯠáá»áœááºá¯ááºááá¯á·áááŒááºážááá¯ááºáá±á¬ááŒá±á¬áá·áº áááºááŸáá¡áá¯á¶ážááŒá¯áá°á¡ááœáẠport áá áºáá¯ááᯠáá»áááºážááœá±ážáá»ááºáá±ážáááºááŒá áºáá±á¬áºáááºáž ááŒáá¯áááºáááºááŸááºáá¬ážáá±á¬ port áá»á¬ážááᯠáá»áœááºá¯ááºáááºááŸááºáá¬ážáá±á¬ááŒá±á¬áá·áºá áááºážááá¯á·ááᯠAPI ááœááºááá¯ážááºááœáẠáá¯á¶ááŒááºáá¬ážááá·áºá¡ááá¯ááºáž áá±á«ááºážááá·áºááá«áááºá
access_type=á¡á±á¬á·ááºááá¯ááºáž ááá¯ááá¯áááºááŸá¬ á¡ááá®áá±ážááŸááºážááẠááá±á¬ááºáá¬ááŸáá·áº á¡áá¯á¶ážááŒá¯áá° á¡ááŒááºá¡ááŸááºáááºááœááºááŸá¯áááŸááá² áááºáááºážáá¯ááºáá¯á¶ážááœá¬ážáá±á¬ ááá¯áááºáá
áºáá¯ááᯠáááºážáááá¯ááºááá¯áẠupdate áá¯ááºááá¯ááºáááºá
response_type=áá¯áẠáá¯ááºááᯠáááºááá¯á·ááŒááºáá±ážáááºááᯠáá¯á¶á
á¶áááºááŸááºááẠ(á¡áá¯á¶ážááŒá¯áá°ááẠááá±á¬ááºáá¬á០áá¯ááºááᯠscript áá²ááá¯á· áá°ážáá°áá±á¬á¡áá«á ááœáá·áºááŒá¯áá»ááºáááºážáááºážáá±á¬ááºážááᯠáááºááœáŸááºážáááº)á
áááºááẠá¡ááá¯ááºážá¡áá¬ááŸáá·áº áááºáá±á¬ááºááŸá¯ á¡áá»áá¯ážá¡á
á¬ážááᯠááœáŸááºááŒáááºá áááºážááá¯á·ááᯠáá±áá¬ááœááºáá»á¬áž ááá¯á·ááá¯áẠ%20 (URL áá¯ááºááœááºážááŒááºážá¡á) ááŒá¬ážáá¬ážááá«áááºá á¡áá»áá¯ážá¡á
á¬ážáá»á¬ážáá«ááŸááá±á¬ á¡áá¯á¶ážááŒá¯ááœáá·áºá§áááá¬áá»á¬ážá
á¬áááºážááᯠá€áá±áá¬ááœáẠááŒáá·áºááŸá¯ááá¯ááºáááº-
ááœáá·áºááŒá¯áá»ááºáá¯ááºááᯠáááºáá¶áááŸáááŒá®ážáá±á¬ááºá á¡ááá®áá±ážááŸááºážááẠááá±á¬ááºáá¬áᶠá¡áá®ážáááºáááºáá±á·áá»áºááᯠááŒááºáá±ážáááºááŒá áºááŒá®ážá ááááºáááºážááœáẠáá¬ážáá±á¬ááºááŒááºážááᯠáááºááá·áºáᬠááá¯áááºááá°ááẠPOST áá±á¬ááºážááá¯áá»ááºááᯠáá±ážááá¯á·áááºááŒá áºáááºá áá»áœááºá¯ááºááá¯á·ááẠáááºážááœáẠááááºá áááºááŸááºáá¬ážáá±á¬ á¡áá¯ááºáá®ááŸáá·áº ááœááºááá¯ážáẠAPI á០áá»áŸáá¯á·ááŸááºáá»ááºá á¡áá¯á¶ážááŒá¯áá°ááᯠááŒááºáááºááœáŸááºážáá±ážááá·áº ááááºá á¬ááŸáá·áº áááá¯ááá¯áá±á¬ áááºááŸááºáá»ááºááŸáá·áºá¡áá® ááœáá·áºááŒá¯áá±ážááá·áº á¡áá»áá¯ážá¡á á¬ážá
áá¯á¶á·ááŒááºááŸá¯á¡áá±ááŒáá·áºá áá»áœááºá¯ááºááá¯á·ááẠAccess token ááᯠá áá¹ááá·áºááá¯ááºážá¡ááœááºáž áááºážáááá¬ážáááºáá¬áááŸáá·áº ááŒááºáááºá áááºááẠááá¯áááºáá áºáá¯ááᯠáá»áœááºá¯ááºááá¯á·áááŸááááºááŒá áºááŒá®ážá Access token ááᯠá¡ááºááááºáá¯ááºááá¯ááºáá«áááºá
á¡ááá®áá±ážááŸááºážááẠááá¯áááºáá»á¬ážááᯠáá¬ááŸááºáá¶ááá·áºáá±áá¬ááœáẠáá¯á¶ááŒá¯á¶áá±á¬áá±áá¬ááœáẠááááºážáááºážáá¬ážááááºááŒá áºááŒá®ážá ááá¯á·ááŒá±á¬áá·áº áá»áœááºá¯ááºááá¯á· áááºáá¶áááŸááá¬ážáá±á¬ á¡áá¯á¶ážááŒá¯ááœáá·áºááᯠáá¯ááºááááºážáááºá¡áá á¡ááá®áá±ážááŸááºážá០ááŒááºáááºáááºážáá áºáá¬ážáá±á¬ ááá¯áááºááᯠááŒááºáá±ážáááºááá¯ááºáá«á á¡áá¯á¶ážááœááºá áá»áœááºá¯ááºááẠááá¯áááºááᯠááŒááºáááºáá¯ááºááááºážááẠáá±á¬ááºážááá¯áá»ááºáá áºáá¯ááᯠááá·áºááœááºážáá²á·áááºá áá»áŸá±á¬ááºááœáŸá¬ááᯠá¡á±á¬ááºááŒááºá áœá¬ áááŒá®ážááŒá±á¬ááºáá²á·áá² ááŒááºáááºáááºážáá áºááá·áº ááá¯áááºááᯠááŒááºááááá¯ááºáá«áá áááºážááẠáá¯ááºáááºážá ááºááᯠááŒááºáááºá áááºáááá·áºááẠ(áá»áœááºá¯ááºááá¯á·ááẠááá¯áááºáá»á¬ážááᯠá ááºááœááºážááœáẠááá¯ááŸá±á¬ááºááẠá¡áá¹ááá¬ááºáááŸááᯠáá»áœááºá¯ááºááá¯á· áá°áááŒááŒá®ážá cryptography áá²á· á¡áá¬ááœá±ááᯠáááŸá¯ááºááœá±ážá á±áá»ááºáá°áž áá«ááŸááá¯áẠááá±á¬ááºáá¬ááᯠáááŒá¬ááááœáá·áºáá«á)
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
}
áááºáááááŒá¯áááá¬ážááá·áºá¡ááá¯ááºážá ááá¯áááºáá áºáá¯ááᯠáá¯ááºááááºážááá·áºá¡áá«á Invoke-WebRequest ááᯠá¡áá¯á¶ážááŒá¯áááºá Invoke-RestMethod ááŸáá·áºááá°áá²á áááºážááẠáááºáá¶áááŸááá¬ážáá±á¬áá±áá¬ááᯠá¡áá¯á¶ážááŒá¯ááá¯ááºáá±á¬áá¯á¶á á¶ááŒáá·áº ááŒááºááá±ážáá² áá±á¬ááºážááá¯áá»ááºáá¡ááŒá±á¡áá±ááá¯ááŒááááºá
ááá¯á·áá±á¬ááºá script ááẠááá·áºá¡á¬áž á¡áá¯á¶ážááŒá¯áá°á á¡áááºááŸáá·áº áá±á¬ááºáá¯á¶ážá¡áááºááᯠááá¯ááºááá·áºáᬠáá±á¬á·ááºá¡áẠ+ á¡á®ážáá±ážááºááᯠáááºáá®ážááá¯ááºážáááºá
áá±á¬ááºážááá¯áá»ááºáá»á¬áž
áá±á¬ááºáá±á¬ááºážááá¯ááŸá¯áá»á¬ážááŸá¬ - ááááŠážá áœá¬á á¡áá áºáá áºáá¯áááºáá®ážááŒááºáž ááá¯á·ááá¯áẠáááºááŸáááá¯ááœáá·áºááŒááºážááá¯ááºáᬠáá¯á¶ážááŒááºáá»ááºáá áºáá¯áááŸááááºá¡ááœáẠáá°áá®áá±á¬ login ááŸáááá·áºá¡áá¯á¶ážááŒá¯áá°ááŸáááŸáá·áºááŒá®ážáá¬ážááŸááááŸá á á áºáá±ážááẠááá¯á¡ááºáá«áááºá
ááá¯ááºááᯠá¡áá¯á¶ážááŒá¯á ááœá±ážáá»ááºááŸá¯áá áºáá¯ááŒáá·áº áá¯ááºáá±á¬ááºáá»ááºáá áºáá¯á áá±á¬áºáááºááœáẠáá±á¬ááºážááá¯ááŸá¯á¡á¬ážáá¯á¶ážááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááẠáá¯á¶ážááŒááºáá²á·áááº-
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'])
}
}
}
}
áá±á¬ááºážááá¯áá»ááºáá áºáá¯á á®ááœááºá ááá¯áááºá¡áá»áá¯ážá¡á á¬ážááŸáá·áº Access token ááá¯ááºááá¯ááºáá«ááŸááá±á¬ ááœáá·áºááŒá¯áá»ááºáá±á«ááºážá á®ážááᯠáá±ážááá¯á·ááẠááá¯á¡ááºáááºá áááºááŸáááœááºá ááá¯áááºá¡áá»áá¯ážá¡á á¬ážááẠá¡ááŒá²áááºáž Bearer ááŒá áºáááºá áá¬ááŒá áºááá¯á·áá²ááá¯áá±á¬á· ááá¯áááºáááºáááºážááá¯ááºáá±ážááŒá±á¬ááºáž á á áºáá±ážááẠááá¯á¡ááºááŒá®áž áááºážááá¯áá¯ááºáá±ážááá·áºá¡áá»áááºá០áá áºáá¬áá®á¡ááŒá¬ááœáẠáááºážááᯠá¡ááºááááºáá¯ááºááẠááá¯á¡ááºáááºá áá»áœááºá¯ááºááẠAccess token ááᯠááŒááºáá±ážááá·áº á¡ááŒá¬ážáá¯ááºáá±á¬ááºááŸá¯áá áºáá¯á¡ááœáẠáá±á¬ááºážááá¯áá»ááºááᯠáááºááŸááºáá±ážáá«áááºá ááááá¯á¶áž Access token ááá¯áááºáá¶áááŸááá±á¬á¡áá« áá°áá®áá±á¬áá¯ááºá¡ááá¯ááºážááẠscript áá¡á ááœááºááŒá áºáááºá
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
}
áááºááŸáááŸá¯á¡ááœáẠá¡áá±á¬áá·áºááᯠá á áºáá±ážááŒááºáž-
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
}
á¡á®ážáá±ážááº:$query áá±á¬ááºážááá¯áá»ááºááẠáá¬áááºáá°áá»á¬ážá¡áá«á¡ááẠááá¯á¡á®ážáá±ážááºá¡ááá¡áá»ááŸááá±á¬ áá¯á¶ážá áœá²áá°ááᯠááŸá¬ááœá±ááẠAPI á¡á¬áž áá±á¬ááºážááá¯áááºááŒá áºáááºá ááááºááºáááºááá¯áááºáž áá¯á¶ážááá¯ááºáááº- =, :, :{PREFIX}*.
áá±áá¬ááá°áááºá GET áá±á¬ááºážááá¯ááŸá¯áááºážáááºážááᯠá¡áá¯á¶ážááŒá¯áá«á áá±áá¬ááá·áºááœááºážááẠ(á¡áá±á¬áá·áºáá áºáá¯áááºáá®ážááŒááºáž ááá¯á·ááá¯áẠá¡ááœá²á·áááºáá áºáŠážááᯠá¡ááœá²á·áá áºáá¯ááá¯á·ááá·áºááŒááºáž) - POSTá ááŸáááŒá®ážáá¬ážáá±áá¬ááᯠá¡ááºááááºáá¯ááºááẠ- PUTá ááŸááºáááºážáá áºáá¯ááᯠáá»ááºááẠ(á¥ááá¬á á¡ááœá²á·áá áºáá¯á០á¡ááœá²á·áááºáá áºáŠáž) - áá»ááºáá«á
Script ááẠáá¯ááºážáá¶áá«ááºáá áºáᯠ(ááá¬ážááááºáá±á¬ á á¬ááŒá±á¬ááºážáá áºáá¯) ááŸáá·áº áá±áááá¯ááºáᬠááŒáá·áºááŒá°ážáá±ážá¡ááœá²á·ááœáẠáá«áááºáááºá¡ááœááºáááºáž áá±á¬ááºážááá¯áá«áááºá áááºážááẠááœá±ážáá»ááºáá¬ážáá±á¬ Active Directory OU ááá¯á¡ááŒá±áá¶á á¡áá¯á¶ážááŒá¯áá°ááœáẠáááºááá·áºá¡ááœá²á·á¡á ááºážáá°áá áºááᯠáá¯á¶ážááŒááºáá±ážááŒá®áž á áá¬ážááŸááºáá áºáá¯áá±á«áºáá¬áááº-
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"
ááŒá®ážáá±á¬á· áá°á á¡áá±á¬áá·áºááᯠááŒááºááŸááºááá¯á· á áááºáááºá
$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
}
á¡áá±á¬áá·áºáá áºáá¯ááᯠá¡ááºááááºáá¯ááºááŒááºážááŸáá·áº áááºáá®ážááŒááºážá¡ááœáẠáá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááœáẠáááºáá°áá±á¬ á¡áá¬ážá¡ááá¯áá áºáá¯áá«ááŸááááºá á¡ááá¯á¡ááœááºáá»á¬ážá¡á¬ážáá¯á¶ážááᯠáááá¯á¡ááºáá«á áá¯ááºážáá¶áá«ááºáá»á¬ážáá«ááá·áº ááá¹áááœááºá áá¶áá«ááºááŸáá·áº áááºážáá¡áá»áá¯ážá¡á á¬ážááŸáá·áº á á¶áá»áááºáá áºáá¯á¡áá áá«áááºááá¯ááºááá·áº áááºážáá»ááºážáá áºáá¯ááᯠáááºáááºááŸááºááẠááá¯á¡ááºáá«áááºá
á¡ááœá²á·áá áºáá¯ááá¯á· á¡áá¯á¶ážááŒá¯áá°áá áºáŠážááᯠááá·áºááá·áºá¡áá« á¡ááŸá¬ážá¡ááœááºážáá áºáá¯ááááŸáá á±áááºá á¡áá¯á¶ážááŒá¯áá°ááá¯ááºááá¯ááºá០á¡ááœá²á·áááºá á¬áááºáž ááá¯á·ááá¯áẠáá±á«ááºážá ááºááœá²á·á ááºážááŸá¯ááᯠááá°ááŒááºážááŒáá·áº áááºážááẠá€á¡ááœá²á·áá¡ááœá²á·áááºááŒá áºááŒááºážááŸáá áááŸáááᯠáŠážá áœá¬á á áºáá±ážááá¯ááºáá«áááºá
áááºáááºááŸááºááŸááºá¡áá¯á¶ážááŒá¯áá°áá áºáŠážá á¡ááœá²á·á¡ááœá²á·áááºááŒá áºááŸá¯ááᯠá á¯á¶á ááºážáá±ážááŒááºážááŒááºážááẠáááºáá«ááá²áá²áá¯ááºáá±á¬ááºáááºááá¯ááºááá·áºá¡ááŒáẠááá¯ááºááá¯ááºá¡ááœá²á·áááºááŒááºážááá¯áᬠááŒááááºááŒá áºáááºá á¡áá¯á¶ážááŒá¯áá°á¡ááœá²á·áááºááŒá áºáá¬ážááá·áº ááá±ážá¡ááœá²á·ááŸáááŒá®ážáá¬áž áááááºá¡ááœá²á·ááœáẠá¡áá¯á¶ážááŒá¯áá°áá áºáŠážá¡áá«á¡ááẠá¡á±á¬ááºááŒááºáááºááŒá áºáááºá
áá±á¬ááºáá»ááº
áá»ááºáá¬á¡á¬ážáá¯á¶ážá á¡áá±á¬áá·áºá¡áá áºá¡ááœáẠá áá¬ážááŸááºááᯠáá¯á¶ážá áœá²áá°áᶠáá±ážááá¯á·áááºááŒá áºáááºá áá»áœááºá¯ááºááá¯á·ááẠáááºážááᯠSMS ááŸáá áºááá·áºáá¯ááºáá±á¬ááºááŒá®áž á¡ááœá±ááœá±á¡áá»ááºá¡áááºáá»á¬ážááᯠááœáŸááºááŒá¬ážáá»ááºáá»á¬ážááŸáá·áºá¡áá° á á¯áá±á¬ááºážáá±ážáá¬áá០áá±ážáá±á¬ááºáá¬ážááá·áº áá¯ááºážáá¶áá«ááºáá áºáá¯ááŸáá·áºá¡áá° ááá¯ááºáá±ážááá¯ááºáá¬á¡á®ážáá±ážááºááá¯á· áááºáá±á¬ááºááŒá®áž á¡ááœá±ááœá±á¡áá»ááºá¡áááºáá»á¬ážááᯠáá±ážááá¯á·áá«áááºá á¡ááŒá¬ážááœá±ážáá»ááºá áá¬á¡áá±ááŒáá·áºá áááºááẠááœá±á á¯ááá¯ááºááŒá®áž áááºáá áá¬ážááŸááºááᯠáá»áŸáá¯á·ááŸááºááŒá±ážáááºážá áá¬ážááŒá±á¬áááºážááá¯á· áá±ážááá¯á·ááá¯ááºáááºá áááºážááẠáá¯áááá¡áá»ááºáᯠáá°áááá¯ááºááẠ(MacBooks ááẠáá»áœááºážáá»ááºáá áºáá¯ááŒá áºáááá·áºáááº)á
á¡áá¯á¶ážáááááºáá±ážááá¯á· áá»á±ážáá°ážáááºáá«áááºá áá±á¬ááºážáá«ážáá±ážáááºááᯠááá¯ááá¯áá±á¬ááºážááœááºáá¬á á±áááºá¡ááœáẠá¡ááŒá¶ááŒá¯áá»ááºáá»á¬ážááᯠááŒááºááœá±á·áááá·áºá¡ááœáẠáááºážááŒá±á¬ááºááááŒá®áž Script áá»á¬ážáá±ážáá¬ážáá¬ááœáẠá¡ááŸá¬ážá¡ááœááºážáá»á¬áž áááºážáá«ážáá¬á á±ááẠáá¯áá±á¬ááºážáá±ážáá«áááºá =)
á¡ááŒá±á¬ááºážá¡áá¬á¡á á¡áá¯á¶ážáááºááá¯ááºáá±á¬ ááá¯á·ááá¯áẠáá±ážááœááºážáá»á¬ážááᯠááŒá±ááẠááá·áºááºáá»á¬ážá á¬áááºáž-
ááá¯ááá¯ááºážááŸáá·áº áááºá áºáá±á¬á·á¡ááºááºáá»á¬ážá¡ááœáẠOAuth 2.0 Web Server Applications á¡ááœáẠOAuth 2.0 ááᯠá¡áá¯á¶ážááŒá¯ááŒááºážá OAuth á¡áá»á¬ážáá°ááŸá¬áá±á¬ááºáááºáá»á¬ážá Code Exchange á¡ááœáẠá¡áá±á¬ááºá¡áá¬ážáá®áž PowerShell ááŒáá·áº áá»áááºážá á¬áá¯á¶ážáá»á¬ážááᯠáááºáá®ážáá«á ASCII ááá¬ážááŸáá·áºáá±á¬áºááŒáá»áẠPowerShell- á á¬ááŒá±á¬ááºážáá áºáá¯á¡ááœáẠhash áááºááá¯ážááᯠááá°ááŒááºážá Encode/Decode Base64Url Base64 áá¯ááºááŸáá·áº Base64url áá¯ááºáá¶áá«áẠPowerShell 5.1 ááœáẠInvoke-RestMethod access_type ááẠá¡ááá·áº 1 ááœáẠá¡á±á¬á·ááºááá¯ááºážááŒá áºáá±áá±á¬áºáááºáž refresh ááá¯áááºáááá«á ááŸáá¯ááºážááŸááºá¡á±á¬áºááá±áá¬áá»á¬ážá¡ááŒá±á¬ááºáž áááºážááœáŸáẠAPI- á¡áá¯á¶ážááŒá¯áá°á¡áá±á¬áá·áºáá»á¬áž á¡áá¯á¶ážááŒá¯áá°áá»á¬ážááᯠááŸá¬ááœá±áá«á áááºážááœáŸáẠAPI- á¡á¯ááºá á¯áá»á¬áž Invoke-RestMethod á¡ááœáẠá¡ááŸá¬ážá¡ááœááºáž ááá¯ááºááœááºááŒááºáž - Powershell
source: www.habr.com