ะัะธะฒะตั!
์ด ๋ฌธ์์์๋ G Suite ์ฌ์ฉ์๋ฅผ ์กฐ์ํ๊ธฐ ์ํด Google API์ PowerShell ์ํธ ์์ฉ์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์ค๋ช ํฉ๋๋ค.
์ฐ๋ฆฌ๋ ์กฐ์ง ์ ์ฒด์์ ์ฌ๋ฌ ๋ด๋ถ ๋ฐ ํด๋ผ์ฐ๋ ์๋น์ค๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์น์ธ์ Google ๋๋ Active Directory๋ก ๊ท์๋๋ฉฐ ๊ทธ ์ฌ์ด์๋ ๋ณต์ ๋ณธ์ ์ ์งํ ์ ์์ผ๋ฏ๋ก ์ ๊ท ์ง์์ด ํด์ฌํ ๊ฒฝ์ฐ ์ด ๋ ์์คํ
์์ ๊ณ์ ์ ์์ฑ/ํ์ฑํํด์ผ ํฉ๋๋ค. ํ๋ก์ธ์ค๋ฅผ ์๋ํํ๊ธฐ ์ํด ์ฐ๋ฆฌ๋ ์ ๋ณด๋ฅผ ์์งํ์ฌ ๋ ์๋น์ค ๋ชจ๋์ ๋ณด๋ด๋ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
๊ถํ ๋ถ์ฌ
์๊ตฌ ์ฌํญ์ ์์ฑํ ๋ ์ค์ ์ธ๊ฐ ๊ด๋ฆฌ์๋ฅผ ์ฌ์ฉํ์ฌ ์น์ธ์ ํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ์ด๋ ์ฐ๋ฐ์ ์ด๊ฑฐ๋ ์๋์ ์ธ ๋๊ท๋ชจ ๋ณ๊ฒฝ์ด ๋ฐ์ํ ๊ฒฝ์ฐ ์กฐ์น ๋ถ์์ ๋จ์ํํฉ๋๋ค.
Google API๋ ์ธ์ฆ ๋ฐ ์น์ธ์ ์ํด OAuth 2.0 ํ๋กํ ์ฝ์ ์ฌ์ฉํฉ๋๋ค. ์ฌ์ฉ ์ฌ๋ก์ ์์ธํ ์ค๋ช
์ ์ฌ๊ธฐ์์ ํ์ธํ ์ ์์ต๋๋ค.
๋ฐ์คํฌํฑ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ธ์ฆ์ ์ฌ์ฉ๋๋ ์คํฌ๋ฆฝํธ๋ฅผ ์ ํํ์ต๋๋ค. ์ฌ์ฉ์์ ๋ถํ์ํ ์ด๋์ด ํ์ํ์ง ์์ ์๋น์ค ๊ณ์ ์ ์ฌ์ฉํ๋ ์ต์ ๋ ์์ต๋๋ค.
์๋ ๊ทธ๋ฆผ์ Google ํ์ด์ง์์ ์ ํํ ์๋๋ฆฌ์ค์ ๋ํ ๊ฐ๋ต์ ์ธ ์ค๋ช ์ ๋๋ค.
- ๋จผ์ GET ๋งค๊ฐ๋ณ์๋ฅผ ์ง์ ํ์ฌ ์ฌ์ฉ์๋ฅผ Google ๊ณ์ ์ธ์ฆ ํ์ด์ง๋ก ๋ณด๋
๋๋ค.
- ์ ํ๋ฆฌ์ผ์ด์ ID
- ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ก์ธ์คํด์ผ ํ๋ ์์ญ
- ์ ์ฐจ ์๋ฃ ํ ์ฌ์ฉ์๊ฐ ๋ฆฌ๋๋ ์ ๋ ์ฃผ์
- ํ ํฐ์ ์ ๋ฐ์ดํธํ๋ ๋ฐฉ๋ฒ
- ๋ณด์ ์ฝ๋
- ์ธ์ฆ๋ฒํธ ์ ์ก ํ์
- ์ธ์ฆ์ด ์๋ฃ๋ ํ ์ฌ์ฉ์๋ GET ๋งค๊ฐ๋ณ์์ ์ํด ์ ๋ฌ๋ ์ค๋ฅ ๋๋ ์ธ์ฆ ์ฝ๋์ ํจ๊ป ์ฒซ ๋ฒ์งธ ์์ฒญ์ ์ง์ ๋ ํ์ด์ง๋ก ๋ฆฌ๋๋ ์ ๋ฉ๋๋ค.
- ์ ํ๋ฆฌ์ผ์ด์ (์คํฌ๋ฆฝํธ)์ ์ด๋ฌํ ๋งค๊ฐ๋ณ์๋ฅผ ์์ ํด์ผ ํ๋ฉฐ, ์ฝ๋๋ฅผ ์์ ํ ๊ฒฝ์ฐ ํ ํฐ์ ์ป๊ธฐ ์ํด ๋ค์ ์์ฒญ์ ์ํํด์ผ ํฉ๋๋ค.
- ์์ฒญ์ด ์ ํํ๋ฉด Google API๋ ๋ค์์ ๋ฐํํฉ๋๋ค.
- ์์ฒญ์ ํ ์ ์๋ ์ก์ธ์ค ํ ํฐ
- ์ด ํ ํฐ์ ์ ํจ ๊ธฐ๊ฐ
- ์ก์ธ์ค ํ ํฐ์ ์๋ก ๊ณ ์น๋ ค๋ฉด ์๋ก ๊ณ ์นจ ํ ํฐ์ด ํ์ํฉ๋๋ค.
๋จผ์ Google API ์ฝ์๋ก ์ด๋ํด์ผ ํฉ๋๋ค.
์คํฌ๋ฆฝํธ ์๊ณ ๋ฆฌ์ฆ์ ๋ ์ฝ๊ฒ ์ฝ์ ์ ์๋๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ํ ์ก์ธ์ค ๋ฐ ์๋ก ๊ณ ์นจ ํ ํฐ์ ๋ฐํํ๋ ๋ณ๋์ ํจ์์ ์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ฅผ ํ์ํ ์ ์์ต๋๋ค.
$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์ ํด๋ผ์ด์ธํธ ๋น๋ฐ์ ์ค์ ํ๊ณ , ์ฝ๋ ๊ฒ์ฆ์๋ ์์ฝ๋์ง ์์ ๋ฌธ์([AZ] / [az] / [43-128 ])์์ ๋ฌด์์๋ก ์์ฑ๋์ด์ผ ํ๋ 0~9์์ ๋ฌธ์์ด์ ๋๋ค. / "-" / "." / "_" / "~".
๊ทธ๋ฌ๋ฉด ์ด ์ฝ๋๊ฐ ๋ค์ ์ ์ก๋ฉ๋๋ค. ์ด๋ ๊ณต๊ฒฉ์๊ฐ ์ฌ์ฉ์ ์ธ์ฆ ํ ๋ฆฌ๋๋ ์
์ผ๋ก ๋ฐํ๋ ์๋ต์ ๊ฐ๋ก์ฑ ์ ์๋ ์ทจ์ฝ์ฑ์ ์ ๊ฑฐํฉ๋๋ค.
ํ์ฌ ์์ฒญ์ ์ฝ๋ ๊ฒ์ฆ๊ธฐ๋ฅผ ์ผ๋ฐ ํ
์คํธ(์๋ฏธ ์์ - SHA256์ ์ง์ํ์ง ์๋ ์์คํ
์๋ง ์ ํฉํจ)๋ก ๋ณด๋ด๊ฑฐ๋ BASE256Url๋ก ์ธ์ฝ๋ฉํด์ผ ํ๋ SHA64 ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ํด์๋ฅผ ์์ฑํ์ฌ ๋ณด๋ผ ์ ์์ต๋๋ค(๋ค๋ฆ) Base64์์ ๋ ๊ฐ์ ํ
์ด๋ธ ๋ฌธ์๋ก) ๋ฐ ๋ฌธ์ ์ค ๋์ ์ ๊ฑฐํฉ๋๋ค: =.
๋ค์์ผ๋ก, ์ธ์ฆ ํ ์๋ต์ ์์ ํ๊ธฐ ์ํด ๋ก์ปฌ ์์คํ ์์ http ์์ ์ ์์ํด์ผ ํ๋ฉฐ, ์ด๋ ๋ฆฌ๋๋ ์ ์ผ๋ก ๋ฐํ๋ฉ๋๋ค.
๊ด๋ฆฌ ์์ ์ ํน์ ์๋ฒ์์ ์ํ๋๋ฏ๋ก ์ฌ๋ฌ ๊ด๋ฆฌ์๊ฐ ๋์์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ ๊ฐ๋ฅ์ฑ์ ๋ฐฐ์ ํ ์ ์์ผ๋ฏ๋ก ํ์ฌ ์ฌ์ฉ์์ ๋ํ ํฌํธ๋ฅผ ๋ฌด์์๋ก ์ ํํ์ง๋ง ๋ฏธ๋ฆฌ ์ ์๋ ํฌํธ๋ฅผ ์ง์ ํ์ต๋๋ค. ๋ํ API ์ฝ์์์ ์ ๋ขฐํ ์ ์๋ ๊ฒ์ผ๋ก ์ถ๊ฐํด์ผ ํฉ๋๋ค.
access_type=์คํ๋ผ์ธ ์ด๋ ์ฌ์ฉ์๊ฐ ๋ธ๋ผ์ฐ์ ์ ์ํธ ์์ฉํ์ง ์๊ณ ๋ ์ ํ๋ฆฌ์ผ์ด์
์ด ๋ง๋ฃ๋ ํ ํฐ์ ์์ฒด์ ์ผ๋ก ์
๋ฐ์ดํธํ ์ ์์์ ์๋ฏธํฉ๋๋ค.
์๋ต ์ ํ=์ฝ๋ ์ฝ๋๊ฐ ๋ฐํ๋๋ ๋ฐฉ์์ ํ์์ ์ค์ ํฉ๋๋ค(์ฌ์ฉ์๊ฐ ๋ธ๋ผ์ฐ์ ์์ ์คํฌ๋ฆฝํธ๋ก ์ฝ๋๋ฅผ ๋ณต์ฌํ ๋ ์ด์ ์ธ์ฆ ๋ฐฉ๋ฒ์ ๋ํ ์ฐธ์กฐ).
๋ฒ์ ์ก์ธ์ค ๋ฒ์์ ์ ํ์ ๋ํ๋
๋๋ค. URL ์ธ์ฝ๋ฉ์ ๋ฐ๋ผ ๊ณต๋ฐฑ์ด๋ %20์ผ๋ก ๊ตฌ๋ถํด์ผ ํฉ๋๋ค. ์ ํ์ด ํฌํจ๋ ์ก์ธ์ค ์์ญ ๋ชฉ๋ก์ ์ฌ๊ธฐ์์ ๋ณผ ์ ์์ต๋๋ค.
์ธ์ฆ ์ฝ๋๋ฅผ ๋ฐ์ ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ธ๋ผ์ฐ์ ์ ๋ซ๊ธฐ ๋ฉ์์ง๋ฅผ ๋ฐํํ๊ณ ํฌํธ ์์ ๋๊ธฐ๋ฅผ ์ค์งํ ํ ํ ํฐ์ ์ป๊ธฐ ์ํด POST ์์ฒญ์ ๋ณด๋ ๋๋ค. ์ฌ๊ธฐ์๋ ์ฝ์ API์์ ์ด์ ์ ์ง์ ํ ID์ ๋น๋ฐ, ํ๋กํ ์ฝ ์ฌ์์ ๋ฐ๋ผ ์ฌ์ฉ์๊ฐ ๋ฆฌ๋๋ ์ ๋ ์ฃผ์ ๋ฐ grant_type์ด ํ์๋ฉ๋๋ค.
์ด์ ๋ํ ์๋ต์ผ๋ก ์ฐ๋ฆฌ๋ ์ก์ธ์ค ํ ํฐ, ์ ํจ ๊ธฐ๊ฐ(์ด), ์ก์ธ์ค ํ ํฐ์ ์ ๋ฐ์ดํธํ ์ ์๋ ์๋ก ๊ณ ์นจ ํ ํฐ์ ๋ฐ๊ฒ ๋ฉ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ ์ ํจ ๊ธฐ๊ฐ์ด ๊ธด ์์ ํ ์ฅ์์ ํ ํฐ์ ์ ์ฅํด์ผ ํ๋ฏ๋ก, ์์ ๋ ์ก์ธ์ค ๊ถํ์ ์ทจ์ํ ๋๊น์ง ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋ก ๊ณ ์นจ ํ ํฐ์ ๋ฐํํ์ง ์์ต๋๋ค. ๋ง์ง๋ง์ ํ ํฐ ์ทจ์ ์์ฒญ์ ์ถ๊ฐํ๋๋ฐ, ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์ง ์๊ณ ์๋ก ๊ณ ์นจ ํ ํฐ์ด ๋ฐํ๋์ง ์์ผ๋ฉด ์ ์ฐจ๊ฐ ๋ค์ ์์๋ฉ๋๋ค(์ฐ๋ฆฌ๋ ํ ํฐ์ ํฐ๋ฏธ๋์ ๋ก์ปฌ๋ก ์ ์ฅํ๋ ๊ฒ์ด ์์ ํ์ง ์๋ค๊ณ ํ๋จํ์ฌ ์ํธํ๋ก ์ผ์ ๋ณต์กํ๊ฒ ํ๊ฑฐ๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ์์ฃผ ์ด๊ณ ์ถ์ง ์์ต๋๋ค.)
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์ ๋ฌ๋ฆฌ ์์ ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉ ๊ฐ๋ฅํ ํ์์ผ๋ก ๋ฐํํ์ง ์๊ณ ์์ฒญ ์ํ๋ฅผ ํ์ํฉ๋๋ค.
๋ค์์ผ๋ก ์คํฌ๋ฆฝํธ๋ ์ฌ์ฉ์์ ์ฑ๊ณผ ์ด๋ฆ์ ์ ๋ ฅํ์ฌ ๋ก๊ทธ์ธ + ์ด๋ฉ์ผ์ ์์ฑํ๋๋ก ์์ฒญํฉ๋๋ค.
์์ฒญ
๋ค์ ์์ฒญ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๋จผ์ ์ ๋ก๊ทธ์ธ์ ๋ง๋ค๊ฑฐ๋ ํ์ฌ ๋ก๊ทธ์ธ์ ํ์ฑํํ๋ ๊ฒฐ์ ์ ๋ด๋ฆฌ๋ ค๋ฉด ๋์ผํ ๋ก๊ทธ์ธ์ ๊ฐ์ง ์ฌ์ฉ์๊ฐ ์ด๋ฏธ ์กด์ฌํ๋์ง ํ์ธํด์ผ ํฉ๋๋ค.
์ค์์น๋ฅผ ์ฌ์ฉํ์ฌ ์ ํ ํญ๋ชฉ์ด ์๋ ํ๋์ ํจ์ ํ์์ผ๋ก ๋ชจ๋ ์์ฒญ์ ๊ตฌํํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
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'])
}
}
}
}
๊ฐ ์์ฒญ์์ ํ ํฐ ์ ํ๊ณผ ์ก์ธ์ค ํ ํฐ ์์ฒด๊ฐ ํฌํจ๋ Authorization ํค๋๋ฅผ ๋ณด๋ด์ผ ํฉ๋๋ค. ํ์ฌ ํ ํฐ ์ ํ์ ํญ์ Bearer์ ๋๋ค. ์๋ํ๋ฉด ํ ํฐ์ด ๋ง๋ฃ๋์ง ์์๋์ง ํ์ธํ๊ณ ๋ฐ๊ธ๋ ์ง ํ ์๊ฐ ํ์ ์ ๋ฐ์ดํธํด์ผ ํฉ๋๋ค. ์ ๋ ์ก์ธ์ค ํ ํฐ์ ๋ฐํํ๋ ๋ค๋ฅธ ํจ์์ ๋ํ ์์ฒญ์ ์ง์ ํ์ต๋๋ค. ์ฒซ ๋ฒ์งธ ์ก์ธ์ค ํ ํฐ์ ๋ฐ์ ๋ ์คํฌ๋ฆฝํธ ์์ ๋ถ๋ถ์ ๋์ผํ ์ฝ๋ ์กฐ๊ฐ์ด ์์ต๋๋ค.
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
}
email:$query ์์ฒญ์ ๋ณ์นญ์ ํฌํจํ์ฌ ์ ํํ ํด๋น ์ด๋ฉ์ผ์ ๊ฐ์ง ์ฌ์ฉ์๋ฅผ ์ฐพ๋๋ก API์ ์์ฒญํฉ๋๋ค. ์์ผ๋์นด๋๋ฅผ ์ฌ์ฉํ ์๋ ์์ต๋๋ค. =, :, :{์ ๋์ฌ}*.
๋ฐ์ดํฐ๋ฅผ ์ป์ผ๋ ค๋ฉด GET ์์ฒญ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ์ญ์์ค(๊ณ์ ์์ฑ ๋๋ ๊ทธ๋ฃน์ ๊ตฌ์ฑ์ ์ถ๊ฐ) - POST, ๊ธฐ์กด ๋ฐ์ดํฐ ์ ๋ฐ์ดํธ - PUT, ๋ ์ฝ๋ ์ญ์ (์: ๊ทธ๋ฃน์ ๊ตฌ์ฑ์) - ์ญ์ .
๋ํ ์คํฌ๋ฆฝํธ๋ ์ ํ๋ฒํธ(๊ฒ์ฆ๋์ง ์์ ๋ฌธ์์ด)์ ์ง์ญ ๋ฐฐํฌ ๊ทธ๋ฃน์ ํฌํจ์ ์์ฒญํฉ๋๋ค. ์ ํํ 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
}
๊ณ์ ์ ์ ๋ฐ์ดํธํ๊ณ ์์ฑํ๋ ํจ์๋ ๊ตฌ๋ฌธ์ด ๋น์ทํฉ๋๋ค. ๋ชจ๋ ์ถ๊ฐ ํ๋๊ฐ ํ์ํ ๊ฒ์ ์๋๋๋ค. ์ ํ๋ฒํธ๊ฐ ์๋ ์น์ ์์๋ ๋ฒํธ์ ํด๋น ์ ํ์ด ํฌํจ๋ ๋ ์ฝ๋๋ฅผ ์ต๋ XNUMX๊ฐ๊น์ง ํฌํจํ ์ ์๋ ๋ฐฐ์ด์ ์ง์ ํด์ผ ํฉ๋๋ค.
์ฌ์ฉ์๋ฅผ ๊ทธ๋ฃน์ ์ถ๊ฐํ ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์๋๋ก ํ๋ ค๋ฉด ๋จผ์ ์ฌ์ฉ์๋ก๋ถํฐ ๊ทธ๋ฃน ๊ตฌ์ฑ์ ๋ชฉ๋ก์ด๋ ๊ตฌ์ฑ ๋ชฉ๋ก์ ์ป์ด์ ํด๋น ์ฌ์ฉ์๊ฐ ์ด๋ฏธ ์ด ๊ทธ๋ฃน์ ๊ตฌ์ฑ์์ธ์ง ์ฌ๋ถ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
ํน์ ์ฌ์ฉ์์ ๊ทธ๋ฃน ๋ฉค๋ฒ์ญ์ ์ฟผ๋ฆฌํ๋ฉด ์ฌ๊ท์ ์ด์ง ์์ผ๋ฉฐ ์ง์ ๋ฉค๋ฒ์ญ๋ง ํ์๋ฉ๋๋ค. ์ฌ์ฉ์๊ฐ ๊ตฌ์ฑ์์ผ๋ก ์ํ ํ์ ๊ทธ๋ฃน์ด ์ด๋ฏธ ์๋ ์์ ๊ทธ๋ฃน์ ์ฌ์ฉ์๋ฅผ ํฌํจํ๋ฉด ์ฑ๊ณตํฉ๋๋ค.
๊ฒฐ๋ก
๋จ์ ๊ฒ์ ์ฌ์ฉ์์๊ฒ ์ ๊ณ์ ์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณด๋ด๋ ๊ฒ๋ฟ์ ๋๋ค. ์ฐ๋ฆฌ๋ SMS๋ฅผ ํตํด ์ด๋ฅผ ์ํํ๊ณ ์ฑ์ฉ ๋ถ์์์ ์ ๊ณตํ ์ ํ๋ฒํธ์ ํจ๊ป ๊ฐ์ธ ์ด๋ฉ์ผ์ ๋ํ ์ง์นจ ๋ฐ ๋ก๊ทธ์ธ๊ณผ ํจ๊ป ์ผ๋ฐ ์ ๋ณด๋ฅผ ๋ณด๋ ๋๋ค. ๋์์ผ๋ก, ๋น์ฉ์ ์ ์ฝํ๊ณ ๋น๋ฐ ์ ๋ณด ์ฑํ ์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณด๋ผ ์ ์์ต๋๋ค. ์ด๋ ๋ ๋ฒ์งธ ์์๋ก ๊ฐ์ฃผ๋ ์๋ ์์ต๋๋ค(MacBook์ ์์ธ์).
๋๊น์ง ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๊ธฐ์ฌ ์์ฑ ์คํ์ผ์ ๊ฐ์ ํ๊ธฐ ์ํ ์ ์์ ๋ณด๊ฒ ๋์ด ๊ธฐ์๊ณ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ ๋ ์ค๋ฅ๊ฐ ์ค์ด๋ค๊ธฐ๋ฅผ ๋ฐ๋๋๋ค =)
์ฃผ์ ๋ณ๋ก ์ ์ฉํ๊ฑฐ๋ ๋จ์ํ ์ง๋ฌธ์ ๋ต๋ณํ ์ ์๋ ๋งํฌ ๋ชฉ๋ก:
๋ชจ๋ฐ์ผ ๋ฐ ๋ฐ์คํฌํฑ ์ฑ์ฉ OAuth 2.0 ์น ์๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ OAuth 2.0 ์ฌ์ฉ OAuth ๊ณต๊ฐ ํด๋ผ์ด์ธํธ์ ์ํ ์ฝ๋ ๊ตํ์ ์ํ ์ฆ๋ช ํค PowerShell์ ์ฌ์ฉํ์ฌ ์์์ ๋ฌธ์ ์์ฑ ASCII ํ ์ด๋ธ ๋ฐ ์ค๋ช PowerShell: ๋ฌธ์์ด์ ํด์ ๊ฐ ๊ฐ์ ธ์ค๊ธฐ Base64Url ์ธ์ฝ๋ฉ/๋์ฝ๋ฉ Base64 ์ธ์ฝ๋ฉ๊ณผ Base64url ์ธ์ฝ๋ฉ ๋น๊ต PowerShell 5.1์ Invoke-RestMethod 1๋จ๊ณ์์ access_type์ด ์คํ๋ผ์ธ์ธ๋ฐ๋ ์๋ก ๊ณ ์นจ ํ ํฐ์ ๋ฐ์ง ๋ชปํจ ๋น๊ต ์ฐ์ฐ์ ์ ๋ณด ๋๋ ํฐ๋ฆฌ API: ์ฌ์ฉ์ ๊ณ์ ์ฌ์ฉ์ ๊ฒ์ ๋๋ ํ ๋ฆฌ API: ๊ทธ๋ฃน Invoke-RestMethod์ ๋ํ ์ค๋ฅ ์ฒ๋ฆฌ - Powershell
์ถ์ฒ : habr.com