Google Apps Scriptで共有ドライブ一覧取得とユーザ差し替え【GAS】

人事異動の季節になるとやらざるを得ない業務の一つとして、グループアドレスのメンバーの入れ替えおよび組織変更があれば「共有ドライブに対するアクセス権の変更」です。少数ならば手作業で行えば良いのですが、多数ある場合活躍するのがGoogle Apps Scriptです。

今回は後者の共有ドライブへのアクセス権が付与されてるアドレスを一括で差し替えるケースです。組織変更で対象のドライブに対するアクセス権をこれまでのグループアドレス(部署)から別のグループアドレスへ変更するといった場合、多数ドライブがあると漏れが生じます。これを自動化するのが目的です。

Google Apps Scriptで共有ドライブをコントロールする【GAS】

今回利用するスプレッドシート

今回のスクリプトはDrive APIを利用して共有ドライブへ付与されてるアドレスの追加と削除を一括で行う機能と、現在の共有ドライブの一覧を取得する機能も装備しています。

事前準備

Drive APIを有効にする

今回のスクリプトはDrive API v2を利用します。よって、以下の手順に従って、Drive APIをONにする必要性があります。

  1. スクリプトエディター画面に於いて、サービス欄の+記号をクリック
  2. Drive APIを探しだして、選択する
  3. 追加ボタンをクリックする

これでDrive APIがGoogle Apps ScriptでDrive APIを使えるようになります。

図:Drive APIをオンにした

保持可否グループアドレス一覧の用意

スプレッドシートのsharedDriveシートには、スクリプトの機能で現在の共有ドライブの一覧とアクセス出来るユーザのアドレス・権限がリストアップされます。メニューからアクション=>共有ドライブ一覧取得で取得されます。

そのシートに於いて「保持可否」という列での検証で使うアドレスです。このアドレスは通常は外さない「固定で割り当ててるアドレス」の一覧で、sharedDriveの一覧取得後の関数にてvlookupで参照され、存在すれば表示される仕組みです。

変更対象にチェックを入れれば変更はできますが、通常はこれらのアドレスは変更対象とはしないものなので(例えばadminのアドレスや部署紐付けのグループアドレス等)、次のフェーズの権限の付与・削除時の「変更対象のチェック入力」での判断基準となります。

表が完成したら、メニューからアクション=>ドライブアクセス権一括変更を実施すると、古いアドレスは削除され、新しいアドレスが追加され差し替わるという仕組みです。

この保持可否のアドレス以外で表示されてるアドレスに対して「新アドレス」と「変更対象」にチェックを入れて準備は完了です。なお、このプログラムは以下のような仕様になっています。

  • 変更対象にチェックを入れていないレコードは処理対象外としてスルーされます。
  • メールアドレスが空の場合は、アドレス削除処理の対象外としてスルーされます。
  • 新アドレスが空の場合は、アドレス追加処理の対象外としてスルーされます。

図:この表を完成させるのが重要です

ソースコード

本プログラムは管理者権限が実質必要になっています。管理者権限が無い場合、そのユーザが見える範囲の共有ドライブにしかアクセスができません。管理者の場合はアクセス権限がなくとも、useDomainAdminAccessがTrueとなっている為、ドライブにアクセスすることが可能になっています。

共有ドライブ一覧とロール等を一括取得

まずは、現在のGoogle Workspace上にある全ての共有ドライブの一覧・アクセス権限・メールアドレス等を取得する必要があります。

function getSharedDriveList() {
  //Drive API用変数
  let pageToken;
  let array = [];

  do{
    //共有ドライブの一覧を取得する
    let sharedDrives = Drive.Drives.list({
      maxResults: 100,
      useDomainAdminAccess: true,
      hidden: false,
      pageToken:pageToken,
    });

    //ドライブの情報を取得する
    let sharedDrivesItems = sharedDrives.items;

    //ドライブの名前だけ取得する
    for(var i = 0;i<sharedDrivesItems.length;i++){
      //レコードを一個取り出す
      let rec = sharedDrivesItems[i];

      //ドライブの名称を取得する
      let drivename = rec.name

      //ドライブのIDを取得する
      let driveid = rec.id

      //ドライブのメンバー一覧を取得する
      const args = {
        supportsAllDrives: true
      };

      let pList = Drive.Permissions.list(driveid, args);
      let pmember = pList.items;

      //メンバー一覧のアドレスとロールを取得する
      for(var j = 0;j<pmember.length;j++){
        //レコードを取り出す
        let member = pmember[j];

        //ロールを取り出す
        let role = member.role;

        //メンバーアドレスを取得する
        let maddress = member.emailAddress

        let temparr = [
          drivename,
          driveid,
          maddress,
          role
        ]

        array.push(temparr)

      }
    }

    //ページトークンを取得する
    pageToken = sharedDrives.nextPageToken;

  }while(pageToken)

  //データを一括消去
  let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sharedDrive");
  sheet.getRange("A2:G").clearContent();

  //取得情報をシートに一括書き出し
  let lastColumn = array[0].length;   //カラムの数を取得する
  let lastRow = array.length;         //行の数を取得する
  sheet.getRange(2,1,lastRow,lastColumn).setValues(array); 

  //A列を昇順でソート
  sheet.getRange("A2:G").sort({column:1, accending: true})

  //vlookup式を定義反映
  let setformula = "=arrayformula(iferror(vlookup($C$2:$C,special!$B$2:$B,1,false)))"
  sheet.getRange("E2").setValue(setformula);
}
  • 共有ドライブ一覧は1度に100件までしか取得できません。nextPageTokenを取得して次のページを取得し次の100件を取得するようにしています。
  • Drive.Drives.listにて共有ドライブ一覧を一括で取得することが可能です。
  • Drive.Permissions.listにて取得したドライブのIDとsupportAllDrivesのオプションでアクセス可能ユーザメールアドレスとロールを取得します。
  • 配列に情報を追加してsharedDriveシートに一括で書き出しします。
  • 書き出したsharedDriveのデータをA列基準(ドライブ名)で昇順ソートさせています。
  • 最後にE2セルにメールアドレスとspecialシートのメアド列を参照するarrayformulaでvlookupを一括で行わせる数式を入れてあげます。
  • 数式はsetFormulaでなくともsetValueでそのまま入力が可能です。
  • useDomainAdminAccessをTrueとしてるので管理者権限が必要です。これをfalseとした場合にはユーザ権限で取得可能な範囲のドライブ一覧のみが取得されることになります。

Arrayformula関数で配列数式の便利さを知ろう

共有ドライブの特定アドレスを差し替える

前述のドライブ一覧と新アドレスおよび変更対象のチェックをもとに、対象ドライブから旧アドレスを削除し、新アドレスを同じ権限で追加する差し替えの処理を実行します。

function setSharedDriveAssign(){
  //変更リストを取得する
  let ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sharedDrive");
  let sheet = ss.getRange("A2:G").getValues();

  //変更対象のレコードだけアクセス権限対象を差し替える
  for(let i = 0;i<sheet.length;i++){
    //レコードを一個取り出す
    let rec = sheet[i];

    //変更対象かどうか?
    let changeflg = rec[6];
    if(changeflg == false || changeflg == ""){
      //処理をスルーする
      continue;
    }

    //対象のドライブのIDを取得
    let targetid = rec[1];

    //削除対象のアドレスを取得
    let deletemail = rec[2];

    //新規に割り当てるアドレスを取得
    let setmail = rec[5];

    //対象の共有ドライブからdeletemailを削除
    if(deletemail == ""){
      //処理をスルーする
    }else{
      let ret = deleteUser(deletemail,targetid)
    }
    
    //対象の共有ドライブへsetmailを追加
    if(setmail == ""){
      //セット対象が無いので処理をスルーする
      continue;
    }else{
      var resource = {
        role: rec[3],
        type:"user",
        value:setmail
      }
      
      Drive.Permissions.insert(
        resource, 
        targetid, 
        {
          sendNotificationEmails:false,
          supportsAllDrives:true,
          useDomainAdminAccess:true
        }
      );
    }
  }
}

//共有ユーザを削除する
function deleteUser(user,folderid){
  try{
    var shareuser = Drive.Permissions.list(folderid, {maxResults:100,supportsAllDrives:true}) ;
    var userlist = shareuser.items;

    //permissionIdを取得する
    var permissionId = "";

    for(var i = 0;i<userlist.length;i++){
      //レコードを一個取り出す
      let rec = userlist[i];

      //メアドが一致するかどうか?
      if(user == rec.emailAddress){
        permissionId = rec.id;
        break;
      }
    }

    if(permissionId == ""){
      //ユーザが見つからなかった
      return "対象のユーザが見つかりませんでした。"
    }else{
      //deleteで削除
      Drive.Permissions.remove(folderid, permissionId,{supportsAllDrives:true});

      //結果を返す
      return 0;
    }
  }catch(e){
    return e.message;
  }
}
  • 前述の仕様に従って、変更対象にチェックがあるものを処理対象とし、それ以外は処理をスルーします。
  • deleteUser関数で対象のドライブに付与されてるユーザのpermissionIdを取得し、そのIDを持ってDrive.Permissions.removeでアドレスを削除しています。
  • 次に新アドレスがある場合は、Drive.Permissions.insertにて対象のドライブに新アドレスを同じroleで追加します。
  • 削除するだけならば新アドレスを空にしたままとし、新規に追加のみならばメールアドレスを空にして新アドレスを入れておけば実現可能です。

関連リンク

 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)