API เจฆเฉเจ†เจฐเจพ PowerShell เจคเฉ‹เจ‚ Google เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจฌเจฃเจพเจ‰เจฃเจพ

เจนเฉˆเจฒเฉ‹!

เจ‡เจน เจฒเฉ‡เจ– G Suite เจ‰เจชเจญเฉ‹เจ—เจคเจพเจตเจพเจ‚ เจจเฉ‚เฉฐ เจนเฉ‡เจฐเจพเจซเฉ‡เจฐเฉ€ เจ•เจฐเจจ เจฒเจˆ Google API เจจเจพเจฒ PowerShell เจ‡เฉฐเจŸเจฐเฉˆเจ•เจธเจผเจจ เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจ เจฆเจพ เจตเจฐเจฃเจจ เจ•เจฐเฉ‡เจ—เจพเฅค

เจ…เจธเฉ€เจ‚ เจชเฉ‚เจฐเฉ‡ เจธเฉฐเจ—เจ เจจ เจตเจฟเฉฑเจš เจ•เจˆ เจ…เฉฐเจฆเจฐเฉ‚เจจเฉ€ เจ…เจคเฉ‡ เจ•เจฒเจพเจ‰เจก เจธเฉ‡เจตเจพเจตเจพเจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚เฅค เจœเจผเจฟเจ†เจฆเจพเจคเจฐ เจนเจฟเฉฑเจธเฉ‡ เจฒเจˆ, เจ‰เจนเจจเจพเจ‚ เจตเจฟเฉฑเจš เจ…เจงเจฟเจ•เจพเจฐ Google เจœเจพเจ‚ เจเจ•เจŸเจฟเจต เจกเจพเจ‡เจฐเฉˆเจ•เจŸเจฐเฉ€ เจตเจฟเฉฑเจš เจ†เจ‰เจ‚เจฆเฉ‡ เจนเจจ, เจœเจฟเจธ เจฆเฉ‡ เจตเจฟเจšเจ•เจพเจฐ เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจ• เจชเฉเจฐเจคเฉ€เจ•เฉเจฐเจฟเจคเฉ€ เจจเฉ‚เฉฐ เจ•เจพเจ‡เจฎ เจจเจนเฉ€เจ‚ เจฐเฉฑเจ– เจธเจ•เจฆเฉ‡; เจ‡เจธเจฆเฉ‡ เจ…เจจเฉเจธเจพเจฐ, เจœเจฆเฉ‹เจ‚ เจ‡เฉฑเจ• เจจเจตเจพเจ‚ เจ•เจฐเจฎเจšเจพเจฐเฉ€ เจ›เฉฑเจกเจฆเจพ เจนเฉˆ, เจคเจพเจ‚ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจ‡เจนเจจเจพเจ‚ เจฆเฉ‹ เจชเฉเจฐเจฃเจพเจฒเฉ€เจ†เจ‚ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจ–เจพเจคเจพ เจฌเจฃเจพเจ‰เจฃ/เจฏเฉ‹เจ— เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉเฉฐเจฆเฉ€ เจนเฉˆเฅค เจชเฉเจฐเจ•เจฟเจฐเจฟเจ† เจจเฉ‚เฉฐ เจธเจตเฉˆเจšเจพเจฒเจค เจ•เจฐเจจ เจฒเจˆ, เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจ• เจธเจ•เฉเจฐเจฟเจชเจŸ เจฒเจฟเจ–เจฃ เจฆเจพ เจซเฉˆเจธเจฒเจพ เจ•เฉ€เจคเจพ เจนเฉˆ เจœเฉ‹ เจœเจพเจฃเจ•เจพเจฐเฉ€ เจ‡เจ•เฉฑเจ เฉ€ เจ•เจฐเจฆเฉ€ เจนเฉˆ เจ…เจคเฉ‡ เจ‡เจธเจจเฉ‚เฉฐ เจฆเฉ‹เจตเจพเจ‚ เจธเฉ‡เจตเจพเจตเจพเจ‚ เจจเฉ‚เฉฐ เจญเฉ‡เจœเจฆเฉ€ เจนเฉˆเฅค

เจชเฉเจฐเจฎเจพเจฃเฉ€เจ•เจฐเจฃ

เจฒเฉ‹เฉœเจพเจ‚ เจจเฉ‚เฉฐ เจคเจฟเจ†เจฐ เจ•เจฐเจฆเฉ‡ เจธเจฎเฉ‡เจ‚, เจ…เจธเฉ€เจ‚ เจ…เจงเจฟเจ•เจพเจฐ เจฒเจˆ เจ…เจธเจฒ เจฎเจจเฉเฉฑเจ–เฉ€ เจชเฉเจฐเจธเจผเจพเจธเจ•เจพเจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจ เจฆเจพ เจซเฉˆเจธเจฒเจพ เจ•เฉ€เจคเจพ; เจ‡เจน เจฆเฉเจฐเจ˜เจŸเจจเจพ เจœเจพเจ‚ เจœเจพเจฃเจฌเฉเฉฑเจ เจ•เฉ‡ เจตเฉฑเจกเฉ‡ เจฌเจฆเจฒเจพเจ… เจฆเฉ€ เจธเจฅเจฟเจคเฉ€ เจตเจฟเฉฑเจš เจ•เจพเจฐเจตเจพเจˆเจ†เจ‚ เจฆเฉ‡ เจตเจฟเจธเจผเจฒเฉ‡เจธเจผเจฃ เจจเฉ‚เฉฐ เจธเจฐเจฒ เจฌเจฃเจพเจ‰เจ‚เจฆเจพ เจนเฉˆเฅค

Google API เจชเฉเจฐเจฎเจพเจฃเฉ€เจ•เจฐเจจ เจ…เจคเฉ‡ เจชเฉเจฐเจฎเจพเจฃเฉ€เจ•เจฐเจจ เจฒเจˆ OAuth 2.0 เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเจจเฅค เจ•เฉ‡เจธเจพเจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเฉ‹ เจ…เจคเฉ‡ เจนเฉ‹เจฐ เจตเจฟเจธเจคเฉเจฐเจฟเจค เจตเจฐเจฃเจจ เจ‡เฉฑเจฅเฉ‡ เจฒเฉฑเจญเฉ‡ เจœเจพ เจธเจ•เจฆเฉ‡ เจนเจจ: Google API เจคเฉฑเจ• เจชเจนเฉเฉฐเจš เจ•เจฐเจจ เจฒเจˆ OAuth 2.0 เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจเจพ.

เจฎเฉˆเจ‚ เจ‰เจน เจธเจ•เฉเจฐเจฟเจชเจŸ เจšเฉเจฃเฉ€ เจนเฉˆ เจœเฉ‹ เจกเฉˆเจธเจ•เจŸเฉŒเจช เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจเจพเจ‚ เจตเจฟเฉฑเจš เจชเฉเจฐเจฎเจพเจฃเจฟเจ•เจคเจพ เจฒเจˆ เจตเจฐเจคเฉ€ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆเฅค เจธเฉ‡เจตเจพ เจ–เจพเจคเฉ‡ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจ เจฆเจพ เจตเจฟเจ•เจฒเจช เจตเฉ€ เจนเฉˆ, เจœเจฟเจธ เจตเจฟเฉฑเจš เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจคเฉ‹เจ‚ เจฌเฉ‡เจฒเฉ‹เฉœเฉ€ เจนเจฐเจ•เจค เจฆเฉ€ เจฒเฉ‹เฉœ เจจเจนเฉ€เจ‚ เจนเฉˆเฅค

เจนเฉ‡เจ เจพเจ‚ เจฆเจฟเฉฑเจคเฉ€ เจคเจธเจตเฉ€เจฐ เจ—เฉ‚เจ—เจฒ เจชเฉ‡เจœ เจคเฉ‹เจ‚ เจšเฉเจฃเฉ‡ เจ—เจ เจฆเฉเจฐเจฟเจธเจผ เจฆเจพ เจฏเฉ‹เจœเจจเจพเจฌเฉฑเจง เจตเจฐเจฃเจจ เจนเฉˆเฅค

API เจฆเฉเจ†เจฐเจพ PowerShell เจคเฉ‹เจ‚ Google เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจฌเจฃเจพเจ‰เจฃเจพ

  1. เจชเจนเจฟเจฒเจพเจ‚, เจ…เจธเฉ€เจ‚ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจจเฉ‚เฉฐ GET เจชเฉˆเจฐเจพเจฎเฉ€เจŸเจฐเจพเจ‚ เจจเฉ‚เฉฐ เจจเจฟเจธเจผเจšเจฟเจค เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ, Google เจ–เจพเจคเจพ เจชเฉเจฐเจฎเจพเจฃเฉ€เจ•เจฐเจจ เจชเฉฐเจจเฉ‡ 'เจคเฉ‡ เจญเฉ‡เจœเจฆเฉ‡ เจนเจพเจ‚:
    • เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจ เจ†เจˆ.เจกเฉ€
    • เจ‰เจน เจ–เฉ‡เจคเจฐ เจœเจฟเจจเฉเจนเจพเจ‚ เจคเฉฑเจ• เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจ เจจเฉ‚เฉฐ เจชเจนเฉเฉฐเจš เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ
    • เจ‰เจน เจชเจคเจพ เจœเจฟเจธ 'เจคเฉ‡ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจจเฉ‚เฉฐ เจชเฉเจฐเจ•เจฟเจฐเจฟเจ† เจชเฉ‚เจฐเฉ€ เจ•เจฐเจจ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจฐเฉ€เจกเจพเจ‡เจฐเฉˆเจ•เจŸ เจ•เฉ€เจคเจพ เจœเจพเจตเฉ‡เจ—เจพ
    • เจœเจฟเจธ เจคเจฐเฉ€เจ•เฉ‡ เจจเจพเจฒ เจ…เจธเฉ€เจ‚ เจŸเฉ‹เจ•เจจ เจจเฉ‚เฉฐ เจ…เจชเจกเฉ‡เจŸ เจ•เจฐเจพเจ‚เจ—เฉ‡
    • เจธเฉเจฐเฉฑเจ–เจฟเจ† เจ•เฉ‹เจก
    • เจคเจธเจฆเฉ€เจ• เจ•เฉ‹เจก เจชเฉเจฐเจธเจพเจฐเจฃ เจซเจพเจฐเจฎเฉˆเจŸ

  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] / [az] / [0-9] / "-" / "เฅค" / "_" / "~"เฅค

เจ‡เจน เจ•เฉ‹เจก เจซเจฟเจฐ เจฆเฉเจฌเจพเจฐเจพ เจชเฉเจฐเจธเจพเจฐเจฟเจค เจ•เฉ€เจคเจพ เจœเจพเจตเฉ‡เจ—เจพเฅค เจ‡เจน เจ•เจฎเจœเจผเฉ‹เจฐเฉ€ เจจเฉ‚เฉฐ เจ–เจคเจฎ เจ•เจฐเจฆเจพ เจนเฉˆ เจœเจฟเจธ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจนเจฎเจฒเจพเจตเจฐ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจชเฉเจฐเจฎเจพเจฃเฉ€เจ•เจฐเจจ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจฐเฉ€เจกเจพเจ‡เจฐเฉˆเจ•เจŸ เจตเจœเฉ‹เจ‚ เจตเจพเจชเจธ เจ•เฉ€เจคเฉ‡ เจœเจตเจพเจฌ เจจเฉ‚เฉฐ เจฐเฉ‹เจ• เจธเจ•เจฆเจพ เจนเฉˆเฅค
เจคเฉเจธเฉ€เจ‚ เจฎเฉŒเจœเฉ‚เจฆเจพ เจฌเฉ‡เจจเจคเฉ€ เจตเจฟเฉฑเจš เจธเจชเจธเจผเจŸ เจŸเฉˆเจ•เจธเจŸ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจ•เฉ‹เจก เจตเฉˆเจฐเฉ€เจซเจพเจ‡เจฐ เจญเฉ‡เจœ เจธเจ•เจฆเฉ‡ เจนเฉ‹ (เจœเฉ‹ เจ‡เจธเจจเฉ‚เฉฐ เจ…เจฐเจฅเจนเฉ€เจฃ เจฌเจฃเจพเจ‰เจ‚เจฆเจพ เจนเฉˆ - เจ‡เจน เจธเจฟเจฐเจซ เจ‰เจนเจจเจพเจ‚ เจธเจฟเจธเจŸเจฎเจพเจ‚ เจฒเจˆ เจขเฉเจ•เจตเจพเจ‚ เจนเฉˆ เจœเฉ‹ SHA256 เจฆเจพ เจธเจฎเจฐเจฅเจจ เจจเจนเฉ€เจ‚ เจ•เจฐเจฆเฉ‡ เจนเจจ), เจœเจพเจ‚ SHA256 เจเจฒเจ—เฉ‹เจฐเจฟเจฆเจฎ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจ‡เฉฑเจ• เจนเฉˆเจธเจผ เจฌเจฃเจพ เจ•เฉ‡, เจœเจฟเจธ เจจเฉ‚เฉฐ BASE64Url เจตเจฟเฉฑเจš เจเจจเจ•เฉ‹เจก เจ•เฉ€เจคเจพ เจœเจพเจฃเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆ (เจตเฉฑเจ–เจฐเจพ เจฌเฉ‡เจธ 64 เจคเฉ‹เจ‚ เจฆเฉ‹ เจŸเฉ‡เจฌเจฒ เจ…เฉฑเจ–เจฐเจพเจ‚ เจฆเฉเจ†เจฐเจพ) เจ…เจคเฉ‡ เจ…เฉฑเจ–เจฐ เจฒเจพเจˆเจจ เจฆเฉ‡ เจ…เฉฐเจค เจจเฉ‚เฉฐ เจนเจŸเจพเจ‰เจฃเจพ: =.

เจ…เฉฑเจ—เฉ‡, เจ…เจงเจฟเจ•เจพเจฐ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจœเจตเจพเจฌ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจฒเจˆ เจธเจพเจจเฉ‚เฉฐ เจธเจฅเจพเจจเจ• เจฎเจธเจผเฉ€เจจ 'เจคเฉ‡ http เจจเฉ‚เฉฐ เจธเฉเจฃเจจเจพ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ, เจœเฉ‹ เจ•เจฟ เจ‡เฉฑเจ• เจฐเฉ€เจกเจพเจ‡เจฐเฉˆเจ•เจŸ เจฆเฉ‡ เจฐเฉ‚เจช เจตเจฟเฉฑเจš เจตเจพเจชเจธ เจ•เฉ€เจคเจพ เจœเจพเจตเฉ‡เจ—เจพเฅค

เจชเฉเจฐเจฌเฉฐเจงเจ•เฉ€ เจ•เฉฐเจฎ เจ‡เฉฑเจ• เจตเจฟเจธเจผเฉ‡เจธเจผ เจธเจฐเจตเจฐ 'เจคเฉ‡ เจ•เฉ€เจคเฉ‡ เจœเจพเจ‚เจฆเฉ‡ เจนเจจ, เจ…เจธเฉ€เจ‚ เจ‡เจธ เจธเฉฐเจญเจพเจตเจจเจพ เจคเฉ‹เจ‚ เจ‡เจจเจ•เจพเจฐ เจจเจนเฉ€เจ‚ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจ•เจฟ เจ•เจˆ เจชเฉเจฐเจธเจผเจพเจธเจ• เจ‡เฉฑเจ•เฉ‹ เจธเจฎเฉ‡เจ‚ เจธเจ•เฉเจฐเจฟเจชเจŸ เจจเฉ‚เฉฐ เจšเจฒเจพเจ‰เจฃเจ—เฉ‡, เจ‡เจธเจฒเจˆ เจ‡เจน เจฎเฉŒเจœเฉ‚เจฆเจพ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจฒเจˆ เจฌเฉ‡เจคเจฐเจคเฉ€เจฌเฉ‡ เจคเฉŒเจฐ 'เจคเฉ‡ เจ‡เฉฑเจ• เจชเฉ‹เจฐเจŸ เจšเฉเจฃเฉ‡เจ—เจพ, เจชเจฐ เจฎเฉˆเจ‚ เจชเจนเจฟเจฒเจพเจ‚ เจคเฉ‹เจ‚ เจชเจฐเจฟเจญเจพเจธเจผเจฟเจค เจชเฉ‹เจฐเจŸเจพเจ‚ เจจเฉ‚เฉฐ เจจเจฟเจฐเจงเจพเจฐเจค เจ•เฉ€เจคเจพ เจนเฉˆ เจ•เจฟเจ‰เจ‚เจ•เจฟ เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ API เจ•เฉฐเจธเฉ‹เจฒ เจตเจฟเฉฑเจš เจญเจฐเฉ‹เจธเฉ‡เจฏเฉ‹เจ— เจตเจœเฉ‹เจ‚ เจตเฉ€ เจœเฉ‹เฉœเจฟเจ† เจœเจพเจฃเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆเฅค

access_type=เจ†เจซเจฒเจพเจˆเจจ เจฆเจพ เจฎเจคเจฒเจฌ เจนเฉˆ เจ•เจฟ เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจ เจฌเฉเจฐเจพเจŠเจœเจผเจฐ เจจเจพเจฒ เจฏเฉ‚เจœเจผเจฐ เจ‡เฉฐเจŸเจฐเฉˆเจ•เจธเจผเจจ เจฆเฉ‡ เจฌเจฟเจจเจพเจ‚ เจ†เจชเจฃเฉ‡ เจ†เจช เจ‡เฉฑเจ• เจฎเจฟเจ†เจฆ เจชเฉเฉฑเจ—เฉ‡ เจŸเฉ‹เจ•เจจ เจจเฉ‚เฉฐ เจ…เจชเจกเฉ‡เจŸ เจ•เจฐ เจธเจ•เจฆเฉ€ เจนเฉˆ,
เจœเจตเจพเจฌ_เจ•เจฟเจธเจฎ = เจ•เฉ‹เจก เจ‡เจน เจซเจพเจฐเจฎเฉˆเจŸ เจธเฉˆเฉฑเจŸ เจ•เจฐเจฆเจพ เจนเฉˆ เจ•เจฟ เจ•เฉ‹เจก เจจเฉ‚เฉฐ เจ•เจฟเจตเฉ‡เจ‚ เจตเจพเจชเจธ เจ•เฉ€เจคเจพ เจœเจพเจตเฉ‡เจ—เจพ (เจชเฉเจฐเจพเจฃเฉ€ เจชเฉเจฐเจฎเจพเจฃเจฟเจ•เจคเจพ เจตเจฟเจงเฉ€ เจฆเจพ เจนเจตเจพเจฒเจพ, เจœเจฆเฉ‹เจ‚ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจจเฉ‡ เจฌเฉเจฐเจพเจŠเจœเจผเจฐ เจคเฉ‹เจ‚ เจ•เฉ‹เจก เจจเฉ‚เฉฐ เจธเจ•เฉเจฐเจฟเจชเจŸ เจตเจฟเฉฑเจš เจ•เจพเจชเฉ€ เจ•เฉ€เจคเจพ),
เจธเจ•เฉ‹เจช เจชเจนเฉเฉฐเจš เจฆเฉ‡ เจฆเจพเจ‡เจฐเฉ‡ เจ…เจคเฉ‡ เจ•เจฟเจธเจฎ เจจเฉ‚เฉฐ เจฆเจฐเจธเจพเจ‰เจ‚เจฆเจพ เจนเฉˆเฅค เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ เจธเจชเฉ‡เจธ เจœเจพเจ‚ %20 (URL เจเจจเจ•เฉ‹เจกเจฟเฉฐเจ— เจฆเฉ‡ เจ…เจจเฉเจธเจพเจฐ) เจฆเฉเจ†เจฐเจพ เจตเฉฑเจ– เจ•เฉ€เจคเจพ เจœเจพเจฃเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆเฅค เจ•เจฟเจธเจฎเจพเจ‚ เจตเจพเจฒเฉ‡ เจชเจนเฉเฉฐเจš เจ–เฉ‡เจคเจฐเจพเจ‚ เจฆเฉ€ เจธเฉ‚เจšเฉ€ เจ‡เฉฑเจฅเฉ‡ เจตเฉ‡เจ–เฉ€ เจœเจพ เจธเจ•เจฆเฉ€ เจนเฉˆ: Google API เจฒเจˆ OAuth 2.0 เจธเจ•เฉ‹เจช.

เจ…เจงเจฟเจ•เจพเจฐ เจ•เฉ‹เจก เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ, เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจ เจฌเฉเจฐเจพเจŠเจœเจผเจฐ เจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจจเจœเจผเจฆเฉ€เจ•เฉ€ เจธเฉเจจเฉ‡เจนเจพ เจตเจพเจชเจธ เจ•เจฐเฉ‡เจ—เฉ€, เจชเฉ‹เจฐเจŸ 'เจคเฉ‡ เจธเฉเจฃเจจเจพ เจฌเฉฐเจฆ เจ•เจฐ เจฆเฉ‡เจตเฉ‡เจ—เฉ€ เจ…เจคเฉ‡ เจŸเฉ‹เจ•เจจ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจฒเจˆ เจ‡เฉฑเจ• POST เจฌเฉ‡เจจเจคเฉ€ เจญเฉ‡เจœเฉ‡เจ—เฉ€เฅค เจ…เจธเฉ€เจ‚ เจ‡เจธ เจตเจฟเฉฑเจš เจชเจนเจฟเจฒเจพเจ‚ เจจเจฟเจฐเจงเจพเจฐเจค เจ†เจˆเจกเฉ€ เจ…เจคเฉ‡ เจ•เฉฐเจธเฉ‹เจฒ API เจคเฉ‹เจ‚ เจ—เฉเจชเจค เจธเฉฐเจ•เฉ‡เจค เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚, เจ‰เจน เจชเจคเจพ เจœเจฟเจธ 'เจคเฉ‡ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจจเฉ‚เฉฐ เจฐเฉ€เจกเจพเจ‡เจฐเฉˆเจ•เจŸ เจ•เฉ€เจคเจพ เจœเจพเจตเฉ‡เจ—เจพ เจ…เจคเฉ‡ เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ เจจเจฟเจฐเจงเจพเจฐเจจ เจฆเฉ‡ เจ…เจจเฉเจธเจพเจฐ 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'])
      }
    }
  }
}

เจนเจฐเฉ‡เจ• เจฌเฉ‡เจจเจคเฉ€ เจตเจฟเฉฑเจš, เจคเฉเจนเจพเจจเฉ‚เฉฐ เจŸเฉ‹เจ•เจจ เจ•เจฟเจธเจฎ เจ…เจคเฉ‡ เจ–เฉเจฆ เจเจ•เจธเฉˆเจธ เจŸเฉ‹เจ•เจจ เจตเจพเจฒเจพ เจ‡เฉฑเจ• เจชเฉเจฐเจฎเจพเจฃเฉ€เจ•เจฐเจจ เจธเจฟเจฐเจฒเฉ‡เจ– เจญเฉ‡เจœเจฃ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉเฉฐเจฆเฉ€ เจนเฉˆเฅค เจตเจฐเจคเจฎเจพเจจ เจตเจฟเฉฑเจš, เจŸเฉ‹เจ•เจจ เจฆเฉ€ เจ•เจฟเจธเจฎ เจนเจฎเฉ‡เจธเจผเจพเจ‚ เจฌเฉ‡เจ…เจฐเจฐ เจนเฉเฉฐเจฆเฉ€ เจนเฉˆเฅค เจ•เจฟเจ‰เจ‚เจ•เจฟ เจธเจพเจจเฉ‚เฉฐ เจ‡เจน เจœเจพเจ‚เจš เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ เจ•เจฟ เจŸเฉ‹เจ•เจจ เจฆเฉ€ เจฎเจฟเจ†เจฆ เจ–เจคเจฎ เจจเจนเฉ€เจ‚ เจนเฉ‹เจˆ เจนเฉˆ เจ…เจคเฉ‡ เจ‡เจธเจจเฉ‚เฉฐ เจœเจพเจฐเฉ€ เจ•เฉ€เจคเฉ‡ เจœเจพเจฃ เจคเฉ‹เจ‚ เจ‡เฉฑเจ• เจ˜เฉฐเจŸเฉ‡ เจฌเจพเจ…เจฆ เจ‡เจธเจจเฉ‚เฉฐ เจ…เฉฑเจชเจกเฉ‡เจŸ เจ•เจฐเจจเจพ เจนเฉˆ, เจฎเฉˆเจ‚ เจ‡เฉฑเจ• เจนเฉ‹เจฐ เจซเฉฐเจ•เจธเจผเจจ เจฒเจˆ เจ‡เฉฑเจ• เจฌเฉ‡เจจเจคเฉ€ เจจเจฟเจฐเจงเจพเจฐเจค เจ•เฉ€เจคเฉ€ เจนเฉˆ เจœเฉ‹ เจ‡เฉฑเจ• เจเจ•เจธเฉˆเจธ เจŸเฉ‹เจ•เจจ เจตเจพเจชเจธ เจ•เจฐเจฆเจพ เจนเฉˆเฅค เจ•เฉ‹เจก เจฆเจพ เจ‰เจนเฉ€ เจŸเฉเจ•เฉœเจพ เจธเจ•เฉเจฐเจฟเจชเจŸ เจฆเฉ‡ เจธเจผเฉเจฐเฉ‚ เจตเจฟเฉฑเจš เจนเฉเฉฐเจฆเจพ เจนเฉˆ เจœเจฆเฉ‹เจ‚ เจชเจนเจฟเจฒเจพ เจเจ•เจธเฉˆเจธ เจŸเฉ‹เจ•เจจ เจชเฉเจฐเจพเจชเจค เจนเฉเฉฐเจฆเจพ เจนเฉˆ:

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, เจ‡เฉฑเจ• เจฐเจฟเจ•เจพเจฐเจก เจจเฉ‚เฉฐ เจฎเจฟเจŸเจพเจ‰เจฃ เจฒเจˆ (เจ‰เจฆเจพเจนเจฐเจจ เจฒเจˆ, เจ‡เฉฑเจ• เจธเจฎเฉ‚เจน เจคเฉ‹เจ‚ เจ‡เฉฑเจ• เจฎเฉˆเจ‚เจฌเจฐ) - เจฎเจฟเจŸเจพเจ“เฅค

เจธเจ•เฉเจฐเจฟเจชเจŸ เจ‡เฉฑเจ• เจซเจผเฉ‹เจจ เจจเฉฐเจฌเจฐ (เจ‡เฉฑเจ• เจ—เฉˆเจฐ-เจชเฉเจฐเจฎเจพเจฃเจฟเจค เจธเจคเจฐ) เจ…เจคเฉ‡ เจ‡เฉฑเจ• เจ–เฉ‡เจคเจฐเฉ€ เจตเฉฐเจก เจธเจฎเฉ‚เจน เจตเจฟเฉฑเจš เจธเจผเจพเจฎเจฒ เจ•เจฐเจจ เจฒเจˆ เจตเฉ€ เจชเฉเฉฑเจ›เฉ‡เจ—เฉ€เฅค เจ‡เจน เจซเฉˆเจธเจฒเจพ เจ•เจฐเจฆเจพ เจนเฉˆ เจ•เจฟ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจจเฉ‚เฉฐ เจšเฉเจฃเฉ€ เจ—เจˆ เจเจ•เจŸเจฟเจต เจกเจพเจ‡เจฐเฉˆเจ•เจŸเจฐเฉ€ 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
}

เจ‡เฉฑเจ• เจ–เจพเจคเจพ เจ…เฉฑเจชเจกเฉ‡เจŸ เจ•เจฐเจจ เจ…เจคเฉ‡ เจฌเจฃเจพเจ‰เจฃ เจฒเจˆ เจซเฉฐเจ•เจธเจผเจจเจพเจ‚ เจฆเจพ เจ‡เฉฑเจ• เจธเจฎเจพเจจ เจธเฉฐเจŸเฉˆเจ•เจธ เจนเฉเฉฐเจฆเจพ เจนเฉˆ; เจธเจพเจฐเฉ‡ เจตเจพเจงเฉ‚ เจ–เฉ‡เจคเจฐเจพเจ‚ เจฆเฉ€ เจฒเฉ‹เฉœ เจจเจนเฉ€เจ‚ เจนเฉเฉฐเจฆเฉ€ เจนเฉˆ; เจซเจผเฉ‹เจจ เจจเฉฐเจฌเจฐเจพเจ‚ เจตเจพเจฒเฉ‡ เจญเจพเจ— เจตเจฟเฉฑเจš, เจคเฉเจนเจพเจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจเจฐเฉ‡ เจจเจฟเจฐเจงเจพเจฐเจค เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉเฉฐเจฆเฉ€ เจนเฉˆ เจœเจฟเจธ เจตเจฟเฉฑเจš เจจเฉฐเจฌเจฐ เจ…เจคเฉ‡ เจ‡เจธเจฆเฉ€ เจ•เจฟเจธเจฎ เจฆเฉ‡ เจจเจพเจฒ เจ‡เฉฑเจ• เจฐเจฟเจ•เจพเจฐเจก เจนเฉ‹ เจธเจ•เจฆเจพ เจนเฉˆเฅค

เจ•เจฟเจธเฉ‡ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจจเฉ‚เฉฐ เจธเจฎเฉ‚เจน เจตเจฟเฉฑเจš เจธเจผเจพเจฎเจฒ เจ•เจฐเจจ เจตเฉ‡เจฒเฉ‡ เจ•เฉ‹เจˆ เจ—เจฒเจคเฉ€ เจจเจพ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจฒเจˆ, เจ…เจธเฉ€เจ‚ เจชเจนเจฟเจฒเจพเจ‚ เจ–เฉเจฆ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจคเฉ‹เจ‚ เจธเจฎเฉ‚เจน เจฎเฉˆเจ‚เจฌเจฐเจพเจ‚ เจœเจพเจ‚ เจฐเจšเจจเจพ เจฆเฉ€ เจธเฉ‚เจšเฉ€ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจ•เฉ‡ เจœเจพเจ‚เจš เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเจพเจ‚ เจ•เจฟ เจ•เฉ€ เจ‰เจน เจชเจนเจฟเจฒเจพเจ‚ เจนเฉ€ เจ‡เจธ เจธเจฎเฉ‚เจน เจฆเจพ เจฎเฉˆเจ‚เจฌเจฐ เจนเฉˆ เจœเจพเจ‚ เจจเจนเฉ€เจ‚เฅค

เจ•เจฟเจธเฉ‡ เจ–เจพเจธ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจฆเฉ€ เจธเจฎเฉ‚เจน เจธเจฆเฉฑเจธเจคเจพ เจฌเจพเจฐเฉ‡ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจ•เจฐเจจเจพ เจฆเฉเจนเจฐเจพเจ‰เจฃ เจตเจพเจฒเจพ เจจเจนเฉ€เจ‚ เจนเฉ‹เจตเฉ‡เจ—เจพ เจ…เจคเฉ‡ เจธเจฟเจฐเจซ เจธเจฟเฉฑเจงเฉ€ เจธเจฆเฉฑเจธเจคเจพ เจฆเจฟเจ–เจพเจเจ—เจพเฅค เจ‡เฉฑเจ• เจฎเฉ‚เจฒ เจธเจฎเฉ‚เจน เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจจเฉ‚เฉฐ เจธเจผเจพเจฎเจฒ เจ•เจฐเจจเจพ เจœเจฟเจธ เจตเจฟเฉฑเจš เจชเจนเจฟเจฒเจพเจ‚ เจคเฉ‹เจ‚ เจนเฉ€ เจ‡เฉฑเจ• เจšเจพเจˆเจฒเจก เจ—เจฐเฉเฉฑเจช เจนเฉˆ เจœเจฟเจธเจฆเจพ เจ‰เจชเจฏเฉ‹เจ—เจ•เจฐเจคเจพ เจฎเฉˆเจ‚เจฌเจฐ เจนเฉˆเฅค

เจธเจฟเฉฑเจŸเจพ

เจœเฉ‹ เจฌเจšเจฆเจพ เจนเฉˆ เจ‰เจน เจนเฉˆ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจจเฉ‚เฉฐ เจจเจตเฉ‡เจ‚ เจ–เจพเจคเฉ‡ เจฒเจˆ เจชเจพเจธเจตเจฐเจก เจญเฉ‡เจœเจฃเจพเฅค เจ…เจธเฉ€เจ‚ เจเจธเจเจฎเจเจธ เจฐเจพเจนเฉ€เจ‚ เจ…เจœเจฟเจนเจพ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚, เจ…เจคเฉ‡ เจนเจฆเจพเจ‡เจคเจพเจ‚ เจฆเฉ‡ เจจเจพเจฒ เจ†เจฎ เจœเจพเจฃเจ•เจพเจฐเฉ€ เจญเฉ‡เจœเจฆเฉ‡ เจนเจพเจ‚ เจ…เจคเฉ‡ เจ‡เฉฑเจ• เจจเจฟเฉฑเจœเฉ€ เจˆเจฎเฉ‡เจฒ 'เจคเฉ‡ เจฒเฉŒเจ—เจ‡เจจ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚, เจœเฉ‹ เจ•เจฟ, เจ‡เฉฑเจ• เจซเจผเฉ‹เจจ เจจเฉฐเจฌเจฐ เจฆเฉ‡ เจจเจพเจฒ, เจญเจฐเจคเฉ€ เจตเจฟเจญเจพเจ— เจฆเฉเจ†เจฐเจพ เจชเฉเจฐเจฆเจพเจจ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจธเฉ€เฅค เจ‡เฉฑเจ• เจตเจฟเจ•เจฒเจช เจตเจœเฉ‹เจ‚, เจคเฉเจธเฉ€เจ‚ เจชเฉˆเจธเฉ‡ เจฌเจšเจพ เจธเจ•เจฆเฉ‡ เจนเฉ‹ เจ…เจคเฉ‡ เจ‡เฉฑเจ• เจ—เฉเจชเจค เจŸเฉˆเจฒเฉ€เจ—เฉเจฐเจพเจฎ เจšเฉˆเจŸ เจตเจฟเฉฑเจš เจ†เจชเจฃเจพ เจชเจพเจธเจตเจฐเจก เจญเฉ‡เจœ เจธเจ•เจฆเฉ‡ เจนเฉ‹, เจœเจฟเจธ เจจเฉ‚เฉฐ เจฆเฉ‚เจœเจพ เจ•เจพเจฐเจ• เจตเฉ€ เจฎเฉฐเจจเจฟเจ† เจœเจพ เจธเจ•เจฆเจพ เจนเฉˆ (เจฎเฉˆเจ•เจฌเฉเฉฑเจ• เจ‡เฉฑเจ• เจ…เจชเจตเจพเจฆ เจนเฉ‹เจตเฉ‡เจ—เจพ)เฅค

เจ…เฉฐเจค เจคเฉฑเจ• เจชเฉœเฉเจนเจจ เจฒเจˆ เจคเฉเจนเจพเจกเจพ เจงเฉฐเจจเจตเจพเจฆเฅค เจฎเฉˆเจจเฉ‚เฉฐ เจฒเฉ‡เจ– เจฒเจฟเจ–เจฃ เจฆเฉ€ เจธเจผเฉˆเจฒเฉ€ เจจเฉ‚เฉฐ เจธเฉเจงเจพเจฐเจจ เจฒเจˆ เจธเฉเจเจพเจ… เจฆเฉ‡เจ– เจ•เฉ‡ เจ–เฉเจธเจผเฉ€ เจนเฉ‹เจตเฉ‡เจ—เฉ€ เจ…เจคเฉ‡ เจฎเฉˆเจ‚ เจšเจพเจนเฉเฉฐเจฆเจพ เจนเจพเจ‚ เจ•เจฟ เจคเฉเจธเฉ€เจ‚ เจธเจ•เฉเจฐเจฟเจชเจŸเจพเจ‚ เจฒเจฟเจ–เจฃ เจตเฉ‡เจฒเฉ‡ เจ˜เฉฑเจŸ เจ—เจฒเจคเฉ€เจ†เจ‚ เจซเฉœเฉ‹ =)

เจฒเจฟเฉฐเจ•เจพเจ‚ เจฆเฉ€ เจธเฉ‚เจšเฉ€ เจœเฉ‹ เจฅเฉ€เจฎเฉˆเจŸเจฟเจ• เจคเฉŒเจฐ 'เจคเฉ‡ เจ‰เจชเจฏเฉ‹เจ—เฉ€ เจนเฉ‹ เจธเจ•เจฆเฉ€ เจนเฉˆ เจœเจพเจ‚ เจธเจฟเจฐเจซเจผ เจธเจตเจพเจฒเจพเจ‚ เจฆเฉ‡ เจœเจตเจพเจฌ เจฆเฉ‡ เจธเจ•เจฆเฉ€ เจนเฉˆ:

เจธเจฐเฉ‹เจค: www.habr.com

เจ‡เฉฑเจ• เจŸเจฟเฉฑเจชเจฃเฉ€ เจœเฉ‹เฉœเฉ‹