This directory contains example configuration files and usage scenarios for the Google Admin Client (gac).
File: basic-config.yaml
Minimal configuration for getting started:
# Google Workspace domain
domain: example.com
# OAuth2 credentials (optional - defaults to ~/.credentials/)
client-secret: ~/.credentials/client_secret.json
cache-file: ~/.credentials/gac.jsonUsage:
cp examples/basic-config.yaml ~/.google-admin.yaml
# Edit with your domain
gac user listFile: production-config.yaml
Configuration for production use with custom paths:
# Production Google Workspace domain
domain: company.com
# OAuth2 credentials in custom locations
client-secret: /etc/gac/client_secret.json
cache-file: /var/lib/gac/token.json
# Additional security: restrict to specific pathsUsage:
# Use with --config flag
gac --config /etc/gac/production-config.yaml user listFile: development-config.yaml
Configuration for development/testing:
# Development domain
domain: dev.example.com
# Development credentials
client-secret: ~/.credentials/dev_client_secret.json
cache-file: ~/.credentials/dev_token.jsonUsage:
# Keep separate configs for dev and prod
export GAC_CONFIG=~/.google-admin-dev.yaml
gac user listFile: onboarding-example.sh
Complete script for onboarding a new employee:
#!/bin/bash
# Onboard a new employee with all necessary setup
EMAIL="$1"
FIRST_NAME="$2"
LAST_NAME="$3"
DEPARTMENT="$4"
TITLE="$5"
MANAGER="$6"
PERSONAL_EMAIL="$7"
# Create user
echo "Creating user: $EMAIL"
gac user create \
-f "$FIRST_NAME" \
-l "$LAST_NAME" \
-e "$PERSONAL_EMAIL" \
-g all-staff \
"$EMAIL"
# Update user profile
echo "Updating user profile..."
gac user update \
--dept "$DEPARTMENT" \
--title "$TITLE" \
--manager "$MANAGER" \
--type staff \
--id "$(uuidgen)" \
"$EMAIL"
# Add to department group
DEPT_GROUP=$(echo "$DEPARTMENT" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
echo "Adding to department group: $DEPT_GROUP"
gac user update -g "$DEPT_GROUP" "$EMAIL"
echo "Onboarding complete for $EMAIL"Usage:
./examples/onboarding-example.sh \
jdoe@example.com \
"John" \
"Doe" \
"Engineering" \
"Software Engineer" \
"manager@example.com" \
"john.doe@personal.com"File: bulk-export.sh
Export all users to CSV for backup or analysis:
#!/bin/bash
# Export all users to CSV with timestamp
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
OUTPUT_FILE="users_export_${TIMESTAMP}.csv"
echo "Exporting all users to $OUTPUT_FILE..."
gac user list --csv --full > "$OUTPUT_FILE"
echo "Export complete: $OUTPUT_FILE"
echo "Total users: $(tail -n +2 "$OUTPUT_FILE" | wc -l)"Usage:
./examples/bulk-export.shFile: offboarding-example.sh
Script for offboarding an employee:
#!/bin/bash
# Offboard an employee: transfer data and disable account
SOURCE_EMAIL="$1"
DESTINATION_EMAIL="$2"
if [ -z "$SOURCE_EMAIL" ] || [ -z "$DESTINATION_EMAIL" ]; then
echo "Usage: $0 <source-email> <destination-email>"
exit 1
fi
# Transfer documents and resources
echo "Transferring data from $SOURCE_EMAIL to $DESTINATION_EMAIL..."
gac transfer --from "$SOURCE_EMAIL" --to "$DESTINATION_EMAIL"
# Wait for transfer to complete
echo "Waiting for transfer to complete (check Google Admin console for status)"
read -p "Press enter when transfer is complete..."
# Disable the user account
echo "Disabling user account: $SOURCE_EMAIL"
gac user update --remove "$SOURCE_EMAIL"
# Clear PII
echo "Clearing personal information..."
gac user update --clear-pii "$SOURCE_EMAIL"
echo "Offboarding complete for $SOURCE_EMAIL"Usage:
./examples/offboarding-example.sh olduser@example.com newowner@example.comFile: group-audit.sh
Audit groups for inactive members:
#!/bin/bash
# Find groups containing former employees
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
OUTPUT_FILE="group_audit_${TIMESTAMP}.txt"
echo "Auditing groups for inactive members..."
echo "Group Audit Report - $TIMESTAMP" > "$OUTPUT_FILE"
echo "======================================" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
gac group list --contains-former-employees >> "$OUTPUT_FILE"
echo "Audit complete: $OUTPUT_FILE"
cat "$OUTPUT_FILE"Usage:
./examples/group-audit.shFile: create-recurring-meeting.sh
Create recurring team meetings:
#!/bin/bash
# Create a recurring team meeting
CALENDAR_EMAIL="$1"
MEETING_TITLE="$2"
START_DATE="$3" # Format: 2025-10-15T09:00:00-04:00
END_DATE="$4" # Format: 2025-10-15T10:00:00-04:00
FREQUENCY="${5:-weekly}" # daily, weekly, or monthly
COUNT="${6:-52}" # Number of occurrences
if [ -z "$CALENDAR_EMAIL" ] || [ -z "$MEETING_TITLE" ] || [ -z "$START_DATE" ] || [ -z "$END_DATE" ]; then
echo "Usage: $0 <calendar-email> <meeting-title> <start-date> <end-date> [frequency] [count]"
echo "Example: $0 team@example.com 'Team Standup' '2025-10-15T09:00:00-04:00' '2025-10-15T09:30:00-04:00' daily 90"
exit 1
fi
echo "Creating recurring meeting: $MEETING_TITLE"
gac calendar create "$CALENDAR_EMAIL" \
-s "$MEETING_TITLE" \
-b "$START_DATE" \
-e "$END_DATE" \
-f "$FREQUENCY" \
-c "$COUNT" \
-l "Virtual - Zoom"
echo "Meeting created successfully"Usage:
./examples/create-recurring-meeting.sh \
team@example.com \
"Daily Standup" \
"2025-10-15T09:00:00-04:00" \
"2025-10-15T09:15:00-04:00" \
daily \
90File: batch-update-users.sh
Update multiple users from a CSV file:
#!/bin/bash
# Batch update users from CSV
# CSV format: email,department,title,manager
INPUT_FILE="${1:-users-to-update.csv}"
if [ ! -f "$INPUT_FILE" ]; then
echo "Error: File not found: $INPUT_FILE"
echo "Usage: $0 [csv-file]"
exit 1
fi
echo "Updating users from: $INPUT_FILE"
echo ""
# Skip header line and process each user
tail -n +2 "$INPUT_FILE" | while IFS=, read -r EMAIL DEPT TITLE MANAGER; do
echo "Updating: $EMAIL"
echo " Department: $DEPT"
echo " Title: $TITLE"
echo " Manager: $MANAGER"
gac user update \
--dept "$DEPT" \
--title "$TITLE" \
--manager "$MANAGER" \
"$EMAIL"
if [ $? -eq 0 ]; then
echo " ✓ Updated successfully"
else
echo " ✗ Update failed"
fi
echo ""
done
echo "Batch update complete"Sample CSV (users-to-update.csv):
email,department,title,manager
jdoe@example.com,Engineering,Senior Engineer,manager@example.com
jsmith@example.com,Sales,Account Executive,sales-mgr@example.comUsage:
./examples/batch-update-users.sh users-to-update.csvFile: ou-restructure.sh
Demonstrate OU management - creating structure, updating, and reorganizing:
#!/bin/bash
# Organizational Unit Restructure Example
set -euo pipefail
echo "Creating organizational structure..."
# Create top-level OUs
gac ou create /Engineering --description "Engineering department"
gac ou create /Sales --description "Sales department"
gac ou create /Operations --description "Operations department"
# Create Engineering sub-OUs
gac ou create /Engineering/Backend --description "Backend engineering team"
gac ou create /Engineering/Frontend --description "Frontend engineering team"
gac ou create /Engineering/DevOps --description "DevOps and infrastructure team"
# Create Sales sub-OUs
gac ou create /Sales/Enterprise --description "Enterprise sales team"
gac ou create /Sales/SMB --description "Small and medium business sales"
echo "✓ Organizational structure created"
# List the structure
gac ou list
# Update an OU
gac ou update /Engineering --description "Engineering department - All technical teams"
# Move an OU to a different parent
gac ou update /Engineering/DevOps --parent /Operations --name "DevOps"
echo "✓ OU reorganization complete"Usage:
./examples/ou-restructure.shCleanup:
# Delete sub-OUs first (must be empty of users)
gac ou delete /Engineering/Backend
gac ou delete /Engineering/Frontend
gac ou delete /Sales/Enterprise
gac ou delete /Sales/SMB
gac ou delete /Operations/DevOps
# Then delete top-level OUs
gac ou delete /Engineering
gac ou delete /Sales
gac ou delete /OperationsFile: alias-management.sh
Demonstrate user alias management - adding, listing, and removing email aliases:
#!/bin/bash
# User Alias Management Example
set -euo pipefail
# Configuration
USER_EMAIL="user@example.com"
ALIAS1="support@example.com"
ALIAS2="help@example.com"
ALIAS3="info@example.com"
echo "Managing aliases for user..."
# List current aliases
gac alias list "$USER_EMAIL"
# Add aliases
echo "Adding aliases..."
gac alias add "$USER_EMAIL" "$ALIAS1"
gac alias add "$USER_EMAIL" "$ALIAS2"
gac alias add "$USER_EMAIL" "$ALIAS3"
# List aliases after adding
gac alias list "$USER_EMAIL"
# Remove an alias
echo "Removing alias..."
gac alias remove "$USER_EMAIL" "$ALIAS2" --force
# List final aliases
gac alias list "$USER_EMAIL"
echo "✓ Alias management complete"Usage:
# Set your user and alias emails
export USER_EMAIL=user@example.com
export ALIAS1=support@example.com
export ALIAS2=help@example.com
export ALIAS3=info@example.com
./examples/alias-management.shCleanup:
# Remove all demo aliases
gac alias remove user@example.com support@example.com --force
gac alias remove user@example.com info@example.com --forceCommon Use Cases:
- Department addresses (support@, sales@, info@)
- Role-based addresses (admin@, webmaster@)
- Alternative name formats (first.last@, firstlast@)
- Legacy addresses when renaming users
File: user-suspension.sh
Demonstrate user account suspension and unsuspension for various scenarios:
#!/bin/bash
# User Account Suspension Example
set -euo pipefail
# Configuration
USER_EMAIL="user@example.com"
SUSPENSION_REASON="Demo suspension for testing"
echo "Suspending user account..."
# Check current status
gac user list "$USER_EMAIL"
# Suspend the user
gac user suspend "$USER_EMAIL" --reason "$SUSPENSION_REASON" --force
# Verify suspension
gac user list "$USER_EMAIL"
# Unsuspend the user
gac user unsuspend "$USER_EMAIL" --force
echo "✓ Suspension demo complete"Usage:
# Set your user email
export USER_EMAIL=user@example.com
export SUSPENSION_REASON="Extended leave"
./examples/user-suspension.shCommon Workflows:
-
Employee Departure:
# Suspend account immediately gac user suspend departing@example.com --reason "Employee departure" # Transfer data ownership (see offboarding example) # Delete account after retention period
-
Security Incident:
# Immediate suspension gac user suspend compromised@example.com --reason "Security incident" --force # Investigate and resolve # Unsuspend after resolution gac user unsuspend compromised@example.com --force
-
Extended Leave:
# Suspend during leave period gac user suspend onleave@example.com --reason "Extended leave - 3 months" # Unsuspend on return gac user unsuspend onleave@example.com
Key Points:
- Suspended users cannot sign in or access any Google Workspace services
- Emails to suspended accounts will bounce
- All data is preserved during suspension
- Unsuspending immediately restores full access
- Always document suspension reasons for audit purposes
Best Practices:
- Provide clear suspension reasons
- Document suspensions in ticketing system
- Review suspended accounts monthly
- Have clear unsuspension approval process
- Communicate with affected users when appropriate
Manage calendar resources like conference rooms, equipment, and other bookable items.
File: cal-resource-management.sh
What it demonstrates:
- Creating conference room resources with capacity and features
- Creating equipment resources
- Listing and filtering resources by type
- Updating resource properties
- Deleting resources
Key commands:
# Create a conference room
gac cal-resource create conf-room-a \
--name "Conference Room A" \
--type room \
--capacity 12 \
--building-id main-bldg \
--floor "3rd Floor"
# Create equipment
gac cal-resource create projector-1 \
--name "HD Projector" \
--type equipment \
--category "AV Equipment"
# List all resources
gac cal-resource list
# List only rooms
gac cal-resource list --type room
# Update capacity
gac cal-resource update conf-room-a --capacity 15
# Delete resource
gac cal-resource delete old-projector --forceUsage:
# Optionally set building ID
export BUILDING_ID=main-bldg
./examples/cal-resource-management.shCommon Resource Types:
-
Conference Rooms:
gac cal-resource create exec-boardroom \ --name "Executive Boardroom" \ --type room \ --capacity 20 \ --building-id headquarters \ --floor "10th Floor"
-
Equipment:
gac cal-resource create laptop-loaner-5 \ --name "Loaner Laptop #5" \ --type equipment \ --category "Computers" \ --description "MacBook Pro for temporary employee use"
-
Other Resources:
gac cal-resource create parking-spot-a1 \ --name "Parking Spot A1" \ --type other \ --category "Parking" \ --description "Reserved parking near main entrance"
Key Points:
- Each resource gets a unique email address for calendar booking
- Resources can be organized by building, floor, and section
- Capacity prevents overbooking of rooms
- Resource types: room, equipment, or other
- Features are displayed when listing but must be managed separately through the Google Admin Console
Best Practices:
- Use consistent naming conventions (e.g.,
bldg-floor-room-number) - Set accurate capacity to prevent overbooking
- Organize resources hierarchically with buildings and floors
- Include user-friendly descriptions
- Use meaningful categories for equipment (e.g., "AV Equipment", "Computers")
- Regularly audit and remove unused resources
- Document resource policies (e.g., booking limits, approval requirements)
Manage Google Workspace group settings including access control, posting permissions, moderation, and email preferences.
File: group-settings-management.sh
What it demonstrates:
- Viewing group settings in table and JSON formats
- Configuring access control (who can join/view)
- Setting posting permissions
- Enabling message moderation
- Adding custom email footers
- Managing reply-to and archive settings
Key commands:
# View group settings
gac group-settings list team@example.com
# View settings as JSON
gac group-settings list team@example.com --format json
# Allow anyone in domain to join
gac group-settings update team@example.com \
--who-can-join ALL_IN_DOMAIN_CAN_JOIN
# Configure posting permissions
gac group-settings update engineering@example.com \
--who-can-post-message ALL_MEMBERS_CAN_POST \
--allow-web-posting true
# Enable moderation for announcements
gac group-settings update announcements@example.com \
--message-moderation-level MODERATE_ALL_MESSAGES \
--who-can-moderate-content ALL_MANAGERS_CAN_POST
# Add custom footer
gac group-settings update support@example.com \
--custom-footer-text "For help, contact support@example.com" \
--include-custom-footer true
# Make group read-only archive
gac group-settings update archive@example.com \
--archive-only trueUsage:
# Optionally set group emails
export GROUP_EMAIL=team@example.com
export ANNOUNCEMENTS_GROUP=announcements@example.com
export SUPPORT_GROUP=support@example.com
./examples/group-settings-management.shCommon Configuration Scenarios:
-
Team Collaboration Group:
gac group-settings update team@example.com \ --who-can-join ALL_IN_DOMAIN_CAN_JOIN \ --who-can-post-message ALL_MEMBERS_CAN_POST \ --allow-web-posting true \ --reply-to REPLY_TO_SENDER -
Moderated Announcements:
gac group-settings update announcements@example.com \ --who-can-post-message ALL_MANAGERS_CAN_POST \ --message-moderation-level MODERATE_ALL_MESSAGES \ --who-can-view-group ALL_IN_DOMAIN_CAN_VIEW \ --allow-external-members false -
External Partner Group:
gac group-settings update partners@example.com \ --allow-external-members true \ --who-can-join INVITED_CAN_JOIN \ --who-can-post-message ALL_MEMBERS_CAN_POST \ --message-moderation-level MODERATE_NON_MEMBERS -
Read-Only Archive:
gac group-settings update archive-2024@example.com \ --archive-only true \ --who-can-view-group ALL_IN_DOMAIN_CAN_VIEW \ --who-can-post-message NONE_CAN_POST
Available Settings:
- Access Control:
who-can-join,who-can-view-group,who-can-view-membership,allow-external-members - Posting:
who-can-post-message,allow-web-posting,message-moderation-level,spam-moderation-level - Email:
reply-to,custom-reply-to,custom-footer-text,include-custom-footer,include-in-global-address-list - Archive:
archive-only,show-in-group-directory - Members:
who-can-leave-group,who-can-add,who-can-invite,who-can-approve-members,members-can-post-as-the-group - Moderation:
who-can-contact-owner,who-can-moderate-members,who-can-moderate-content,who-can-ban-users
Key Points:
- Only update settings you want to change; others remain unchanged
- Settings use specific values (e.g.,
ALL_IN_DOMAIN_CAN_JOIN,ALL_MEMBERS_CAN_POST) - Custom footers can include up to 1,000 characters
- Archive-only groups reject new messages
- Moderation levels:
MODERATE_ALL_MESSAGES,MODERATE_NON_MEMBERS,MODERATE_NEW_MEMBERS,MODERATE_NONE
Best Practices:
- Document group purposes and settings in group descriptions
- Use moderation for announcement-only groups
- Restrict external members for sensitive groups
- Add custom footers for support/compliance information
- Set appropriate join permissions based on group sensitivity
- Use
archive-onlyfor historical groups instead of deleting - Test settings with a pilot group before applying to all groups
- Review group settings regularly for security compliance
- Use reply-to settings to control conversation flow
- Enable spam moderation for public-facing groups
-
Protect credentials:
chmod 600 ~/.credentials/*.json chmod 700 ~/.credentials
-
Use environment-specific configs:
- Keep separate credentials for dev, staging, and production
- Never commit credentials to version control
- Use
.gitignoreto exclude credential files
-
Rotate credentials regularly:
- Create new OAuth2 clients periodically
- Revoke old tokens in Google Cloud Console
-
Use configuration files for persistent settings:
# ~/.google-admin.yaml domain: example.com
-
Use environment variables for CI/CD:
export GAC_DOMAIN=example.com export GAC_CLIENT_SECRET=/path/to/credentials.json
-
Use command-line flags for one-off overrides:
gac --domain dev.example.com user list
-
Check exit codes:
if gac user create newuser@example.com; then echo "Success" else echo "Failed" exit 1 fi
-
Add error handling:
set -euo pipefail # Exit on error, undefined vars, pipe failures
-
Log operations:
gac user create newuser@example.com 2>&1 | tee -a operations.log
-
Use dry-run when available (future feature):
gac user update --dry-run --dept Engineering user@example.com
-
Batch operations when possible to reduce API calls
-
Add delays between bulk operations to avoid rate limits:
for user in $(cat users.txt); do gac user update --dept Engineering "$user" sleep 1 # Delay between requests done
-
Monitor API quotas in Google Cloud Console
-
Test on non-production domains first
-
Validate inputs before bulk operations:
# Validate email format if [[ ! "$EMAIL" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then echo "Invalid email: $EMAIL" exit 1 fi
-
Keep backups before destructive operations:
gac user list --csv --full > backup_$(date +%Y%m%d).csv
- Main README - Full documentation
- CREDENTIALS.md - OAuth2 setup guide
- CONTRIBUTING.md - Development guidelines
- ARCHITECTURE.md - Technical details
Have a useful script or configuration? We welcome contributions!
- Add your example to this directory
- Update this README with documentation
- Submit a pull request
See CONTRIBUTING.md for guidelines.