You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Script无法通过SKU ID获取带付费许可的用户

问题详情
  • 使用Google Script管理学校IT环境,开发脚本用于排查离校学生并移除其付费许可,但无法通过SKU ID筛选出拥有对应许可的学生,仅能识别免费版Google Workspace Fundamentals(SKU ID:1010070001)。
  • 学校付费许可由教育厅通过经销商采购,尝试使用经销商提供的SKU ID也无法找到对应许可用户。
  • 调用licensing.licenseAssignments.get接口时持续报错:GoogleJsonResponseException: API call to licensing.licenseAssignments.get failed with error: Backend Error
排查脚本
// --- CONFIGURATION ---

const TARGET_OU_PATH = '/TargetOU'; 
const MAX_RESULTS = 500;

const PRODUCT_ID = 'Google-Apps';

const TARGET_SKUS = [
    { id: '1010310008', name: 'Education Plus (Global ID)' }, 
];

// ---------------------------------------------

function getLicensedAssignmentsByEmail(customerId, productId, targetSkuIds) {
  const licensedAssignments = new Map();
  let pageToken = null;
  let attempts = 0;
  
  do {
    const options = {
      maxResults: MAX_RESULTS, 
      pageToken: pageToken
    };
    
    try {
      const response = AdminLicenseManager.LicenseAssignments.listForProduct(
        productId, 
        customerId, 
        options
      );

      const assignments = response.items || [];
      
      for (const assignment of assignments) {
        if (targetSkuIds.has(assignment.skuId)) {
             licensedAssignments.set(assignment.userId, assignment.skuId);
        }
      }

      pageToken = response.nextPageToken;

    } catch (e) {
      const errorString = e.toString();
      if (errorString.includes('Backend Error') && attempts < 3) {
         attempts++;
         const delay = 5000 * attempts; 
         Logger.log(`WARNING: Batch fetch failed, retrying in ${delay / 1000}s. Error: ${errorString}`);
         Utilities.sleep(delay);
      } else {
        Logger.log(`FATAL ERROR during batch license fetch: ${errorString}`);
        return null;
      }
    }
    
  } while (pageToken);

  return licensedAssignments;
}

function reportUsersWithLicense() {
  
  let pageToken;
  let usersWithTargetSkus = 0;
  let usersScanned = 0;
  let CUSTOMER_ID;

  try {
    const customer = AdminDirectory.Customers.get('my_customer');
    CUSTOMER_ID = customer.id;
  } catch (e) {
    Logger.log(`FATAL ERROR: Could not retrieve Customer ID. Error: ${e.toString()}`);
    return;
  }
  
  const TARGET_SKU_IDS = new Set(TARGET_SKUS.map(s => s.id));
  
  const LICENSED_ASSIGNMENTS = getLicensedAssignmentsByEmail(CUSTOMER_ID, PRODUCT_ID, TARGET_SKU_IDS);
  
  if (!LICENSED_ASSIGNMENTS) {
    Logger.log('Cannot proceed due to fatal error in license fetching.');
    return;
  }
  
  do {
    const options = {
      customer: 'my_customer',
      query: `orgUnitPath='${TARGET_OU_PATH}'`,
      maxResults: MAX_RESULTS,
      pageToken: pageToken
    };

    try {
      const response = AdminDirectory.Users.list(options);
      const users = response.users;

      if (!users || users.length === 0) {
        break;
      }

      for (const user of users) {
        usersScanned++;
        const anonUserId = `User_${String(usersScanned).padStart(4, '0')}`;
        const userEmail = user.primaryEmail; 
        
        if (LICENSED_ASSIGNMENTS.has(userEmail)) {
          const assignedSku = LICENSED_ASSIGNMENTS.get(userEmail);
          
          const licenseInfo = TARGET_SKUS.find(s => s.id === assignedSku) || { name: 'Unknown Target SKU' };
          
          Logger.log(`${anonUserId}, ${assignedSku}, ${licenseInfo.name}`);
          usersWithTargetSkus++;
        }
      }

      pageToken = response.nextPageToken;

    } catch (directoryError) {
      Logger.log(`FATAL ERROR during Directory API call: ${directoryError.toString()}`);
      break;
    }

  } while (pageToken);

  Logger.log(`
--- Report Complete ---`);
  Logger.log(`Total Users Scanned: ${usersScanned}`);
  Logger.log(`Total Users Found with License: ${usersWithTargetSkus}`);
}

内容的提问来源于stack exchange,提问作者Leon Sangster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 23:42:42