ืงืจื™ื™ื™ื˜ื™ื ื’ Google ื™ื•ื–ืขืจื– ืคึฟื•ืŸ PowerShell ื“ื•ืจืš ืึทืคึผื™

ื”ื™!

ื“ืขืจ ืึทืจื˜ื™ืงืœ ื•ื•ืขื˜ ื‘ืึทืฉืจื™ื™ึทื‘ืŸ ื“ื™ ื™ืžืคึผืœืึทืžืขื ื˜ื™ื™ืฉืึทืŸ ืคื•ืŸ PowerShell ื™ื ื˜ืขืจืึทืงืฉืึทืŸ ืžื™ื˜ ื“ื™ Google API ืฆื• ืžืึทื ื™ืคึผื•ืœื™ืจืŸ G Suite ื™ื•ื–ืขืจื–.

ืžื™ืจ ื ื•ืฆืŸ ืขื˜ืœืขื›ืข ื™ื ืขืจืœืขืš ืื•ืŸ ื•ื•ืึธืœืงืŸ ื‘ืึทื“ื™ื ื•ื ื’ืก ืึทืจื™ื‘ืขืจ ื“ื™ ืึธืจื’ืึทื ื™ื–ืึทืฆื™ืข. ืฆื•ื ืžืขืจืกื˜ืŸ, ื“ืขืจ ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ ืื™ืŸ ื–ื™ื™ ืงื•ืžื˜ ืึทืจืึธืคึผ ืฆื• Google ืึธื“ืขืจ ืึทืงื˜ื™ื•ื•ืข Directory, ืฆื•ื•ื™ืฉืŸ ื•ื•ืึธืก ืžื™ืจ ืงืขื ืขืŸ ื ื™ืฉื˜ ื”ืึทืœื˜ืŸ ืึท ืจืขืคึผืœื™ืงืข; ืึทืงืึธืจื“ื™ื ื’ืœื™, ื•ื•ืขืŸ ืึท ื ื™ื™ึทืข ืึธื ื’ืขืฉื˜ืขืœื˜ืขืจ ืคืึทืจืœืึธื–ืŸ, ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืฉืึทืคึฟืŸ / ื’ืขื‘ืŸ ืึท ื—ืฉื‘ื•ืŸ ืื™ืŸ ื“ื™ ืฆื•ื•ื™ื™ ืกื™ืกื˜ืขืžืขืŸ. ืฆื• ืึธื˜ืึทืžื™ื™ื˜ ื“ืขื ืคึผืจืึธืฆืขืก, ืžื™ืจ ื‘ืึทืฉืœืึธืกืŸ ืฆื• ืฉืจื™ื™ึทื‘ืŸ ืึท ืฉืจื™ืคื˜ ื•ื•ืึธืก ืงืึทืœืขืงืฅ ืื™ื ืคึฟืึธืจืžืึทืฆื™ืข ืื•ืŸ ืกืขื ื“ื– ืขืก ืฆื• ื‘ื™ื™ื“ืข ื‘ืึทื“ื™ื ื•ื ื’ืก.

ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ

ื•ื•ืขืŸ ื“ื™ ืจืขืงื•ื•ื™ืจืขืžืขื ืฅ, ืžื™ืจ ื‘ืึทืฉืœืึธืกืŸ ืฆื• ื ื•ืฆืŸ ืคืึทืงื˜ื™ืฉ ืžืขื ื˜ืฉ ืึทื“ืžื™ื ื™ืกื˜ืจืึทื˜ืึธืจืก ืคึฟืึทืจ ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ; ื“ืึธืก ืกื™ืžืคึผืœืึทืคื™ื™ื– ื“ื™ ืึทื ืึทืœื™ืกื™ืก ืคื•ืŸ ืึทืงืฉืึทื ื– ืื™ืŸ ืคืึทืœ ืคื•ืŸ ืึทืงืกืึทื“ืขื ื˜ืึทืœ ืึธื“ืขืจ ื™ื ื˜ืขื ืฉืึทื ืึทืœ ืžืึทืกื™ื•ื• ืขื ื“ืขืจื•ื ื’ืขืŸ.

Google ืึทืคึผื™ืก ื ื•ืฆืŸ ื“ื™ OAuth 2.0 ืคึผืจืึธื˜ืึธืงืึธืœ ืคึฟืึทืจ ืึธื˜ืขื ื˜ืึทืงื™ื™ืฉืึทืŸ ืื•ืŸ ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ. ื ื™ืฆืŸ ืงืึทืกืขืก ืื•ืŸ ืžืขืจ ื“ื™ื˜ื™ื™ืœื“ ื“ื™ืกืงืจื™ืคึผืฉืึทื ื– ืงืขื ืขืŸ ื–ื™ื™ืŸ ื’ืขืคึฟื•ื ืขืŸ ื“ืึธ: ื ื™ืฆืŸ OAuth 2.0 ืฆื• ืึทืงืกืขืก Google APIs.

ืื™ืš ืื•ื™ืกื“ืขืจื•ื•ื™ื™ืœื˜ ื“ื™ ืฉืจื™ืคื˜ ื•ื•ืึธืก ืื™ื– ื’ืขื ื™ืฆื˜ ืคึฟืึทืจ ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ ืื™ืŸ ื“ืขืกืงื˜ืึทืคึผ ืึทืคึผืœืึทืงื™ื™ืฉืึทื ื–. ืขืก ืื™ื– ืื•ื™ืš ืึทืŸ ืึธืคึผืฆื™ืข ืฆื• ื ื•ืฆืŸ ืึท ื“ื™ื ืกื˜ ื—ืฉื‘ื•ืŸ, ื•ื•ืึธืก ื˜ื•ื˜ ื ื™ืฉื˜ ื“ืึทืจืคืŸ ื•ืžื ื™ื™ื˜ื™ืง ืžื•ื•ื•ืžืึทื ืฅ ืคื•ืŸ ื“ื™ ื‘ืึทื ื™ืฆืขืจ.

ื“ื™ ื‘ื™ืœื“ ืื•ื ื˜ืŸ ืื™ื– ืึท ืกื›ืขืžืึทื˜ื™ืฉ ื‘ืึทืฉืจื™ื™ึทื‘ื•ื ื’ ืคื•ืŸ ื“ื™ ืื•ื™ืกื’ืขืงืœื™ื‘ืŸ ืกืฆืขื ืึทืจ ืคื•ืŸ ื“ื™ Google ื‘ืœืึทื˜.

ืงืจื™ื™ื™ื˜ื™ื ื’ Google ื™ื•ื–ืขืจื– ืคึฟื•ืŸ PowerShell ื“ื•ืจืš ืึทืคึผื™

  1. ืขืจืฉื˜ืขืจ, ืžื™ืจ ืฉื™ืงืŸ ื“ืขื ื‘ืึทื ื™ืฆืขืจ ืฆื• ื“ื™ Google ืึทืงืึทื•ื ื˜ ืึธื˜ืขื ื˜ืึทืงื™ื™ืฉืึทืŸ ื‘ืœืึทื˜, ืกืคึผืขืฆื™ืคื™ืฆื™ืจืŸ GET ืคึผืึทืจืึทืžืขื˜ืขืจืก:
    • ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ืฉื™ื™ึทืŸ
    • ื’ืขื‘ื™ื˜ืŸ ืฆื• ื•ื•ืึธืก ื“ื™ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ื“ืึทืจืฃ ืึทืงืกืขืก
    • ื“ื™ ืึทื“ืจืขืก ืฆื• ื•ื•ืึธืก ื“ืขืจ ื‘ืึทื ื™ืฆืขืจ ื•ื•ืขื˜ ื–ื™ื™ืŸ ืจื™ื“ืขืจืขืงื˜ื™ื“ ื ืึธืš ืงืึทืžืคึผืœื™ื˜ื™ื ื’ ื“ื™ ืคึผืจืึธืฆืขื“ื•ืจ
    • ื“ื™ ื•ื•ืขื’ ืžื™ืจ ื•ื•ืขืœืŸ ื“ืขืจื”ื™ื™ึทื ื˜ื™ืงืŸ ื“ื™ ืกื™ืžืขืŸ
    • ื–ื™ื›ืขืจื”ื™ื™ึทื˜ ืงืึธื“
    • ื•ื•ืขืจืึทืคืึทืงื™ื™ืฉืึทืŸ ืงืึธื“ ื˜ืจืึทื ืกืžื™ืกื™ืข ืคึฟืึธืจืžืึทื˜

  2. ื ืึธืš ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ ืื™ื– ื’ืขืขื ื“ื™ืงื˜, ื“ืขืจ ื‘ืึทื ื™ืฆืขืจ ื•ื•ืขื˜ ื–ื™ื™ืŸ ืจื™ื“ืขืจืขืงื˜ื™ื“ ืฆื• ื“ื™ ื‘ืœืึทื˜ ืกืคึผืขืกื™ืคื™ืขื“ ืื™ืŸ ื“ืขืจ ืขืจืฉื˜ืขืจ ื‘ืขื˜ืŸ, ืžื™ื˜ ืึท ื˜ืขื•ืช ืึธื“ืขืจ ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ ืงืึธื“ ื“ื•ืจื›ื’ืขื’ืื ื’ืขืŸ ื“ื•ืจืš GET ืคึผืึทืจืึทืžืขื˜ืขืจืก
  3. ื“ื™ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ (ืฉืจื™ืคื˜) ื•ื•ืขื˜ ื“ืึทืจืคึฟืŸ ืฆื• ื‘ืึทืงื•ืžืขืŸ ื“ื™ ืคึผืึทืจืึทืžืขื˜ืขืจืก ืื•ืŸ, ืื•ื™ื‘ ื‘ืืงื•ืžืขืŸ ื“ื™ ืงืึธื“, ืžืึทื›ืŸ ื“ื™ ืคืืœื’ืขื ื“ืข ื‘ืขื˜ืŸ ืฆื• ื‘ืึทืงื•ืžืขืŸ ื˜ืึธืงืขื ืก
  4. ืื•ื™ื‘ ื“ื™ ื‘ืงืฉื” ืื™ื– ืจื™ื›ื˜ื™ืง, ื“ื™ Google API ืงืขืจื˜:
    • ืึทืงืกืขืก ืกื™ืžืขืŸ ืžื™ื˜ ื•ื•ืึธืก ืžื™ืจ ืงืขื ืขืŸ ืžืึทื›ืŸ ืจื™ืงื•ื•ืขืก
    • ื“ื™ ื’ื™ืœื˜ื™ืงื™ื™ึทื˜ ืฆื™ื™ึทื˜ ืคื•ืŸ ื“ืขื ืกื™ืžืขืŸ
    • ื“ืขืจืคืจื™ืฉืŸ ื˜ืึธืงืขืŸ ืคืืจืœืื ื’ื˜ ืฆื• ื“ืขืจืคืจื™ืฉืŸ ื“ื™ ืึทืงืกืขืก ืกื™ืžืขืŸ.

ืขืจืฉื˜ืขืจ ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ื’ื™ื™ืŸ ืฆื• ื“ื™ Google API ืงืึทื ืกืึธื•ืœ: ืงืจืึทื“ืขื ื˜ืฉืึทืœื– - Google API ืงืึทื ืกืึธื•ืœ, ืื•ื™ืกืงืœื™ื™ึทื‘ืŸ ื“ื™ ื’ืขื‘ืขื˜ืŸ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ืื•ืŸ ืื™ืŸ ื“ื™ ืงืจืึทื“ืขื ื˜ืฉืึทืœื– ืึธืคึผื˜ื™ื™ืœื•ื ื’ ืฉืึทืคึฟืŸ ืึท ืงืœื™ืขื ื˜ OAuth ื™ื“ืขื ื˜ื™ืคื™ืขืจ. ื“ืึธืจื˜ (ืึธื“ืขืจ ืฉืคึผืขื˜ืขืจ, ืื™ืŸ ื“ื™ ืคึผืจืึธืคึผืขืจื˜ื™ืขืก ืคื•ืŸ ื“ื™ ื‘ืืฉืืคืŸ ืื™ื“ืขื ื˜ื™ืคื™ืฆื™ืจืŸ) ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืกืคึผืขืฆื™ืคื™ืฆื™ืจืŸ ื“ื™ ืึทื“ืจืขืกืขืก ืฆื• ื•ื•ืึธืก ืจื™ื“ืขืจืขืงืฉืึทืŸ ืื™ื– ืขืจืœื•ื™ื‘ื˜. ืื™ืŸ ืื•ื ื“ื–ืขืจ ืคืึทืœ, ื“ืึธืก ื•ื•ืขื˜ ื–ื™ื™ืŸ ืขื˜ืœืขื›ืข ืœืึธืงืึทืœื”ืึธืกื˜ ืื™ื™ื ืกืŸ ืžื™ื˜ ืคืึทืจืฉื™ื“ืขื ืข ืคึผืึธืจืฅ (ื–ืขืŸ ื•ื•ื™ื™ื˜ืขืจ).

ืฆื• ืžืึทื›ืŸ ืขืก ืžืขืจ ื‘ืึทืงื•ื•ืขื ืฆื• ืœื™ื™ืขื ืขืŸ ื“ื™ ืฉืจื™ืคื˜ ืึทืœื’ืขืจื™ื“ืึทื, ืื™ืจ ืงืขื ืขืŸ ื•ื•ื™ื™ึทื–ืŸ ื“ื™ ืขืจืฉื˜ืขืจ ืกื˜ืขืคึผืก ืื™ืŸ ืึท ื‘ืึทื–ื•ื ื“ืขืจ ืคื•ื ืงืฆื™ืข ื•ื•ืึธืก ื•ื•ืขื˜ ืฆื•ืจื™ืงืงื•ืžืขืŸ ืึทืงืกืขืก ืื•ืŸ ื“ืขืจืคืจื™ืฉืŸ ื˜ืึธืงืขื ืก ืคึฟืึทืจ ื“ื™ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ:

$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 ืงืœื™ืขื ื˜ ื™ื™ื“ืขื ืึทืคื™ื™ื“ ืคึผืจืึธืคึผืขืจื˜ื™ืขืก, ืื•ืŸ ื“ื™ ืงืึธื“ ื•ื•ืขืจืึทืคื™ื™ืขืจ ืื™ื– ืึท ืฉื˜ืจื™ืงืœ ืคื•ืŸ 43 ืฆื• 128 ืื•ืชื™ื•ืช ื•ื•ืึธืก ืžื•ื–ืŸ ื–ื™ื™ืŸ ืจืึทื ื“ืึทืžืœื™ ื“ื–ืฉืขื ืขืจื™ื™ื˜ืึทื“ ืคึฟื•ืŸ ืึทื ืจื™ื–ืขืจื•ื•ื“ ืื•ืชื™ื•ืช: [AZ] / [ืึทื–] / [0-9] / "-" / "." / "_" / "~".

ื“ืขืจ ืงืึธื“ ื•ื•ืขื˜ ื“ืขืžืึธืœื˜ ื–ื™ื™ืŸ ื˜ืจืึทื ืกืžื™ื˜ื˜ืขื“ ื•ื•ื™ื“ืขืจ. ืขืก ื™ืœื™ืžืึทื ื™ื™ืฅ ื“ื™ ื•ื•ืึทืœื ืขืจืึทื‘ื™ืœื™ื˜ื™ ืื™ืŸ ื•ื•ืึธืก ืึท ืึทื˜ืึทืงืขืจ ืงืขืŸ ื™ื ื˜ืขืจืกืขืคึผื˜ ืึท ืขื ื˜ืคืขืจ ืื•ืžื’ืขืงืขืจื˜ ื•ื•ื™ ืึท ืจื™ื“ืขืจืขืงื˜ ื ืึธืš ื‘ืึทื ื™ืฆืขืจ ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ.
ืื™ืจ ืงืขื ืขืŸ ืฉื™ืงืŸ ืึท ืงืึธื“ ื•ื•ืขืจื™ืคื™ื™ืขืจ ืื™ืŸ ื“ืขื ืงืจืึทื ื˜ ื‘ืขื˜ืŸ ืื™ืŸ ืงืœืึธืจ ื˜ืขืงืกื˜ (ื•ื•ืึธืก ืžืื›ื˜ ืขืก ืžื™ื ื™ื ื’ืœืึทืก - ื“ืึธืก ืื™ื– ื‘ืœื•ื™ื– ืคึผืึทืกื™ืง ืคึฟืึทืจ ืกื™ืกื˜ืขืžืขืŸ ื•ื•ืึธืก ื˜ืึธืŸ ื ื™ื˜ ืฉื˜ื™ืฆืŸ SHA256), ืึธื“ืขืจ ื“ื•ืจืš ืงืจื™ื™ื™ื˜ื™ื ื’ ืึท ื”ืึทืฉ ืžื™ื˜ ื“ื™ SHA256 ืึทืœื’ืขืจื™ื“ืึทื, ื•ื•ืึธืก ืžื•ื–ืŸ ื–ื™ื™ืŸ ืขื ืงืึธื•ื“ื™ื“ ืื™ืŸ BASE64Url (ื“ื™ืคืขืจืขื ื˜ืœื™). ืคึฟื•ืŸ Base64 ื“ื•ืจืš ืฆื•ื•ื™ื™ ื˜ื™ืฉ ืื•ืชื™ื•ืช) ืื•ืŸ ืจื™ืžื•ื•ื•ื™ื ื’ ื“ื™ ื›ืึทืจืึทืงื˜ืขืจ ืฉื•ืจื” ืขื ื“ื™ื ื’ื–: =.

ื“ืขืจื ืึธืš, ืžื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืึธื ื”ื™ื™ื‘ืŸ ืฆื•ื’ืขื”ืขืจื˜ ืฆื• http ืื•ื™ืฃ ื“ื™ ื”ื™ื’ืข ืžืึทืฉื™ืŸ ืฆื• ื‘ืึทืงื•ืžืขืŸ ืึท ืขื ื˜ืคืขืจ ื ืึธืš ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ, ื•ื•ืึธืก ื•ื•ืขื˜ ื–ื™ื™ืŸ ืื•ืžื’ืขืงืขืจื˜ ื•ื•ื™ ืึท ืจื™ื“ืขืจืขืงื˜.

ืึทื“ืžื™ื ื™ืกื˜ืจืึทื˜ื™ื•ื•ืข ื˜ืึทืกืงืก ื–ืขื ืขืŸ ื“ื•ืจื›ื’ืขืงืึธื›ื˜ ืื•ื™ืฃ ืึท ืกืคึผืขืฆื™ืขืœ ืกืขืจื•ื•ืขืจ, ืžื™ืจ ืงืขื ืขืŸ ื ื™ืฉื˜ ื•ื™ืกืฉืœื™ืกืŸ ื“ื™ ืžืขื’ืœืขื›ืงื™ื™ื˜ ืึทื– ืขื˜ืœืขื›ืข ืึทื“ืžื™ื ื™ืกื˜ืจืึทื˜ืึธืจืก ื•ื•ืขืœืŸ ืœื•ื™ืคืŸ ื“ื™ ืฉืจื™ืคื˜ ืื™ืŸ ื“ืขืจ ื–ืขืœื‘ื™ืงืขืจ ืฆื™ื™ื˜, ืึทื–ื•ื™ ืขืก ื•ื•ืขื˜ ืจืึทื ื“ืึทืžืœื™ ืื•ื™ืกืงืœื™ื™ึทื‘ืŸ ืึท ืคึผืึธืจื˜ ืคึฟืึทืจ ื“ืขื ืงืจืึทื ื˜ ื‘ืึทื ื™ืฆืขืจ, ืึธื‘ืขืจ ืื™ืš ืกืคึผืขืกื™ืคื™ืขื“ ืคึผืจืขื“ืขืคื™ื ืขื“ ืคึผืึธืจืฅ ื•ื•ื™ื™ึทืœ ื–ื™ื™ ืžื•ื–ืŸ ืื•ื™ืš ื–ื™ื™ืŸ ืžื•ืกื™ืฃ ื•ื•ื™ ื˜ืจืึทืกื˜ื™ื“ ืื™ืŸ ื“ื™ ืึทืคึผื™ ืงืึทื ืกืึธื•ืœ.

access_type=ืึธืคืคืœื™ื ืข ืžื™ื˜ืœ ืึทื– ื“ื™ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ืงืขื ืขืŸ ื“ืขืจื”ื™ื™ึทื ื˜ื™ืงืŸ ืึทืŸ ืื•ื™ืกื’ืขื’ืื ื’ืขืŸ ืกื™ืžืขืŸ ืื•ื™ืฃ ื–ื™ืš ืึธืŸ ื‘ืึทื ื™ืฆืขืจ ื™ื ื˜ืขืจืึทืงืฉืึทืŸ ืžื™ื˜ ื“ืขื ื‘ืœืขื˜ืขืจืขืจ,
ืจืขืกืคึผืึธื ืกืข_ื˜ื™ืคึผ = ืงืึธื“ ืฉื˜ืขืœื˜ ื“ืขื ืคึฟืึธืจืžืึทื˜ ืคื•ืŸ ื•ื•ื™ ื“ืขืจ ืงืึธื“ ื•ื•ืขื˜ ื–ื™ื™ืŸ ืื•ืžื’ืขืงืขืจื˜ (ืึท ืจืขืคึฟืขืจืขื ืฅ ืฆื• ื“ื™ ืึทืœื˜ ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ ืื•ืคึฟืŸ, ื•ื•ืขืŸ ื“ืขืจ ื‘ืึทื ื™ืฆืขืจ ืงืึทืคึผื™ื“ ื“ื™ ืงืึธื“ ืคื•ืŸ ื“ืขื ื‘ืœืขื˜ืขืจืขืจ ืื™ืŸ ื“ื™ ืฉืจื™ืคื˜),
ืคืึทืจื ืขื ื™ื ื“ื™ืงื™ื™ืฅ ื“ื™ ืคืึทืจื ืขื ืื•ืŸ ื˜ื™ืคึผ ืคื•ืŸ ืึทืงืกืขืก. ื–ื™ื™ ืžื•ื–ืŸ ื–ื™ื™ืŸ ืืคื’ืขืฉื™ื™ื“ื˜ ื“ื•ืจืš ืกืคึผื™ื™ืกืึทื– ืึธื“ืขืจ% 20 (ืœื•ื™ื˜ URL ืงืึธื“ื™ืจื•ื ื’). ื ืจืฉื™ืžื” ืคื•ืŸ ืึทืงืกืขืก ื’ืขื‘ื™ื˜ืŸ ืžื™ื˜ ื˜ื™ื™ืคึผืก ืงืขื ืขืŸ ื–ื™ื™ืŸ ื’ืขื–ืขืŸ ื“ืึธ: OAuth 2.0 ืกืงืึธืคึผืขืก ืคึฟืึทืจ Google ืึทืคึผื™ืก.

ื ืึธืš ื‘ืืงื•ืžืขืŸ ื“ื™ ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ ืงืึธื“, ื“ื™ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ื•ื•ืขื˜ ืฆื•ืจื™ืงืงื•ืžืขืŸ ืึท ื ืึธืขื ื˜ ืึธื ื–ืึธื’ ืฆื• ื“ืขื ื‘ืœืขื˜ืขืจืขืจ, โ€‹โ€‹ื”ืึทืœื˜ืŸ ืฆื•ื’ืขื”ืขืจื˜ ืื™ืŸ ื“ื™ ืคึผืึธืจื˜ ืื•ืŸ ืฉื™ืงืŸ ืึท POST ื‘ืขื˜ืŸ ืฆื• ื‘ืึทืงื•ืžืขืŸ ื“ืขื ืกื™ืžืขืŸ. ืžื™ืจ ืึธื ื•ื•ื™ื™ึทื–ืŸ ืื™ืŸ ืขืก ื“ื™ ืคืจื™ืขืจ ืกืคึผืขืกื™ืคื™ืขื“ ืฉื™ื™ึทืŸ ืื•ืŸ ืกื•ื“ ืคื•ืŸ ื“ื™ ืงืึทื ืกืึธื•ืœ ืึทืคึผื™, ื“ื™ ืึทื“ืจืขืก ืฆื• ื•ื•ืึธืก ื“ืขืจ ื‘ืึทื ื™ืฆืขืจ ื•ื•ืขื˜ ื–ื™ื™ืŸ ืจื™ื“ืขืจืขืงื˜ื™ื“ ืื•ืŸ ื’ืจืึทื ื˜_ื˜ื™ืคึผืข ืื™ืŸ ืœื•ื™ื˜ ืžื™ื˜ ื“ื™ ืคึผืจืึธื˜ืึธืงืึธืœ ื‘ืึทืฉืจื™ื™ึทื‘ื•ื ื’.

ืื™ืŸ ืขื ื˜ืคืขืจ, ืžื™ืจ ื•ื•ืขืœืŸ ื‘ืึทืงื•ืžืขืŸ ืึทืŸ ืึทืงืกืขืก ืกื™ืžืขืŸ, ื–ื™ื™ืŸ ื’ื™ืœื˜ื™ืงื™ื™ึทื˜ ืฆื™ื™ึทื˜ ืื™ืŸ ืกืขืงื•ื ื“ืขืก, ืื•ืŸ ืึท ืจืขืคืจืขืฉ ืกื™ืžืขืŸ, ืžื™ื˜ ื•ื•ืึธืก ืžื™ืจ ืงืขื ืขืŸ ื“ืขืจื”ื™ื™ึทื ื˜ื™ืงืŸ ื“ื™ ืึทืงืกืขืก ืกื™ืžืขืŸ.

ื“ื™ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ืžื•ื–ืŸ ืงืจืึธื ื˜ืึธืงืขื ืก ืื™ืŸ ืึท ื–ื™ื›ืขืจ ืคึผืœืึทืฅ ืžื™ื˜ ืึท ืœืึทื ื’ ืคึผืึธืœื™ืฆืข ืœืขื‘ืŸ, ืึทื–ื•ื™ ื‘ื™ื– ืžื™ืจ ืึธืคึผืจื•ืคืŸ ื“ื™ ืึทืงืกืขืก ื‘ืืงื•ืžืขืŸ, ื“ื™ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ื•ื•ืขื˜ ื ื™ืฉื˜ ืฆื•ืจื™ืงืงื•ืžืขืŸ ื“ื™ ื“ืขืจืคืจื™ืฉืŸ ื˜ืึธืงืขืŸ. ืื™ืŸ ื“ื™ ืกื•ืฃ, ืื™ืš ืฆื•ื’ืขื’ืขื‘ืŸ ืึท ื‘ืงืฉื” ืฆื• ืึธืคึผืจื•ืคืŸ ื“ื™ ืกื™ืžืขืŸ; ืื•ื™ื‘ ื“ื™ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ืื™ื– ื ื™ืฉื˜ ื”ืฆืœื—ื” ื’ืขืขื ื“ื™ืงื˜ ืื•ืŸ ื“ื™ ื“ืขืจืคืจื™ืฉืŸ ืกื™ืžืขืŸ ืื™ื– ื ื™ืฉื˜ ืื•ืžื’ืขืงืขืจื˜, ืขืก ื•ื•ืขื˜ ืึธื ื”ื™ื™ื‘ืŸ ื“ื™ ืคึผืจืึธืฆืขื“ื•ืจ ื•ื•ื™ื“ืขืจ (ืžื™ืจ ื”ืึธื‘ืŸ ื’ืขื”ืืœื˜ืŸ ืขืก ืึทื ืกื™ื™ืฃ ืฆื• ืงืจืึธื ื˜ืึธืงืขื ืก ืœืึธื•ืงืึทืœื™ ืื•ื™ืฃ ื“ื™ ื•ื•ืึธืงื–ืึทืœ, ืื•ืŸ ืžื™ืจ ื˜ืึธืŸ ื ื™ืฉื˜ ื•ื•ืขืœืŸ ืฆื• ืงืึธืžืคึผืœื™ืฆื™ืจืŸ ื˜ื™ื ื’ื– ืžื™ื˜ ืงืจื™ืคึผื˜ืึธื’ืจืึทืคื™ ืึธื“ืขืจ ืึธืคื˜ ืขืคืขื ืขืŸ ื“ืขื ื‘ืœืขื˜ืขืจืขืจ).

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

ืื™ืŸ ื™ืขื“ืขืจ ื‘ืงืฉื”, ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืฉื™ืงืŸ ืึทืŸ ืื•ื™ื˜ืึธืจื™ื–ืึทื˜ื™ืึธืŸ ื›ืขื“ืขืจ ืžื™ื˜ ื“ื™ ืกื™ืžืขืŸ ื˜ื™ืคึผ ืื•ืŸ ื“ื™ ืึทืงืกืขืก ืกื™ืžืขืŸ ื–ื™ืš. ื“ืขืจื•ื•ื™ื™ึทืœ, ื“ื™ ืกื™ืžืขืŸ ื˜ื™ืคึผ ืื™ื– ืฉื˜ืขื ื“ื™ืง ื˜ืจืขื’ืขืจ. ื•ื•ื™ื™ึทืœ ืžื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืงืึธื ื˜ืจืึธืœื™ืจืŸ ืึทื– ื“ื™ ืกื™ืžืขืŸ ืื™ื– ื ื™ืฉื˜ ืื•ื™ืกื’ืขื’ืื ื’ืขืŸ ืื•ืŸ ื“ืขืจื”ื™ื™ึทื ื˜ื™ืงืŸ ืขืก ื ืึธืš ืึท ืฉืขื” ืคื•ืŸ ื“ืขื ืžืึธืžืขื ื˜ ืขืก ืื™ื– ืืจื•ื™ืก, ืื™ืš ืกืคึผืขืฆื™ืคื™ืฆื™ืจื˜ ืึท ื‘ืงืฉื” ืคึฟืึทืจ ืืŸ ืื ื“ืขืจ ืคึฟื•ื ืงืฆื™ืข ื•ื•ืึธืก ืงืขืจื˜ ืึทืŸ ืึทืงืกืขืก ืกื™ืžืขืŸ. ื“ืขืจ ื–ืขืœื‘ื™ืงืขืจ ืฉื˜ื™ืง ืคื•ืŸ ืงืึธื“ ืื™ื– ืื™ืŸ ื“ื™ ืึธื ื”ื™ื™ื‘ ืคื•ืŸ ื“ื™ ืฉืจื™ืคื˜ ื•ื•ืขืŸ ืื™ืจ ื‘ืึทืงื•ืžืขืŸ ื“ื™ ืขืจืฉื˜ืขืจ ืึทืงืกืขืก ืกื™ืžืขืŸ:

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
}

ื“ื™ E- ื‘ืจื™ื•ื•: $ ืึธื ืคึฟืจืขื’ ื‘ืขื˜ืŸ ื•ื•ืขื˜ ื‘ืขื˜ืŸ ื“ื™ ืึทืคึผื™ ืฆื• ื–ื•ื›ืŸ ืึท ื‘ืึทื ื™ืฆืขืจ ืžื™ื˜ ืคึผื•ื ืงื˜ ื“ืขื E- ื‘ืจื™ื•ื•, ืึทืจื™ื™ึทื ื’ืขืจืขื›ื ื˜ ื™ื™ืœื™ืึทืกื™ื–. ืื™ืจ ืงืขื ื˜ ืื•ื™ืš ื ื•ืฆืŸ ื•ื•ื™ืœื“ืงืึทืจื“: =, :, :{ืคึผืจืขืคื™ืงืก}*.

ืฆื• ืงืจื™ื’ืŸ ื“ืึทื˜ืŸ, ื ื•ืฆืŸ ื“ื™ 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
}

ื“ื™ ืคืึทื ื’ืงืฉืึทื ื– ืคึฟืึทืจ ืึทืคึผื“ื™ื™ื˜ื™ื ื’ ืื•ืŸ ืงืจื™ื™ื™ื˜ื™ื ื’ ืึท ื—ืฉื‘ื•ืŸ ื”ืึธื‘ืŸ ืึท ืขื ืœืขืš ืกื™ื ื˜ืึทืงืก; ื ื™ื˜ ืึทืœืข ื ืึธืš ืคืขืœื“ืขืจ ื–ืขื ืขืŸ ืคืืจืœืื ื’ื˜; ืื™ืŸ ื“ืขืจ ืึธืคึผื˜ื™ื™ืœื•ื ื’ ืžื™ื˜ ื˜ืขืœืขืคืึธืŸ ื ื•ืžืขืจืŸ, ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืกืคึผืขืฆื™ืคื™ืฆื™ืจืŸ ืึท ืžืขื ื’ืข ื•ื•ืึธืก ืงืขื ืขืŸ ืึทื ื˜ื”ืึทืœื˜ืŸ ืึทืจื•ื™ืฃ ืฆื• ืื™ื™ืŸ ืจืขืงืึธืจื“ ืžื™ื˜ ื“ื™ ื ื•ืžืขืจ ืื•ืŸ ื–ื™ื™ืŸ ื˜ื™ืคึผ.

ื›ื“ื™ ื ื™ืฉื˜ ืฆื• ื‘ืืงื•ืžืขืŸ ื ื˜ืขื•ืช ื•ื•ืขืŸ ืžืขืŸ ืœื™ื™ื’ื˜ ื ื‘ืื ื•ืฆืขืจ ืฆื• ื ื’ืจื•ืคืข, ืงืขื ืขืŸ ืžื™ืจ ืงื•ื“ื ื˜ืฉืขืง ืฆื™ ืขืจ ืื™ื– ืฉื•ื™ืŸ ื ืžื™ื˜ื’ืœื™ื“ ืคื•ืŸ ื“ืขืจ ื’ืจื•ืคืข ื“ื•ืจืš ื‘ืืงื•ืžืขืŸ ื ืœื™ืกื˜ืข ืคื•ืŸ โ€‹โ€‹ื’ืจื•ืคืข ืžื™ื˜ื’ืœื™ื“ืขืจ ืื“ืขืจ ืงืืžืคืื–ื™ืฆื™ืข ืคื•ื ืขื ื‘ืื ื•ืฆืขืจ ืืœื™ื™ืŸ.

ืึธื ืคืจืขื’ ื“ื™ ื’ืจื•ืคึผืข ืžื™ื˜ื’ืœื™ื“ืขืจืฉืึทืคื˜ ืคื•ืŸ ืึท ืกืคึผืขืฆื™ืคื™ืฉ ื‘ืึทื ื™ืฆืขืจ ื•ื•ืขื˜ ื ื™ืฉื˜ ื–ื™ื™ืŸ ืจืขืงื•ืจืกื™ื•ื• ืื•ืŸ ื•ื•ืขื˜ ื‘ืœื•ื™ื– ื•ื•ื™ื™ึทื–ืŸ ื“ื™ืจืขืงื˜ ืžื™ื˜ื’ืœื™ื“ืขืจืฉืึทืคื˜. ืึทืจื™ื™ึทื ื’ืขืจืขื›ื ื˜ ืึท ื‘ืึทื ื™ืฆืขืจ ืื™ืŸ ืึท ืคืึธื˜ืขืจ ื’ืจื•ืคึผืข ื•ื•ืึธืก ื”ืื˜ ืฉื•ื™ืŸ ืึท ืงื™ื ื“ ื’ืจื•ืคึผืข ื•ื•ืึธืก ื“ืขืจ ื‘ืึทื ื™ืฆืขืจ ืื™ื– ืึท ืžื™ื˜ื’ืœื™ื“ ืคื•ืŸ ื•ื•ืขื˜ ื–ื™ื™ืŸ ื’ืขืจืึธื˜ืŸ.

ืกืึธืฃ

ืึทืœืข ื•ื•ืึธืก ื‘ืœื™ื™ื‘ื˜ ืื™ื– ืฆื• ืฉื™ืงืŸ ื“ืขื ื‘ืึทื ื™ืฆืขืจ ื“ื™ ืคึผืึทืจืึธืœ ืคึฟืึทืจ ื“ื™ ื ื™ื™ึทืข ื—ืฉื‘ื•ืŸ. ืžื™ืจ ื˜ืึธืŸ ื“ืึธืก ื“ื•ืจืš SMS, ืื•ืŸ ืฉื™ืงืŸ ืึทืœื’ืขืžื™ื™ื ืข ืื™ื ืคึฟืึธืจืžืึทืฆื™ืข ืžื™ื˜ ืื™ื ืกื˜ืจื•ืงืฆื™ืขืก ืื•ืŸ ืœืึธื’ื™ืŸ ืฆื• ืึท ืคึผืขืจื–ืขื ืœืขืš ื‘ืœื™ืฆืคึผืึธืกื˜, ื•ื•ืึธืก, ืฆื•ื–ืึทืžืขืŸ ืžื™ื˜ ืึท ื˜ืขืœืขืคืึธืŸ ื ื•ืžืขืจ, ืื™ื– ืฆื•ื’ืขืฉื˜ืขืœื˜ ื“ื•ืจืš ื“ื™ ืจืึทืงืจื•ื˜ืžืึทื ื˜ ืึธืคึผื˜ื™ื™ืœื•ื ื’. ื•ื•ื™ ืึทืŸ ืึธืœื˜ืขืจื ืึทื˜ื™ื•ื•, ืื™ืจ ืงืขื ืขืŸ ืฉืคึผืึธืจืŸ ื’ืขืœื˜ ืื•ืŸ ืฉื™ืงืŸ ื“ื™ื™ืŸ ืคึผืึทืจืึธืœ ืฆื• ืึท ื’ืขื”ื™ื™ื ื˜ืขืœืขื’ืจืึทื ืฉืžื•ืขืกืŸ, ื•ื•ืึธืก ืงืขื ืขืŸ ืื•ื™ืš ื–ื™ื™ืŸ ื’ืขื”ืืœื˜ืŸ ื“ื™ ืจื’ืข ืคืึทืงื˜ืึธืจ (ืžืึทืงื‘ืึธืึธืงืก ื•ื•ืขื˜ ื–ื™ื™ืŸ ืึท ื•ื™ืกื ืขื).

ื“ืื ืง ืื™ืจ ืคึฟืึทืจ ืœื™ื™ืขื ืขืŸ ื‘ื™ื– ื“ื™ ืกื•ืฃ. ืื™ืš ื•ื•ืขืœ ื–ื™ื™ืŸ ืฆื•ืคืจื™ื“ืŸ ืฆื• ื–ืขืŸ ืคึฟื™ืจืœื™ื™ื’ืŸ ืฆื• ืคึฟืึทืจื‘ืขืกืขืจืŸ ื“ืขื ื ื•ืกื— ืคื•ืŸ ืฉืจื™ื™ื‘ืŸ ืึทืจื˜ื™ืงืœืขืŸ ืื•ืŸ ื•ื•ื™ื ื˜ืฉืŸ ืื™ืจ ืฆื• ื›ืึทืคึผืŸ ื•ื•ื™ื™ื ื™ืงืขืจืข ืขืจืจืึธืจืก ื•ื•ืขืŸ ืฉืจื™ื™ื‘ืŸ ืกืงืจื™ืคึผืก =)

ืจืฉื™ืžื” ืคื•ืŸ ืœื™ื ืงืก ื•ื•ืึธืก ืงืขืŸ ื–ื™ื™ืŸ ื˜ื™ืžืึทื˜ื™ืงืœื™ ื ื•ืฆื™ืง ืึธื“ืขืจ ืคืฉื•ื˜ ืขื ื˜ืคึฟืขืจืŸ ืคึฟืจืื’ืŸ:

ืžืงื•ืจ: www.habr.com

ืœื™ื™ื’ืŸ ืึท ื‘ืึทืžืขืจืงื•ื ื’