A curated collection of production-ready scripts to automate your Google Workspace administration. Copy, paste, and deploy in seconds.
Automate lifecycle provisioning, deprovisioning, and updates.
Reads user data from a Google Sheet and creates accounts in the Admin Console. Perfect for onboarding batches of new hires/students.
function bulkCreateUsers() {
const SPREADSHEET_ID = 'YOUR_SHEET_ID_HERE';
const SHEET_NAME = 'Users';
const sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
const data = sheet.getDataRange().getValues();
// Skip header row
for (let i = 1; i < data.length; i++) {
const [firstName, lastName, email, password] = data[i];
try {
const user = {
primaryEmail: email,
name: {
givenName: firstName,
familyName: lastName
},
password: password
};
AdminDirectory.Users.insert(user);
Logger.log(`Created user: ${email}`);
sheet.getRange(i + 1, 5).setValue('Success');
} catch (e) {
Logger.log(`Failed to create ${email}: ${e.message}`);
sheet.getRange(i + 1, 5).setValue(`Error: ${e.message}`);
}
}
}
Highly Recommended. This advanced script effectively finds "zombie" accounts by cross-referencing Admin Directory last-login data with actual Login Audit Logs. Includes automated email reporting.
// Calculates inactivity based on LAST LOGIN time found in Reports API
// Full script is too large to display. Please download using the button above.
/*
* CONFIGURATION
* ----------------
* 1. Enable Admin SDK API
* 2. Enable Admin Reports API
* 3. Replace 'YOUR_EMAIL' with the admin email to receive reports
*/
function auditInactiveUsers() {
// ... download to view full logic ...
Logger.log("Starting 180-day audit...");
}
Standardize your brand. Sets a specific HTML signature for a user via the Gmail API.
function updateUserSignature() {
const userEmail = 'user@domain.com';
const newSignature = '<div>Best regards,<br><strong>IT Support</strong></div>';
try {
// Requires Gmail API -> Users.Settings.SendAs.update
Gmail.Users.Settings.SendAs.update(
{ signature: newSignature },
userEmail,
userEmail
);
Logger.log('Signature updated for ' + userEmail);
} catch (e) {
Logger.log('Error: ' + e.message);
}
}
function auditInactiveUsers365() {
// Configuration
var INACTIVE_DAYS_THRESHOLD = 365;
var SHEET_NAME = 'Inactive Users (365 Days)';
// Get users who haven't logged in
var users = AdminDirectory.Users.list({
customer: 'my_customer',
query: 'lastLoginTime < ' + getThresholdDate(INACTIVE_DAYS_THRESHOLD),
maxResults: 500
}).users;
if (!users || users.length === 0) {
Logger.log('No inactive users found.');
return;
}
// Prepare data for spreadsheet
var sheet = getOrCreateSheet(SHEET_NAME);
var values = users.map(function(user) {
return [
user.primaryEmail,
user.name.fullName,
new Date(user.lastLoginTime),
user.orgUnitPath,
user.suspended ? 'Suspended' : 'Active'
];
});
// Write to sheet
sheet.getRange(2, 1, values.length, values[0].length).setValues(values);
}
function getThresholdDate(days) {
var date = new Date();
date.setDate(date.getDate() - days);
return date.toISOString();
}
Don't run this manually! Use this snippet to make it run automatically every month.
function createMonthlyTrigger() {
// Check if trigger already exists to avoid duplicates
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() === 'auditInactiveUsers365') {
Logger.log('Trigger already exists.');
return;
}
}
// Create a monthly trigger (runs on the 1st of every month)
ScriptApp.newTrigger('auditInactiveUsers365')
.timeBased()
.onMonthDay(1)
.atHour(9) // Run at 9 AM
.create();
Logger.log('Monthly trigger created successfully.');
}
Governance and membership tools for Google Groups.
For Large Orgs (5000+ Groups). A smart script that processes groups in batches of 500 to avoid the 6-minute execution limit. It automatically triggers itself to run again until all groups are scanned for missing owners.
// Uses PropertiesService to store state between executions
// Full script available via download button
function createAutoBatchTrigger() {
// Creates a trigger to run the audit every 10 minutes
ScriptApp.newTrigger('auditGroupsWithoutOwners')
.timeBased()
.everyMinutes(10)
.create();
}
Flattens group membership into a sheet. Row format: [Group Name, Group Email, Member Email, Role]
function exportGroupMembers() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
sheet.appendRow(['Group Name', 'Group Email', 'Member Email', 'Member Role']);
// See app-scripts.html for pagination implementation
// ...
Logger.log("Export complete");
}
Security audits and file management.
Scans a folder and reports files shared with users outside your domain.
function auditExternalSharing() {
const FOLDER_ID = 'YOUR_FOLDER_ID';
const YOUR_DOMAIN = 'yourdomain.com';
const folder = DriveApp.getFolderById(FOLDER_ID);
const files = folder.getFiles();
while (files.hasNext()) {
const file = files.next();
const editors = file.getEditors();
editors.forEach(editor => {
if (!editor.getEmail().endsWith(YOUR_DOMAIN)) {
Logger.log(`External Editor: ${editor.getEmail()} on file: ${file.getName()}`);
}
});
}
}
Mailbox settings and delegations.
Remotely set an out-of-office reply for a user.
function setVacationResponder() {
const userEmail = 'user@domain.com';
const vacationSettings = {
enableAutoReply: true,
responseSubject: 'Out of Office',
responseBodyHtml: 'I am currently out of the office.',
startTime: new Date().getTime(),
endTime: new Date('2025-12-31').getTime()
};
Gmail.Users.Settings.updateVacation(vacationSettings, userEmail);
}