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

如何准确获取Google Workspace用户上次修改密码的日期

Google Workspace获取用户上次修改密码日期方案求助

我们正在从AD迁移,改用Google Workspace作为LDAP服务。我的其中一项任务是将AD上的现有工具迁移适配到Google Workspace,其中一个工具的功能是在用户密码到期前14天、7天分别向用户发送提醒,同时在到期前4天向IT管理员发送预警,避免用户账号被锁定。
我之前在Windows环境下通过PowerShell和LDAP实现了该工具,现在尝试用Google App Scripts重新实现。我发现Directory API不对外暴露用户的该项元数据,因此需要使用Admin Report API搜索日志中名为CHANGE_PASSWORD的事件,进而构建包含用户邮箱地址和上次修改密码时间的数组。
目前我已实现该功能,加载Web应用时可按需生成表格,以HTML形式输出用户邮箱和密码剩余有效天数,但我发现我们组织共有120名用户,列表中仅显示78名用户的相关数据。经排查我发现Google Admin reports的报告模块仅保留6个月的日志数据,对我而言报告模块不是确定用户上次修改密码时间的可靠来源。有没有其他方案可以准确获取Google Workspace用户上次修改密码的日期?

请注意:你需要在脚本中添加Admin SDK API服务,且运行脚本的用户必须拥有当前域名的报告相关权限。该代码为概念验证版本并未打磨完善。

现有实现代码

code.gs

const maxPasswordAge = 90;

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function getListOfUsers() {
 const userKey = 'all';
  const applicationName = 'admin';
  const optionalArgs = {
    eventName: 'CHANGE_PASSWORD'
  };

  const logs = AdminReports.Activities.list(userKey, applicationName, optionalArgs);
  const activities = logs.items;
  
  if (activities && activities.length > 0) {
    var passwordLastChanged = new Object();
    for (i = 0; i < activities.length; i++) {
      const activity = activities[i];
      const key = activity.events[0].parameters[0]['value'];
      const value = activity.id.time;

      // If the key does not exist then add it
      if (!passwordLastChanged.hasOwnProperty(key)) {
        passwordLastChanged[key] = value;
      }
    }
  } else {
    Logger.log('No results found.');
  }

  // You will now have an object with emailaddress:Date last Changed

  const todaysDate = new Date();
  
  // Change the date to a number of days till it expires from today's date
  for (const [key, value] of Object.entries(passwordLastChanged)) {
    const dateLastChange = new Date(value);
    const milliBetweenDate = todaysDate - dateLastChange;
    const diffInDays = milliBetweenDate / (1000 * 3600 * 24);
    passwordLastChanged[key] = (maxPasswordAge - diffInDays).toFixed(1);

  }

  // Change the object to a sorted array based on the days left till password expires
  const entries = Object.entries(passwordLastChanged);
  const sorted = entries.sort((a, b) => a[1] - b[1]);

  return sorted;

}

Index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
<style type="text/css">
body {background-color: gray;}
.tg {border-collapse:collapse;border-spacing:0;margin:0px auto;}
.td {border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px; overflow:hidden;padding:10px 5px;word-break:normal; color: floralwhite;}
.col1, .col2, .col3  {text-align:left;vertical-align:top}
.col4, .col5 {text-align:center;vertical-align:top}
</style>
<table id="myTable" class="tg">
<tbody>
  <tr>
    <td class="col3">Email</td>
    <td class="col5">Days Left</td>    
  </tr>
</tbody>
</table>

<script
src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script>
  
  // The code in this function runs when the page is loaded.
  $(function() {
    google.script.run.withSuccessHandler(addUsersToTable).getListOfUsers();
  });

  function addUsersToTable(userArray) {
    for (var i = 0; i < userArray.length; i++) {
      $('#myTable > tbody:last-child').append('<tr><td class="col3">' + userArray[i][0] + '</td><td class="col5">' + userArray[i][1] + '</td></tr>');
    }
  }

</script>
  </body>
</html>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 11:45:01