在Google-Apps-Script中使用Directory API,如何获取组内的组

Ser*_*sas 3 google-apps-script

我正在使用一个脚本,该脚本可获取域中的所有组并列出这些组中的所有用户。

我改写了这个脚本,因为GroupsManager不推荐使用,所以我的旧脚本很快就会停止工作。

一切运行良好(尽管此API速度很慢...),但是我遇到的问题是,某些组不仅具有用户,而且还包括其他组...其中一些仅具有子组(而没有用户(说话方式) !)

我找不到任何办法来解决这种情况,list方法返回用户,它完全忽略了内部的组。

所以我的问题是:

有没有一种方法可以将小组归入小组?我是否缺少明显的东西?

在下面的信息中,我使用了代码来列出电子表格中各组的所有成员,即1张/组,以便以后可以更快,更轻松地操作这些数据。我使用背景颜色标志作为跟踪器来处理(相对)小的批处理操作和计时器触发器,直到完成为止。(是的,我们域中有很多组;-)

function listGroupMembers() {
  var start = new Date().getTime();
  var ss = SpreadsheetApp.openById('1k-o4IVKEhW2zkk_________f2rH4UUt3OAC8I0ZoM');// set your SS ID (runs with timer trigger > needs to open by ID
  var pageToken, page;
  var count=0;
  var groupList = [];
  do {
    page = AdminDirectory.Groups.list({
      domain: 'xxxxx.be',
      maxResults: 100,
      pageToken: pageToken
    });
    var gr = page.groups;
    if (gr) {
      for (var i = 0; i < gr.length; i++) {
        var group = gr[i];
        count++;
        //Logger.log(group);
        groupList.push([group.email,count])
      }
    } else {
      Logger.log('No group found.');
    }
    pageToken = page.nextPageToken;
  } 
  while (pageToken);
  try{
    var GroupAddress = ss.getSheetByName('GroupAddress');// if GroupAddress Sheet already exist, open it
    Logger.log('Use existing sheet "'+GroupAddress.getName()+'"');
  }catch(err){
    Logger.log('create sheet "GroupAddress"');
    ss.deleteSheet(ss.getSheets()[0]);
    var GroupAddress = ss.insertSheet('GroupAddress',0); //else create it as first sheet 
  }
  GroupAddress.getDataRange().clearContent();
  ss.getSheetByName('GroupAddress').getRange(1,1,groupList.length,groupList[0].length).setValues(groupList);

  var groupNames = ss.getSheetByName("GroupAddress").getDataRange().getValues();
  var groupDone = ss.getSheetByName("GroupAddress").getDataRange().getBackgrounds();
  var progress;
  for(var n in groupNames){
    if(groupDone[n][0] != 'white' || (new Date().getTime()-start)/60 > 5000){ // limit to 5 seconds + 1 group
      continue;
    }
    try{
      var outputSheet = ss.insertSheet(groupNames[n][0],Number(n)+1)
      }catch(err){
        var outputSheet = ss.getSheetByName(groupNames[n][0]);
      }
    var group = GroupsApp.getGroupByEmail(groupNames[n][0]);
    //Logger.log('groupNames[n][0] = '+groupNames[n][0]);
    try{
      var users = group.getUsers();
      var output = [];
      for (var i in users){ 
        var user = AdminDirectory.Users.get(users[i].getEmail());
        output.push([Number(i)+1,user.name.fullName, user.primaryEmail,user.aliases!=null?user.aliases:'',new Date(user.creationTime),user.isAdmin,new Date(user.lastLoginTime)]);
      }
      ss.getSheetByName("GroupAddress").getRange(Number(n)+1,1).setBackground('#fff2cc');
      SpreadsheetApp.flush();
      if(output.length>0){
        output.push(['durée :',parseInt((new Date().getTime()-start)/60),'millisecondes','','','','']);
        outputSheet.getRange(1,1,output.length,output[0].length).setValues(output);
      }
    }catch(err){
      continue}
  }
  groupDone = ss.getSheetByName("GroupAddress").getDataRange().getBackgrounds();
  for(progress = groupDone.length-1;progress>=0;progress--){
    if(groupDone[progress][0]!='white'){break};
  }
  Logger.log(n+'='+progress+'?');
  if(n==progress){
    MailApp.sendEmail(Session.getEffectiveUser().getEmail(),'All jobs done in GroupList','All tasks completed on '+new Date().toLocaleString());
    var trig = ScriptApp.getProjectTriggers();
    for(var t in trig){
      try{
      ScriptApp.deleteTrigger(trig[t]);
      }catch(e){}
    }
  }else{
    ScriptApp.newTrigger('listGroupMembers').timeBased().after(3000).create();// wait 3 secs and continue
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑

感谢Göran的回答,我有了一个版本,可以获取所有组(包括子组)的所有成员。

我稍稍更改了他的代码,以满足我的要求,并且我还需要将每张纸上的单元格数量限制为我所需的数量,因为总数(1000 * 26个单元格/张)超过了200000个单元格的限制(我还有更多超过100张)。

下面的完整代码适用于任何有兴趣的人(包括菜单和一些实用程序):

function onOpen() {
  var menu = SpreadsheetApp.getUi().createMenu("Utilitaires INSAS")
  .addItem("reset colors", "resetColors")
  .addItem("create groupUser lists", "listGroupMembers")
  .addItem("delete all sheets", "delsheets");
  menu.addToUi();
}

function listGroupMembers() {
  var start = new Date().getTime();
  var ss = SpreadsheetApp.openById('1k-o4IVKEhW2zkkEu0gAvb92rQf2rH4UUt3OAC8I0ZoM');// set your SS ID (runs with timer trigger > needs to open by ID
  var pageToken, page;
  var count=0;
  var groupList = [];
  do {
    page = AdminDirectory.Groups.list({
      domain: 'insas.be',
      maxResults: 100,
      pageToken: pageToken
    });
    var gr = page.groups;
    if (gr) {
      for (var i = 0; i < gr.length; i++) {
        var group = gr[i];
        count++;
        //Logger.log(group);
        groupList.push([group.email,count])
      }
    } else {
      Logger.log('No group found.');
    }
    pageToken = page.nextPageToken;
  } 
  while (pageToken);
  try{
    var GroupAddress = ss.getSheetByName('GroupAddress');// if GroupAddress Sheet already exist, open it
    Logger.log('Use existing sheet "'+GroupAddress.getName()+'"');
  }catch(err){
    Logger.log('create sheet "GroupAddress"');
    ss.deleteSheet(ss.getSheets()[0]);
    var GroupAddress = ss.insertSheet('GroupAddress',0); //else create it as first sheet 
  }
  GroupAddress.getDataRange().clearContent();
  ss.getSheetByName('GroupAddress').getRange(1,1,groupList.length,groupList[0].length).setValues(groupList);

  var groupNames = ss.getSheetByName("GroupAddress").getDataRange().getValues();
  var groupDone = ss.getSheetByName("GroupAddress").getDataRange().getBackgrounds();
  var progress;
  for(var n in groupNames){
    if(groupDone[n][0] != 'white' || (new Date().getTime()-start)/60 > 5000){ // limit to 5 seconds + 1 group
      continue;
    }
    Logger.log('groupNames[n][0] = '+groupNames[n][0]);
    try{
      var outputSheet = ss.getSheetByName(groupNames[n][0]);
      Logger.log('sheet '+outputSheet.getName()+' created');
      }catch(err){
        var outputSheet = ss.insertSheet(groupNames[n][0],ss.getSheets().length+1);
      }
    try{
      var users = getUsersInGroup(groupNames[n][0]);
      var output = [];
      for (var i in users){ 
        var user = users[i];
//        Logger.log(user);
        output.push([Number(i)+1,user.email,user.role,user.groupName]);
      }
      ss.getSheetByName("GroupAddress").getRange(Number(n)+1,1).setBackground('#fff2cc');
      SpreadsheetApp.flush();
      if(output.length>0){
        output.push(['Ex.T = '+parseInt((new Date().getTime()-start)/60)+' mS','','','']);
        outputSheet.getRange(1,1,output.length,output[0].length).setValues(output);
        outputSheet.deleteRows(output.length+2, outputSheet.getMaxRows()-output.length-4);
        outputSheet.deleteColumns(6, outputSheet.getMaxColumns()-6);
      }
    }catch(err){
      continue}
  }
  groupDone = ss.getSheetByName("GroupAddress").getDataRange().getBackgrounds();
  for(progress = groupDone.length-1;progress>=0;progress--){
    if(groupDone[progress][0]!='white'){break};
  }
  Logger.log(n+'='+progress+'?');
  if(n==progress){
    MailApp.sendEmail(Session.getEffectiveUser().getEmail(),'All jobs done in GroupList','All tasks completed on '+new Date().toLocaleString());
    var trig = ScriptApp.getProjectTriggers();
    for(var t in trig){
      try{
      ScriptApp.deleteTrigger(trig[t]);
      }catch(e){}
    }
  }else{
    ScriptApp.newTrigger('listGroupMembers').timeBased().after(10000).create();// wait 3 secs and continue
  }
}

function resetColors(){
  var ss = SpreadsheetApp.getActive();
  ss.getSheets()[0].getDataRange().setBackground(null);
}

function getUsersInGroup(rootGroup) {
  var groupTreeUsers = [];
  var groups = [];
  groups.push(rootGroup);

  while (groups.length > 0) {
    var currentGroup = groups.pop();
    var groupName = AdminDirectory.Groups.get(currentGroup).name;
    var groupMembers = getAllMembers_(currentGroup);

    for (var i in groupMembers) {
      if (groupMembers[i].type == 'USER') {
        var groupMember = groupMembers[i];
        groupMember['groupName'] = currentGroup;
        groupTreeUsers.push(groupMember)
      }
      else if (groupMembers[i].type == 'GROUP') {
        groups.push(groupMembers[i].email)
      }
    }
  }
  Logger.log('There are %s user members in %s (including sub groups)', groupTreeUsers.length, rootGroup);
  return groupTreeUsers;
}

function getAllMembers_(group) {
  var memberPageToken, memberPage;
  var members = [];
  do {
    memberPage = AdminDirectory.Members.list(group, {
      maxResults: 200,
      pageToken: memberPageToken
    });
    var pageMembers = memberPage.members;
    if (pageMembers) {
      for (var j =0; j < pageMembers.length; j++) {
        members.push(pageMembers[j]);
      }
    }
    memberPageToken = memberPage.nextPageToken;
  } while (memberPageToken);
  return members;
}

function delsheets(){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var numSheets = ss.getNumSheets();// check how many sheets in the spreadsheet
  for (var pa=numSheets-1;pa>0;pa--){ 
    if(ss.getSheets()[pa].getSheetName()!='GroupAddress'){
      ss.deleteSheet(ss.getSheets()[pa]); // delete sheets begining with the last one
      Utilities.sleep(100);
    }
  }
  SpreadsheetApp.flush();
} 
Run Code Online (Sandbox Code Playgroud)

Gör*_*ran 5

AdminDirectory MembersCollection可能就是您想要的。

示例片段:

var members = AdminDirectory.Members.list('testgroup@example.com').members;
for (var i = 0; i < members.length; i++) {
  var member = members[i];
  switch (member.type) {
    case 'USER':
      Logger.log('%s is a user', member.email);
      break;
    case 'GROUP':
      Logger.log('%s is a group', member.email);
      break;
    default:
      Logger.log('This will never happen');
  }
Run Code Online (Sandbox Code Playgroud)

我的一些客户的组包含包含组的组...形成任意深度的组树。我使用以下代码来获取所有用户成员,例如:

function walkTreeStack() {
  var rootGroup = 'testgroup@example.com';
  var groupTreeUsers = [];
  var groups = [];
  groups.push(rootGroup);

  while (groups.length > 0) {
    var currentGroup = groups.pop();
    var groupName = AdminDirectory.Groups.get(currentGroup).name;
    var groupMembers = getAllMembers_(currentGroup);

    for (var i in groupMembers) {
      if (groupMembers[i].type == 'USER') {
        groupTreeUsers.push([groupName, groupMembers[i].email])
      }
      else if (groupMembers[i].type == 'GROUP') {
        groups.push(groupMembers[i].email)
      }
    }
  }

  Logger.log('There are %s user members in %s (including sub groups)', groupTreeUsers.length, groupName);
}

function getAllMembers_(group) {
  var memberPageToken, memberPage;
  var members = [];
  do {
    memberPage = AdminDirectory.Members.list(group, {
      maxResults: 200,
      pageToken: memberPageToken
    });
    var pageMembers = memberPage.members;
    if (pageMembers) {
      for (var j =0; j < pageMembers.length; j++) {
        members.push(pageMembers[j]);
      }
    }
    memberPageToken = memberPage.nextPageToken;
  } while (memberPageToken);
  return members;
}
Run Code Online (Sandbox Code Playgroud)

如果以递归方式进行,则速度会稍快一些,但我怀疑如果存在大量子组和用户成员,脚本可能会由于内存不足而崩溃:

function getGroupTreeMembers() {
  var rootGroup = 'testgroup@example.com';
  var groupTreeUsers = [];

  walkTreeRecursive_(rootGroup, groupTreeUsers);

  var groupName = AdminDirectory.Groups.get(rootGroup).name;  
  Logger.log('There are %s user members in %s (including sub groups)', groupTreeUsers.length, groupName);
}

function walkTreeRecursive_(rootGroup, groupTreeUsers) {
  var groupName = AdminDirectory.Groups.get(rootGroup).name;
  var groupMembers = getAllMembers_(rootGroup);
  var groups = [];
  for (var i in groupMembers) {
    if (groupMembers[i].type == 'USER') {
      groupTreeUsers.push([groupName, groupMembers[i].email])
    }
    else if (groupMembers[i].type == 'GROUP') {
      groups.push(groupMembers[i].email)
    }
  }
  for (var i in groups) {
    walkTreeRecursive_(groups[i], groupTreeUsers);
  }
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请访问:

https://developers.google.com/admin-sdk/directory/v1/reference/members#resource