LoginSignup
6
7

More than 1 year has passed since last update.

Google グループの全メンバー一覧取得

Last updated at Posted at 2021-05-30

概要

Google Workspace 管理者向けの、全グループのメンバーアドレス一覧を GAS で取得する話です。過去に見つけた手順1に対して主に下記を直したものを記しておきます。

  • メンバーが多くても取得可能
  • 複数ドメインでも一括で取得

image.png

1. はじめに

1.1. 背景

成り行き上、Google Workspace の管理をしていたりする Kirurobo です。
管理コンソールからは選んだ1つのグループのメンバー一覧をダウンロードすることはできますが、グループが多くなってくると面倒です。そこででまとめて取得できる方法がないか探しました。

1.1. 既存手法

Google Apps Script を使ってスプレッドシートに書き出すものとしてて2015年のひささんのスクリプト1が見つかりました。

1.2. 提案手法

基本的には上記の内容で良さそうだったのですが、下記について対応すべくスクリプトを修正しました。

  • ページングを考慮する
    • 多くのメンバーが居る場合や多くのグループがある場合取得しきれなかったため
  • ドメイン名は固定で書かない(ハードコーディングしない)
    • スクリプトをそのままコピペで動くようにする
    • ドメインが複数ある場合にも対応させる
  • 確認画面が出た方が安心

2. 前提条件

  • Google Workspace の管理者権限があること
  • Google Workspace で API を有効にしていること

APIについては、管理で [セキュリティ] → [APIの制御] を開き「ドメインで所有する内部アプリを信頼する」にチェックを入れてあればそれで良いと思われます。
image.png

3. スプレッドシート作成

Googleドライブでスプレッドシートを新規作成します。
「全グループメンバー一覧」など適当に名前を付けておきます。
image.png

4. スクリプトの作成

4.1. スクリプトエディタを開く

作成したスプレッドシートのメニューで [ツール] → [スクリプトエディタ] を選択。
※ 2022/06/22追記 現在は [拡張機能] → [App Script] のようです。
image.png

4.2. スクリプトを名前を付けて保存

スクリプトエディタが開いたら、適当な名前で保存しておきます。スプレッドシートと同じでも違っていてもOKです。
image.png

4.3. サービスを追加

左に見える サービス 欄の「+」を押します。
Admin SDK API を選択すると、ID「AdminDirectory」が現れます。これを追加してください。
image.png

4.4. コードを記述

デフォルトの コード.gs の内容は消去して、こちらをコピペしてください。
ドメイン名は自動取得するため、特にこの中を直していただかなくても動くはずです。

コード.gs
// 全グループの、全メンバーアドレス取得

// スプレッドシートを開いた際に、メニューに「スクリプト実行」を追加する
function onOpen() {
  SpreadsheetApp.getUi()
  .createMenu("スクリプト実行")
  .addItem("メンバーアドレス一覧取得", "confirmLoadGroupMembersAddress")
  .addToUi();
}

// 確認を表示してOKなら一覧読み込み
function confirmLoadGroupMembersAddress() {
  // ドメイン一覧を取得
  const domains = getDomains();

  // 開始確認
  const ui = SpreadsheetApp.getUi();

  // 読み込み処理
  var res = ui.alert(
    "確認",
    "このシートを消去して全グループの情報を読み込みます。\nよろしいですか?",
    ui.ButtonSet.OK_CANCEL);

  if (res == "OK") { 
    loadGroupMembersAddress(domains);

    ui.alert(
      "終了",
      "完了しました。OKを押すと表示されます。",
      ui.ButtonSet.OK);
  } else {
    ui.alert(
      "キャンセル",
      "キャンセルしました",
      ui.ButtonSet.OK);
  }
}

// 対象とするドメイン一覧を取得
function getDomains() {
  // 現在ログインしているユーザー情報を元に、全ドメイン一覧を取得
  var mail = Session.getActiveUser().getEmail();
  var user = AdminDirectory.Users.get(mail);
  var domains = AdminDirectory.Domains.list(user.customerId).domains;

  // ドメイン名のリストを作成して返す
  var list = [];
  for (var i = 0; i < domains.length; i++) {
    var domain = domains[i];
    list.push(domain.domainName);
  }
  return list;
}

// 全グループについて取得してシートに出力
function loadGroupMembersAddress(domains)
{
  // ヘッダーの定義
  const header = ["GroupAddress", "Name", "DirectMembersCount", "UserAddress"];

  // 追加される行を保持する配列
  var rows = [];

  // ヘッダ行を出力
  rows.push(header);

  // ドメインごとにループ
  for (var i = 0; i < domains.length; i++) {
    var domain = domains[i];

    // 取得数制限にかかる際のページング
    var groupNextPageToken = null;

    // グループごとのループ
    do {
      var grouplist = AdminDirectory.Groups.list({
        domain: domain,
        nextPageToken: groupNextPageToken
      });

      // グループが存在しなければ終了
      if (!grouplist.groups) break;

      // 次ページがあるときはトークンが入る
      groupNextPageToken = grouplist.nextPageToken;

      // 各グループについての処理
      for(var j = 0; j < grouplist.groups.length; j++){           
        var group = grouplist.groups[j];
        var memberNextPageToken = null;

        // グループに所属するメンバーの取得
        do {
          var memberlist = AdminDirectory.Members.list(group.email, {
            pageToken: memberNextPageToken
          });

          // memberlistが無ければ終了
          if (!memberlist || !memberlist.members) break;

          // 次ページがあるときはトークンが入る
          memberNextPageToken = memberlist.nextPageToken;

          // 今回(このページ)で取得できた分を一覧に追加
          for (var k = 0; k < memberlist.members.length; k++){
            var member = memberlist.members[k];

            var cols = [];         
            cols.push(group.email);
            cols.push(group.name);
            cols.push(group.directMembersCount);
            cols.push(member.email);

            rows.push(cols);
          }
        } while (memberNextPageToken);
      }
    } while (groupNextPageToken);
  }

  // 以降、スプレッドシートへの出力
  // アクティブなシート取得
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

  // 左上セルを基準に、最終行まで削除(書式は残す)
  sheet.getRange(1, 1, sheet.getMaxRows(), header.length).clearContent();

  // 書き込み
  sheet.getRange(1, 1, rows.length , header.length).setValues(rows);
}

5. 実行

スクリプトの準備ができたら、スプレッドシートを再読み込みすると動きます。
スプレッドシートを開いてしばらく待つと [スクリプト実行] というメニューが現れます。
この中の [メンバーアドレス一覧取得] を選ぶと実行されます。
image.png

5.1. (初回のみ)許可

初回は承認が必要となります。
許可を求められたら、続行します。
image.png

アカウントへのアクセスに許可を出します。
image.png

下記のものに許可が必要となっています。

  • 顧客に関連するドメインの情報 (グループ表示対象となるドメイン一覧取得のため)
  • ドメインのグループの表示 (グループ一覧を取得するため)
  • ドメインのユーザーに関する情報の参照 (グループメンバー取得のため)
  • Googleドライブのスプレッドシートの表示、編集、作成、削除 (シートへの出力のため)

初回、許可をした後は実行自体はされないので、もう一度 [スクリプト実行] から実行します。

5.2. 取得確認

実行するとシートを削除してよいか聞かれます。
[OK] を押すと、今開かれているシートの A:D 列の内容が消去され、そこに一覧が現れます。
(書式は消去しません。)

image.png

5.3. 結果

動作すれば一覧が表示されます。
DirectMembersCount はグループ内のメンバー数が入ります。
その行数分のメンバーアドレスが取得されるはずです。

image.png

  1. ひさ 氏. "Google Apps Scriptを用いてグループアドレスメンバーを取得". Sanwa Systems Tech Blog. https://tech.sanwasystem.com/entry/2015/04/13/201535 , 2015-04-13. 2

6
7
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7