Google-แƒ˜แƒก แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ PowerShell-แƒ˜แƒ“แƒแƒœ API-แƒ˜แƒก แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒ˜แƒ—

Hi!

แƒ”แƒก แƒกแƒขแƒแƒขแƒ˜แƒ แƒแƒฆแƒฌแƒ”แƒ แƒก PowerShell-แƒ˜แƒก แƒฃแƒ แƒ—แƒ˜แƒ”แƒ แƒ—แƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒแƒก Google API-แƒกแƒ—แƒแƒœ G Suite แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒœแƒ˜แƒžแƒฃแƒšแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.

แƒฉแƒ•แƒ”แƒœ แƒ•แƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ— แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒจแƒ˜แƒ“แƒ แƒ“แƒ แƒฆแƒ แƒฃแƒ‘แƒšแƒแƒ•แƒแƒœ แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒก แƒแƒ แƒ’แƒแƒœแƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒแƒกแƒจแƒขแƒแƒ‘แƒ˜แƒ—. แƒฃแƒ›แƒ”แƒขแƒ”แƒกแƒฌแƒ˜แƒšแƒแƒ“, แƒ›แƒแƒ—แƒจแƒ˜ แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ แƒ›แƒแƒ“แƒ˜แƒก Google-แƒ–แƒ” แƒแƒœ Active Directory-แƒ–แƒ”, แƒ แƒแƒ›แƒ”แƒšแƒ—แƒ แƒจแƒแƒ แƒ˜แƒกแƒแƒช แƒฉแƒ•แƒ”แƒœ แƒ•แƒ”แƒ  แƒ•แƒ˜แƒœแƒแƒฎแƒแƒ•แƒ— แƒ แƒ”แƒžแƒšแƒ˜แƒ™แƒแƒก; แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒแƒ“, แƒ แƒแƒ“แƒ”แƒกแƒแƒช แƒแƒฎแƒแƒšแƒ˜ แƒ—แƒแƒœแƒแƒ›แƒจแƒ แƒแƒ›แƒ”แƒšแƒ˜ แƒ›แƒ˜แƒ“แƒ˜แƒก, แƒ—แƒฅแƒ•แƒ”แƒœ แƒฃแƒœแƒ“แƒ แƒจแƒ”แƒฅแƒ›แƒœแƒแƒ—/แƒฉแƒแƒ แƒ—แƒแƒ— แƒแƒœแƒ’แƒแƒ แƒ˜แƒจแƒ˜ แƒแƒ› แƒแƒ  แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒแƒจแƒ˜. แƒžแƒ แƒแƒชแƒ”แƒกแƒ˜แƒก แƒแƒ•แƒขแƒแƒ›แƒแƒขแƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ’แƒแƒ“แƒแƒ•แƒฌแƒงแƒ•แƒ˜แƒขแƒ”แƒ— แƒ“แƒแƒ’แƒ•แƒ”แƒฌแƒ”แƒ แƒ แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒ’แƒ แƒแƒ•แƒ”แƒ‘แƒก แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒแƒก แƒ“แƒ แƒแƒ’แƒ–แƒแƒ•แƒœแƒ˜แƒก แƒแƒ แƒ˜แƒ•แƒ” แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒก.

แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ

แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ“แƒ’แƒ”แƒœแƒ˜แƒกแƒแƒก แƒ’แƒแƒ“แƒแƒ•แƒฌแƒงแƒ•แƒ˜แƒขแƒ”แƒ— แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ”แƒœแƒแƒ— แƒ แƒ”แƒแƒšแƒฃแƒ แƒ˜ แƒแƒ“แƒ›แƒ˜แƒœแƒ˜แƒกแƒขแƒ แƒแƒขแƒแƒ แƒ”แƒ‘แƒ˜ แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒช แƒแƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ”แƒ‘แƒก แƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒแƒœแƒแƒšแƒ˜แƒ–แƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒ˜แƒ—แƒ˜ แƒแƒœ แƒ’แƒแƒœแƒ–แƒ แƒแƒฎ แƒ›แƒแƒกแƒ˜แƒฃแƒ แƒ˜ แƒชแƒ•แƒšแƒ˜แƒšแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜.

Google API แƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒก OAuth 2.0 แƒžแƒ แƒแƒขแƒแƒ™แƒแƒšแƒก แƒแƒ•แƒ—แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒกแƒ แƒ“แƒ แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒ”แƒ‘แƒ˜ แƒ“แƒ แƒฃแƒคแƒ แƒ แƒ“แƒ”แƒขแƒแƒšแƒฃแƒ แƒ˜ แƒแƒฆแƒฌแƒ”แƒ แƒ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ˜แƒฎแƒ˜แƒšแƒแƒ— แƒแƒฅ: OAuth 2.0-แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ Google API-แƒ”แƒ‘แƒ–แƒ” แƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.

แƒ›แƒ” แƒแƒ•แƒ˜แƒ แƒฉแƒ˜แƒ” แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒ“แƒ”แƒกแƒ™แƒขแƒแƒžแƒ˜แƒก แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒจแƒ˜ แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. แƒแƒกแƒ”แƒ•แƒ” แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ˜แƒก แƒแƒœแƒ’แƒแƒ แƒ˜แƒจแƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒ•แƒแƒ แƒ˜แƒแƒœแƒขแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒ  แƒกแƒแƒญแƒ˜แƒ แƒแƒ”แƒ‘แƒก แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ˜แƒกแƒ’แƒแƒœ แƒ–แƒ”แƒ“แƒ›แƒ”แƒข แƒ›แƒแƒซแƒ แƒแƒแƒ‘แƒแƒก.

แƒฅแƒ•แƒ”แƒ›แƒแƒ— แƒ›แƒแƒงแƒ•แƒแƒœแƒ˜แƒšแƒ˜ แƒกแƒฃแƒ แƒแƒ—แƒ˜ แƒแƒ แƒ˜แƒก แƒแƒ แƒฉแƒ”แƒฃแƒšแƒ˜ แƒกแƒชแƒ”แƒœแƒแƒ แƒ˜แƒก แƒกแƒฅแƒ”แƒ›แƒแƒขแƒฃแƒ แƒ˜ แƒแƒฆแƒฌแƒ”แƒ แƒ Google-แƒ˜แƒก แƒ’แƒ•แƒ”แƒ แƒ“แƒ˜แƒ“แƒแƒœ.

Google-แƒ˜แƒก แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ PowerShell-แƒ˜แƒ“แƒแƒœ API-แƒ˜แƒก แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒ˜แƒ—

  1. แƒžแƒ˜แƒ แƒ•แƒ”แƒš แƒ แƒ˜แƒ’แƒจแƒ˜, แƒฉแƒ•แƒ”แƒœ แƒ•แƒฃแƒ’แƒ–แƒแƒ•แƒœแƒ˜แƒ— แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒ”แƒšแƒก Google แƒแƒœแƒ’แƒแƒ แƒ˜แƒจแƒ˜แƒก แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒ’แƒ•แƒ”แƒ แƒ“แƒ–แƒ”, แƒกแƒแƒ“แƒแƒช แƒ›แƒ˜แƒ—แƒ˜แƒ—แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ GET แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒ˜:
    • แƒ’แƒแƒœแƒแƒชแƒฎแƒแƒ“แƒ˜แƒก ID
    • แƒกแƒคแƒ”แƒ แƒแƒ”แƒ‘แƒ˜, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ–แƒ”แƒช แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒแƒก แƒกแƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ แƒฌแƒ•แƒ“แƒแƒ›แƒ
    • แƒ›แƒ˜แƒกแƒแƒ›แƒแƒ แƒ—แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ–แƒ”แƒช แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒ”แƒšแƒ˜ แƒ’แƒแƒ“แƒแƒ›แƒ˜แƒกแƒแƒ›แƒแƒ แƒ—แƒ“แƒ”แƒ‘แƒ แƒžแƒ แƒแƒชแƒ”แƒ“แƒฃแƒ แƒ˜แƒก แƒ“แƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’
    • แƒ แƒแƒ’แƒแƒ  แƒ’แƒแƒœแƒ•แƒแƒแƒฎแƒšแƒ”แƒ‘แƒ— แƒŸแƒ”แƒขแƒแƒœแƒก
    • แฒฃแƒกแƒแƒคแƒ แƒ—แƒฎแƒแƒ”แƒ‘แƒ˜แƒก แƒ™แƒแƒ“แƒ˜
    • แƒ’แƒแƒ“แƒแƒ›แƒแƒฌแƒ›แƒ”แƒ‘แƒ˜แƒก แƒ™แƒแƒ“แƒ˜แƒก แƒ’แƒแƒ“แƒแƒชแƒ”แƒ›แƒ˜แƒก แƒคแƒแƒ แƒ›แƒแƒขแƒ˜

  2. แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒ“แƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒ”แƒšแƒ˜ แƒ’แƒแƒ“แƒแƒ›แƒ˜แƒกแƒแƒ›แƒแƒ แƒ—แƒ“แƒ”แƒ‘แƒ แƒžแƒ˜แƒ แƒ•แƒ”แƒš แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒจแƒ˜ แƒ›แƒ˜แƒ—แƒ˜แƒ—แƒ”แƒ‘แƒฃแƒš แƒ’แƒ•แƒ”แƒ แƒ“แƒ–แƒ”, แƒจแƒ”แƒชแƒ“แƒแƒ›แƒ˜แƒ— แƒแƒœ แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒ™แƒแƒ“แƒ˜แƒ—, แƒ แƒแƒ›แƒ”แƒšแƒกแƒแƒช แƒ’แƒแƒ“แƒแƒกแƒชแƒ”แƒ›แƒก GET แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒ˜.
  3. แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒแƒ› (แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ›แƒ) แƒฃแƒœแƒ“แƒ แƒ›แƒ˜แƒ˜แƒฆแƒแƒก แƒ”แƒก แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒ˜ แƒ“แƒ, แƒ—แƒฃ แƒ™แƒแƒ“แƒ˜ แƒ›แƒ˜แƒ˜แƒฆแƒ, แƒ’แƒแƒแƒ™แƒ”แƒ—แƒแƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ แƒขแƒแƒ™แƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒกแƒแƒฆแƒ”แƒ‘แƒแƒ“
  4. แƒ—แƒฃ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ แƒกแƒฌแƒแƒ แƒ˜แƒ, Google API แƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒก:
    • แƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒก แƒŸแƒ”แƒขแƒแƒœแƒ˜, แƒ แƒแƒ›แƒšแƒ˜แƒ—แƒแƒช แƒจแƒ”แƒ’แƒ•แƒ˜แƒซแƒšแƒ˜แƒ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒ
    • แƒแƒ› แƒœแƒ˜แƒจแƒœแƒ˜แƒก แƒ›แƒแƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒ˜แƒก แƒ•แƒแƒ“แƒ
    • แƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒก แƒŸแƒ”แƒขแƒแƒœแƒ˜แƒก แƒ’แƒแƒœแƒแƒฎแƒšแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒกแƒแƒญแƒ˜แƒ แƒแƒ แƒ’แƒแƒœแƒแƒฎแƒšแƒ”แƒ‘แƒ˜แƒก แƒŸแƒ”แƒขแƒแƒœแƒ˜.

แƒฏแƒ”แƒ  แƒฃแƒœแƒ“แƒ แƒ’แƒแƒ“แƒแƒฎแƒ•แƒ˜แƒ“แƒ”แƒ— Google API แƒ™แƒแƒœแƒกแƒแƒšแƒ–แƒ”: แƒ แƒฌแƒ›แƒฃแƒœแƒ”แƒ‘แƒแƒ—แƒ แƒกแƒ˜แƒ’แƒ”แƒšแƒ”แƒ‘แƒ˜ - Google API Console, แƒแƒ˜แƒ แƒฉแƒ˜แƒ”แƒ— แƒกแƒแƒกแƒฃแƒ แƒ•แƒ”แƒšแƒ˜ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ แƒ“แƒ Credentials แƒ’แƒแƒœแƒงแƒแƒคแƒ˜แƒšแƒ”แƒ‘แƒแƒจแƒ˜ แƒจแƒ”แƒฅแƒ›แƒ”แƒœแƒ˜แƒ— แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒ˜แƒก OAuth แƒ˜แƒ“แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒแƒ แƒ˜. แƒ˜แƒฅ (แƒแƒœ แƒ›แƒแƒ’แƒ•แƒ˜แƒแƒœแƒ”แƒ‘แƒ˜แƒ—, แƒจแƒ”แƒฅแƒ›แƒœแƒ˜แƒšแƒ˜ แƒ˜แƒ“แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒแƒ แƒ˜แƒก แƒ—แƒ•แƒ˜แƒกแƒ”แƒ‘แƒ”แƒ‘แƒจแƒ˜) แƒ—แƒฅแƒ•แƒ”แƒœ แƒฃแƒœแƒ“แƒ แƒ›แƒ˜แƒฃแƒ—แƒ˜แƒ—แƒแƒ— แƒ›แƒ˜แƒกแƒแƒ›แƒแƒ แƒ—แƒ”แƒ‘แƒ˜, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ–แƒ”แƒช แƒœแƒ”แƒ‘แƒแƒ“แƒแƒ แƒ—แƒฃแƒšแƒ˜แƒ แƒ’แƒแƒ“แƒแƒ›แƒ˜แƒกแƒแƒ›แƒแƒ แƒ—แƒ”แƒ‘แƒ. แƒฉแƒ•แƒ”แƒœแƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, แƒ”แƒก แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒšแƒแƒ™แƒแƒšแƒฐแƒแƒกแƒขแƒ˜แƒก แƒฉแƒแƒœแƒแƒฌแƒ”แƒ แƒ˜ แƒกแƒฎแƒ•แƒแƒ“แƒแƒกแƒฎแƒ•แƒ แƒžแƒแƒ แƒขแƒ˜แƒ— (แƒ˜แƒฎ. แƒฅแƒ•แƒ”แƒ›แƒแƒ—).

แƒ˜แƒ›แƒ˜แƒกแƒแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ› แƒฃแƒคแƒ แƒ แƒ›แƒแƒกแƒแƒฎแƒ”แƒ แƒฎแƒ”แƒ‘แƒ”แƒšแƒ˜ แƒ˜แƒงแƒแƒก แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜แƒก แƒแƒšแƒ’แƒแƒ แƒ˜แƒ—แƒ›แƒ˜แƒก แƒฌแƒแƒ™แƒ˜แƒ—แƒฎแƒ•แƒ, แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒแƒฉแƒ•แƒ”แƒœแƒแƒ— แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ แƒœแƒแƒ‘แƒ˜แƒฏแƒ”แƒ‘แƒ˜ แƒชแƒแƒšแƒ™แƒ” แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒจแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ“แƒแƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒก Access-แƒก แƒ“แƒ แƒ’แƒแƒœแƒแƒแƒฎแƒšแƒ”แƒ‘แƒก แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒขแƒแƒ™แƒ”แƒœแƒ”แƒ‘แƒก:

$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

แƒฉแƒ•แƒ”แƒœ แƒ“แƒแƒ•แƒแƒงแƒ”แƒœแƒ”แƒ— แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒ˜แƒก ID แƒ“แƒ แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒ˜แƒก แƒกแƒแƒ˜แƒ“แƒฃแƒ›แƒšแƒ, แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒฃแƒšแƒ˜ OAuth แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒ˜แƒก แƒ˜แƒ“แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒแƒ แƒ˜แƒก แƒ—แƒ•แƒ˜แƒกแƒ”แƒ‘แƒ”แƒ‘แƒจแƒ˜, แƒฎแƒแƒšแƒ แƒ™แƒแƒ“แƒ˜แƒก แƒ“แƒแƒ›แƒแƒ“แƒแƒกแƒขแƒฃแƒ แƒ”แƒ‘แƒ”แƒšแƒ˜ แƒแƒ แƒ˜แƒก 43-แƒ“แƒแƒœ 128-แƒ›แƒ“แƒ” แƒกแƒ˜แƒ›แƒ‘แƒแƒšแƒแƒกแƒ’แƒแƒœ แƒจแƒ”แƒ›แƒ“แƒ’แƒแƒ แƒ˜ แƒกแƒขแƒ แƒ˜แƒฅแƒแƒœแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒ˜แƒ— แƒฃแƒœแƒ“แƒ แƒ˜แƒงแƒแƒก แƒ’แƒ”แƒœแƒ”แƒ แƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒแƒ แƒแƒ แƒ”แƒ–แƒ”แƒ แƒ•แƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒกแƒ˜แƒ›แƒ‘แƒแƒšแƒแƒ”แƒ‘แƒ˜แƒ“แƒแƒœ: [AZ] / [az] / [0-9 ] / "-" / "." / "_" / "~".

แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ”แƒก แƒ™แƒแƒ“แƒ˜ แƒ™แƒ•แƒšแƒแƒ• แƒ’แƒแƒ“แƒแƒ”แƒชแƒ”แƒ›แƒ. แƒ˜แƒก แƒ’แƒแƒ›แƒแƒ แƒ˜แƒชแƒฎแƒแƒ•แƒก แƒ“แƒแƒฃแƒชแƒ•แƒ”แƒšแƒแƒ‘แƒแƒก, แƒ แƒแƒ›แƒšแƒ˜แƒก แƒ“แƒ แƒแƒกแƒแƒช แƒ—แƒแƒ•แƒ“แƒแƒ›แƒกแƒฎแƒ›แƒ”แƒšแƒก แƒจแƒ”แƒฃแƒซแƒšแƒ˜แƒ แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ˜แƒก แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ’แƒแƒ“แƒแƒ›แƒ˜แƒกแƒแƒ›แƒแƒ แƒ—แƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒฎแƒ˜แƒ— แƒ“แƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒžแƒแƒกแƒฃแƒฎแƒ˜แƒก แƒฉแƒแƒญแƒ แƒ.
แƒ—แƒฅแƒ•แƒ”แƒœ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒแƒ— แƒ™แƒแƒ“แƒ˜แƒก แƒจแƒ”แƒ›แƒ›แƒแƒฌแƒ›แƒ”แƒ‘แƒ”แƒšแƒ˜ แƒ›แƒ˜แƒ›แƒ“แƒ˜แƒœแƒแƒ แƒ” แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒจแƒ˜ แƒ›แƒ™แƒแƒคแƒ˜แƒ แƒขแƒ”แƒฅแƒกแƒขแƒ˜แƒ— (แƒ แƒแƒช แƒ›แƒแƒก แƒฃแƒแƒ–แƒ แƒ แƒฎแƒ“แƒ˜แƒก - แƒ”แƒก แƒจแƒ”แƒกแƒแƒคแƒ”แƒ แƒ˜แƒกแƒ˜แƒ แƒ›แƒฎแƒแƒšแƒแƒ“ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒกแƒแƒช แƒแƒ  แƒฃแƒญแƒ”แƒ แƒ”แƒœ แƒ›แƒฎแƒแƒ แƒก SHA256), แƒแƒœ แƒฐแƒแƒจแƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ˜แƒ— SHA256 แƒแƒšแƒ’แƒแƒ แƒ˜แƒ—แƒ›แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒฃแƒœแƒ“แƒ แƒ˜แƒงแƒแƒก แƒ™แƒแƒ“แƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ BASE64Url-แƒจแƒ˜ (แƒ’แƒแƒœแƒกแƒฎแƒ•แƒแƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜ Base64-แƒ“แƒแƒœ แƒแƒ แƒ˜ แƒชแƒฎแƒ แƒ˜แƒšแƒ˜แƒก แƒกแƒ˜แƒ›แƒ‘แƒแƒšแƒแƒ—แƒ˜) แƒ“แƒ แƒแƒ›แƒแƒ˜แƒฆแƒ”แƒ— แƒกแƒ˜แƒ›แƒ‘แƒแƒšแƒแƒ”แƒ‘แƒ˜แƒก แƒฎแƒแƒ–แƒ˜แƒก แƒ“แƒแƒ‘แƒแƒšแƒแƒ”แƒ‘แƒ”แƒ‘แƒ˜: =.

แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜, แƒฉแƒ•แƒ”แƒœ แƒฃแƒœแƒ“แƒ แƒ“แƒแƒ•แƒ˜แƒฌแƒงแƒแƒ— http-แƒ˜แƒก แƒ›แƒแƒกแƒ›แƒ”แƒœแƒ แƒแƒ“แƒ’แƒ˜แƒšแƒแƒ‘แƒ แƒ˜แƒ• แƒแƒžแƒแƒ แƒแƒขแƒ–แƒ”, แƒ แƒแƒ—แƒ แƒ›แƒ˜แƒ•แƒ˜แƒฆแƒแƒ— แƒžแƒแƒกแƒฃแƒฎแƒ˜ แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ“แƒแƒ‘แƒ แƒฃแƒœแƒ“แƒ”แƒ‘แƒ แƒ’แƒแƒ“แƒแƒ›แƒ˜แƒกแƒแƒ›แƒแƒ แƒ—แƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒฎแƒ˜แƒ—.

แƒแƒ“แƒ›แƒ˜แƒœแƒ˜แƒกแƒขแƒ แƒแƒชแƒ˜แƒฃแƒšแƒ˜ แƒ“แƒแƒ•แƒแƒšแƒ”แƒ‘แƒ”แƒ‘แƒ˜ แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒกแƒžแƒ”แƒชแƒ˜แƒแƒšแƒฃแƒ  แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ–แƒ”, แƒฉแƒ•แƒ”แƒœ แƒแƒ  แƒ’แƒแƒ›แƒแƒ•แƒ แƒ˜แƒชแƒฎแƒแƒ•แƒ— แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒšแƒแƒ‘แƒแƒก, แƒ แƒแƒ› แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒแƒ“แƒ›แƒ˜แƒœแƒ˜แƒกแƒขแƒ แƒแƒขแƒแƒ แƒ›แƒ แƒ”แƒ แƒ—แƒ“แƒ แƒแƒฃแƒšแƒแƒ“ แƒ’แƒแƒฃแƒจแƒ•แƒแƒก แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜, แƒแƒ›แƒ˜แƒขแƒแƒ› แƒ˜แƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒ˜แƒ— แƒจแƒ”แƒแƒ แƒฉแƒ”แƒ•แƒก แƒžแƒแƒ แƒขแƒก แƒ›แƒ˜แƒ›แƒ“แƒ˜แƒœแƒแƒ แƒ” แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ›แƒ” แƒ›แƒ˜แƒ•แƒฃแƒ—แƒ˜แƒ—แƒ” แƒฌแƒ˜แƒœแƒแƒกแƒฌแƒแƒ  แƒ’แƒแƒœแƒกแƒแƒ–แƒฆแƒ•แƒ แƒฃแƒšแƒ˜ แƒžแƒแƒ แƒขแƒ”แƒ‘แƒ˜, แƒ แƒแƒ“แƒ’แƒแƒœ แƒ˜แƒกแƒ˜แƒœแƒ˜ แƒแƒกแƒ”แƒ•แƒ” แƒฃแƒœแƒ“แƒ แƒ“แƒแƒ”แƒ›แƒแƒขแƒแƒก แƒ แƒแƒ’แƒแƒ แƒช แƒกแƒแƒœแƒ“แƒ API แƒ™แƒแƒœแƒกแƒแƒšแƒจแƒ˜.

แƒฌแƒ•แƒ“แƒแƒ›แƒ_แƒขแƒ˜แƒžแƒ˜=แƒฎแƒแƒ–แƒ’แƒแƒ แƒ”แƒจแƒ” แƒœแƒ˜แƒจแƒœแƒแƒ•แƒก, แƒ แƒแƒ› แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒแƒก แƒจแƒ”แƒฃแƒซแƒšแƒ˜แƒ แƒ’แƒแƒœแƒแƒแƒฎแƒšแƒแƒก แƒ•แƒแƒ“แƒแƒ’แƒแƒกแƒฃแƒšแƒ˜ แƒŸแƒ”แƒขแƒแƒœแƒ˜ แƒ“แƒแƒ›แƒแƒฃแƒ™แƒ˜แƒ“แƒ”แƒ‘แƒšแƒแƒ“ แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ˜แƒก แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒ—แƒแƒœ แƒฃแƒ แƒ—แƒ˜แƒ”แƒ แƒ—แƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”,
แƒžแƒแƒกแƒฃแƒฎแƒ˜_แƒขแƒ˜แƒžแƒ˜=แƒ™แƒแƒ“แƒ˜ แƒแƒ“แƒ’แƒ”แƒœแƒก แƒ™แƒแƒ“แƒ˜แƒก แƒ“แƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒ˜แƒก แƒคแƒแƒ แƒ›แƒแƒขแƒก (แƒ›แƒ˜แƒœแƒ˜แƒจแƒœแƒ”แƒ‘แƒ แƒซแƒ•แƒ”แƒšแƒ˜ แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒ”แƒ—แƒแƒ“แƒ–แƒ”, แƒ แƒแƒ“แƒ”แƒกแƒแƒช แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒ”แƒšแƒ›แƒ แƒ“แƒแƒแƒ™แƒแƒžแƒ˜แƒ แƒ แƒ™แƒแƒ“แƒ˜ แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒ˜แƒ“แƒแƒœ แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒจแƒ˜),
แƒคแƒแƒ แƒ’แƒšแƒ”แƒ‘แƒจแƒ˜ แƒ›แƒ˜แƒฃแƒ—แƒ˜แƒ—แƒ”แƒ‘แƒก แƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒก แƒคแƒแƒ แƒ’แƒšแƒ”แƒ‘แƒกแƒ แƒ“แƒ แƒขแƒ˜แƒžแƒ–แƒ”. แƒ˜แƒกแƒ˜แƒœแƒ˜ แƒ’แƒแƒ›แƒแƒงแƒแƒคแƒ˜แƒšแƒ˜ แƒฃแƒœแƒ“แƒ แƒ˜แƒงแƒแƒก แƒ˜แƒœแƒขแƒ”แƒ แƒ•แƒแƒšแƒ˜แƒ— แƒแƒœ %20 (URL แƒ™แƒแƒ“แƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒฎแƒ”แƒ“แƒ•แƒ˜แƒ—). แƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒก แƒ–แƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒ แƒขแƒ˜แƒžแƒ”แƒ‘แƒ˜แƒ— แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ˜แƒฎแƒ˜แƒšแƒแƒ— แƒแƒฅ: OAuth 2.0 Scopes Google API-แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.

แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒ™แƒแƒ“แƒ˜แƒก แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒก แƒฃแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒก แƒแƒฎแƒšแƒ แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒแƒก, แƒจแƒ”แƒฌแƒงแƒ•แƒ”แƒขแƒก แƒžแƒแƒ แƒขแƒ–แƒ” แƒ›แƒแƒกแƒ›แƒ”แƒœแƒแƒก แƒ“แƒ แƒแƒ’แƒ–แƒแƒ•แƒœแƒ˜แƒก POST แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒก แƒขแƒแƒ™แƒ”แƒœแƒ˜แƒก แƒ›แƒ˜แƒกแƒแƒฆแƒ”แƒ‘แƒแƒ“. แƒฉแƒ•แƒ”แƒœ แƒแƒฆแƒ•แƒœแƒ˜แƒจแƒœแƒแƒ•แƒ— แƒ›แƒแƒกแƒจแƒ˜ แƒแƒ“แƒ แƒ” แƒ›แƒ˜แƒ—แƒ˜แƒ—แƒ”แƒ‘แƒฃแƒš ID-แƒก แƒ“แƒ แƒกแƒแƒ˜แƒ“แƒฃแƒ›แƒšแƒแƒก แƒ™แƒแƒœแƒกแƒแƒšแƒ˜แƒก API-แƒ“แƒแƒœ, แƒ›แƒ˜แƒกแƒแƒ›แƒแƒ แƒ—แƒ–แƒ”, แƒ แƒแƒ›แƒ”แƒšแƒ–แƒ”แƒช แƒ’แƒแƒ“แƒแƒ›แƒ˜แƒกแƒแƒ›แƒแƒ แƒ—แƒ“แƒ”แƒ‘แƒ แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒ”แƒšแƒ˜ แƒ“แƒ แƒ’แƒ แƒแƒœแƒขแƒ˜แƒก_แƒขแƒ˜แƒžแƒ˜ แƒžแƒ แƒแƒขแƒแƒ™แƒแƒšแƒ˜แƒก แƒกแƒžแƒ”แƒชแƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒแƒ“.

แƒกแƒแƒžแƒแƒกแƒฃแƒฎแƒแƒ“, แƒฉแƒ•แƒ”แƒœ แƒ›แƒ˜แƒ•แƒ˜แƒฆแƒ”แƒ‘แƒ— แƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒก แƒŸแƒ”แƒขแƒแƒœแƒก, แƒ›แƒ˜แƒกแƒ˜ แƒ›แƒแƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒ˜แƒก แƒ•แƒแƒ“แƒแƒก แƒฌแƒแƒ›แƒ”แƒ‘แƒจแƒ˜ แƒ“แƒ แƒ’แƒแƒœแƒแƒฎแƒšแƒ”แƒ‘แƒ˜แƒก แƒŸแƒ”แƒขแƒแƒœแƒก, แƒ แƒแƒ›แƒšแƒ˜แƒ—แƒแƒช แƒจแƒ”แƒ’แƒ•แƒ˜แƒซแƒšแƒ˜แƒ แƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒก แƒขแƒแƒ™แƒ”แƒœแƒ˜แƒก แƒ’แƒแƒœแƒแƒฎแƒšแƒ”แƒ‘แƒ.

แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒแƒ› แƒฃแƒœแƒ“แƒ แƒจแƒ”แƒ˜แƒœแƒแƒฎแƒแƒก แƒขแƒแƒ™แƒ”แƒœแƒ”แƒ‘แƒ˜ แƒฃแƒกแƒแƒคแƒ แƒ—แƒฎแƒ แƒแƒ“แƒ’แƒ˜แƒšแƒแƒก แƒฎแƒแƒœแƒ’แƒ แƒซแƒšแƒ˜แƒ•แƒ˜ แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ˜แƒก แƒ•แƒแƒ“แƒ˜แƒ—, แƒแƒกแƒ” แƒ แƒแƒ›, แƒกแƒแƒœแƒแƒ› แƒฉแƒ•แƒ”แƒœ แƒแƒ  แƒ’แƒแƒ•แƒแƒฃแƒฅแƒ›แƒ”แƒ‘แƒ— แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒฃแƒš แƒฌแƒ•แƒ“แƒแƒ›แƒแƒก, แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ แƒแƒ  แƒ“แƒแƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒก แƒ’แƒแƒœแƒแƒฎแƒšแƒ”แƒ‘แƒ˜แƒก แƒŸแƒ”แƒขแƒแƒœแƒก. แƒ“แƒแƒกแƒแƒกแƒ แƒฃแƒšแƒก, แƒ›แƒ” แƒ“แƒแƒ•แƒแƒ›แƒแƒขแƒ” แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ แƒขแƒแƒ™แƒ”แƒœแƒ˜แƒก แƒ’แƒแƒฃแƒฅแƒ›แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘; แƒ—แƒฃ แƒ’แƒแƒœแƒแƒชแƒฎแƒแƒ“แƒ˜ แƒฌแƒแƒ แƒ›แƒแƒขแƒ”แƒ‘แƒ˜แƒ— แƒแƒ  แƒ“แƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒฃแƒšแƒ แƒ“แƒ แƒ’แƒแƒœแƒแƒฎแƒšแƒ”แƒ‘แƒ˜แƒก แƒŸแƒ”แƒขแƒแƒœแƒ˜ แƒแƒ  แƒ“แƒแƒ‘แƒ แƒฃแƒœแƒ“แƒ, แƒ˜แƒก แƒ™แƒ•แƒšแƒแƒ• แƒ“แƒแƒ˜แƒฌแƒงแƒ”แƒ‘แƒก แƒžแƒ แƒแƒชแƒ”แƒ“แƒฃแƒ แƒแƒก (แƒฉแƒ•แƒ”แƒœ แƒฉแƒแƒ•แƒ—แƒ•แƒแƒšแƒ”แƒ— แƒแƒ แƒแƒฃแƒกแƒแƒคแƒ แƒ—แƒฎแƒ แƒขแƒแƒ™แƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒšแƒแƒ™แƒแƒšแƒฃแƒ แƒแƒ“ แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ แƒขแƒ”แƒ แƒ›แƒ˜แƒœแƒแƒšแƒ–แƒ” แƒ“แƒ แƒแƒ  แƒ•แƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒ— แƒแƒ  แƒ›แƒ˜แƒœแƒ“แƒ แƒ แƒแƒ›แƒ˜แƒก แƒ’แƒแƒ แƒ—แƒฃแƒšแƒ”แƒ‘แƒ แƒ™แƒ แƒ˜แƒžแƒขแƒแƒ’แƒ แƒแƒคแƒ˜แƒ˜แƒ— แƒแƒœ แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒ˜แƒก แƒฎแƒจแƒ˜แƒ แƒแƒ“ แƒ’แƒแƒฎแƒกแƒœแƒ).

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

แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒš แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒจแƒ˜ แƒ—แƒฅแƒ•แƒ”แƒœ แƒฃแƒœแƒ“แƒ แƒ’แƒแƒ›แƒแƒแƒ’แƒ–แƒแƒ•แƒœแƒแƒ— แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒกแƒแƒ—แƒแƒฃแƒ แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒจแƒ”แƒ˜แƒชแƒแƒ•แƒก แƒŸแƒ”แƒขแƒแƒœแƒ˜แƒก แƒขแƒ˜แƒžแƒก แƒ“แƒ แƒ—แƒแƒ•แƒแƒ“ แƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒก แƒŸแƒ”แƒขแƒแƒœแƒก. แƒแƒ›แƒŸแƒแƒ›แƒแƒ“, แƒŸแƒ”แƒขแƒแƒœแƒ˜แƒก แƒขแƒ˜แƒžแƒ˜ แƒงแƒแƒ•แƒ”แƒšแƒ—แƒ•แƒ˜แƒก แƒแƒ แƒ˜แƒก Bearer. แƒ˜แƒ›แƒ˜แƒขแƒแƒ› แƒ แƒแƒ› แƒฉแƒ•แƒ”แƒœ แƒฃแƒœแƒ“แƒ แƒจแƒ”แƒ•แƒแƒ›แƒแƒฌแƒ›แƒแƒ—, แƒ แƒแƒ› แƒŸแƒ”แƒขแƒแƒœแƒก แƒ•แƒแƒ“แƒ แƒแƒ  แƒ’แƒแƒฃแƒ•แƒ˜แƒ“แƒ แƒ“แƒ แƒ’แƒแƒœแƒแƒแƒฎแƒšแƒแƒ— แƒ˜แƒ’แƒ˜ แƒ’แƒแƒชแƒ”แƒ›แƒ˜แƒก แƒ›แƒแƒ›แƒ”แƒœแƒขแƒ˜แƒ“แƒแƒœ แƒ”แƒ แƒ—แƒ˜ แƒกแƒแƒแƒ—แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒ›แƒ” แƒ“แƒแƒ•แƒแƒ–แƒฃแƒกแƒขแƒ” แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ แƒกแƒฎแƒ•แƒ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒก Access แƒขแƒแƒ™แƒ”แƒœแƒก. แƒ™แƒแƒ“แƒ˜แƒก แƒ˜แƒ’แƒ˜แƒ•แƒ” แƒœแƒแƒฌแƒ˜แƒšแƒ˜ แƒแƒ แƒ˜แƒก แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜แƒก แƒ“แƒแƒกแƒแƒฌแƒงแƒ˜แƒกแƒจแƒ˜ แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ Access แƒœแƒ˜แƒจแƒœแƒ˜แƒก แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒ˜แƒกแƒแƒก:

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-แƒก แƒ›แƒแƒซแƒ”แƒ‘แƒœแƒแƒก แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒ”แƒšแƒ˜ แƒ–แƒฃแƒกแƒขแƒแƒ“ แƒแƒ› แƒ”แƒšแƒคแƒแƒกแƒขแƒ˜แƒ—, แƒ›แƒ”แƒขแƒกแƒแƒฎแƒ”แƒšแƒ”แƒ‘แƒ˜แƒก แƒฉแƒแƒ—แƒ•แƒšแƒ˜แƒ—. แƒ—แƒฅแƒ•แƒ”แƒœ แƒแƒกแƒ”แƒ•แƒ” แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒแƒ— wildcard: =, :, :{PREFIX}*.

แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒกแƒแƒฆแƒ”แƒ‘แƒแƒ“ แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ— 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-แƒ˜แƒก แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒ˜แƒ— แƒ“แƒ แƒ•แƒฃแƒ’แƒ–แƒแƒ•แƒœแƒ˜แƒ— แƒ–แƒแƒ’แƒแƒ“ แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒแƒก แƒ˜แƒœแƒกแƒขแƒ แƒฃแƒฅแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒ— แƒ“แƒ แƒจแƒ”แƒกแƒ•แƒšแƒแƒ–แƒ” แƒžแƒ˜แƒ แƒแƒ“ แƒ”แƒšแƒคแƒแƒกแƒขแƒแƒ–แƒ”, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒขแƒ”แƒšแƒ”แƒคแƒแƒœแƒ˜แƒก แƒœแƒแƒ›แƒ”แƒ แƒ—แƒแƒœ แƒ”แƒ แƒ—แƒแƒ“ แƒ›แƒแƒ’แƒ•แƒแƒฌแƒแƒ“แƒ แƒ“แƒแƒกแƒแƒฅแƒ›แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒœแƒงแƒแƒคแƒ˜แƒšแƒ”แƒ‘แƒแƒ›. แƒ แƒแƒ’แƒแƒ แƒช แƒแƒšแƒขแƒ”แƒ แƒœแƒแƒขแƒ˜แƒ•แƒ, แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ“แƒแƒ–แƒแƒ’แƒแƒ— แƒคแƒฃแƒšแƒ˜ แƒ“แƒ แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒแƒ— แƒ—แƒฅแƒ•แƒ”แƒœแƒ˜ แƒžแƒแƒ แƒแƒšแƒ˜ แƒกแƒแƒ˜แƒ“แƒฃแƒ›แƒšแƒ แƒขแƒ”แƒšแƒ”แƒ’แƒ แƒแƒ›แƒ˜แƒก แƒฉแƒแƒขแƒจแƒ˜, แƒ แƒแƒช แƒแƒกแƒ”แƒ•แƒ” แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒฉแƒแƒ˜แƒ—แƒ•แƒแƒšแƒแƒก แƒ›แƒ”แƒแƒ แƒ” แƒคแƒแƒฅแƒขแƒแƒ แƒแƒ“ (แƒ’แƒแƒ›แƒแƒœแƒแƒ™แƒšแƒ˜แƒกแƒ˜ แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ MacBooks).

แƒ’แƒ›แƒแƒ“แƒšแƒแƒ‘แƒ—, แƒ แƒแƒ› แƒ‘แƒแƒšแƒแƒ›แƒ“แƒ” แƒฌแƒแƒ˜แƒ™แƒ˜แƒ—แƒฎแƒ”แƒ—. แƒกแƒ˜แƒแƒ›แƒแƒ•แƒœแƒ”แƒ‘แƒ˜แƒ— แƒ•แƒ˜แƒฎแƒ˜แƒšแƒแƒ• แƒฌแƒ˜แƒœแƒแƒ“แƒแƒ“แƒ”แƒ‘แƒ”แƒ‘แƒก แƒกแƒขแƒแƒขแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒฌแƒ”แƒ แƒ˜แƒก แƒกแƒขแƒ˜แƒšแƒ˜แƒก แƒ’แƒแƒกแƒแƒฃแƒ›แƒฏแƒแƒ‘แƒ”แƒกแƒ”แƒ‘แƒšแƒแƒ“ แƒ“แƒ แƒ’แƒ˜แƒกแƒฃแƒ แƒ•แƒ”แƒ‘, แƒ แƒแƒ› แƒœแƒแƒ™แƒšแƒ”แƒ‘แƒ˜ แƒจแƒ”แƒชแƒ“แƒแƒ›แƒ แƒ“แƒแƒ˜แƒญแƒ˜แƒ แƒ แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜แƒก แƒฌแƒ”แƒ แƒ˜แƒกแƒแƒก =)

แƒ‘แƒ›แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒ, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ˜แƒงแƒแƒก แƒ—แƒ”แƒ›แƒแƒขแƒฃแƒ แƒแƒ“ แƒกแƒแƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒ แƒแƒœ แƒฃแƒ‘แƒ แƒแƒšแƒแƒ“ แƒฃแƒžแƒแƒกแƒฃแƒฎแƒแƒก แƒ™แƒ˜แƒ—แƒฎแƒ•แƒ”แƒ‘แƒก:

แƒฌแƒงแƒแƒ แƒ: www.habr.com

แƒแƒฎแƒแƒšแƒ˜ แƒ™แƒแƒ›แƒ”แƒœแƒขแƒแƒ แƒ˜แƒก แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ