Skip to content

Instantly share code, notes, and snippets.

@NoSubstitute
Forked from zk-1/gam-archive.sh
Last active July 21, 2022 21:25
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NoSubstitute/b567a544bad6064bb3c8e4fb8b4ca299 to your computer and use it in GitHub Desktop.
Save NoSubstitute/b567a544bad6064bb3c8e4fb8b4ca299 to your computer and use it in GitHub Desktop.
This script will archive a Google Workspace account's email (as .mbox) and/or Google Drive files to a specified Google Drive folder.
#!/usr/bin/env bash
# Name: gam-archive.sh
# Usage: gam-archive.sh email_prefix [mail|drive|both]
# Example: gam-archive.sh jsmith mail
# Description: This script will archive a Google Workspace account's email (as .mbox) and/or Google Drive files to a specified Google Drive folder.
# Author: Zoë Kelly (zoe@starshade.ca), Kim Nilsson (github@no-substitute.com)
# License: MIT
# Created: 2020
# Updated: 2022-07-19
## Note: Depending on the export size and your upload speed, it could take 10 minutes or longer for each archival.
## Note: This script requires GAM, https://github.com/GAM-team/GAM
## Note: This script can't be used with GAMADV-XTD3, https://github.com/taers232c/GAMADV-XTD3/wiki/Vault with its current syntax, even though it also supports Vault.
# Configuration:
# Your Google Workspace admin username (email prefix)
gam_admin='admin'
# Your Google Workspace domain
gam_domain='example.com'
# A Vault matter ID. You can create a matter using: gam create vaultmatter "Offboarding - Archives"
matter_id='000000-0000-0000-0000-000000000000'
# The ID of the Google Drive folder or shared drive where you want to store the archives (extract from URL)
drive_archive_folder_id='0000000000000000000000000000000'
# How many seconds between export readiness checks
export_wait_interval='31'
# Delete Google Workspace account after archiving? Change to yes to enable deletion of user after archiving.
delete_user='no'
# Delete Vault export after archiving? Change to yes to enable deletion of export after archiving.
delete_export='no'
# Where to put error logs, if there are any.
# You should definitely use a better path for this, and check it if script isn't successful.
log_path="$HOME/Desktop"
# --- --- --- --- --- --- --- --- --- ---
the_user=$1
today_stamp=$(date "+%d-%m-%Y")
time_stamp=$(date "+%d-%m-%Y %H:%M")
## Specify your GAM binary location here if different from default
gam() {
"$HOME/bin/gam/gam" "$@" ;
}
# Returns 0 if number is between two specified numbers
# Usage: length_between 55 50 60
length_between() {
if [[ ${#1} -ge $2 ]] && [[ ${#1} -le $3 ]]; then return 0; else return 1; fi
}
# Usage info
usage="`printf 'Usage: ' && basename $0 | tr -d '\n' && printf ' email_prefix [mail|drive|both]'`"
# If no paramater given, print usage and exit
if [ $# -lt 1 ]; then
echo "$usage"
exit
fi
# --- --- --- --- --- --- --- --- --- ---
# Determine export type from parameter if given,
# otherwise ask for type
if [[ $# == 2 ]]; then
if [[ $2 == 'mail' ]] || [[ $2 == 'drive' ]] || [[ $2 == 'both' ]]; then
to_archive=$2
else
echo "Invalid choice"
return
fi
else
PS3='Choose archive options: '
options3=("Email" "Google Drive" "Both")
select opt3 in "${options3[@]}"
do
case $opt3 in
"Email")
to_archive='mail'
break
;;
"Google Drive")
to_archive='drive'
break
;;
"Both")
to_archive='both'
break
;;
esac
done
fi
# Main export function
# Takes export type as single parameter
do_export () {
export_type="$1"
# Start the export
if [[ $export_type == "mail" ]]; then
export_id=$(gam create export matter uid:$matter_id name "GAM - Offboarding Email export for $the_user" corpus mail accounts $the_user@$gam_domain | grep "id: " | cut -d " " -f3)
elif [[ $export_type == "drive" ]]; then
# Drive export also requires owner terms be specified, otherwise it will include every document the user has access to!
export_id=$(gam create export matter uid:$matter_id name "GAM - Offboarding Google Drive export for $the_user" corpus drive accounts $the_user@$gam_domain terms owner:$the_user@$gam_domain | grep "id: " | cut -d " " -f3)
fi
# Ensure the returned UID is valid
if $(length_between $export_id 40 50); then
printf '%s' "-- Server-side $export_type export for $the_user in progress.."
else
echo "-- Invalid export_id, logging error to $log_path/gam-archive-error.log"
echo "$time_stamp - Abort - Invalid export_id for $the_user" >> $log_path/gam-archive-error.log
exit 1
fi
# Check repeatedly until the export is ready
export_ready="0"
while [[ $export_ready != "COMPLETED" ]]; do
printf '%s' ".."
sleep $export_wait_interval
export_ready=$(gam info export uid:$matter_id uid:$export_id | grep "status: " | cut -d " " -f3)
done
echo
echo "-- Export finished, downloading files.."
# Set up the temp folder
archive_name="$the_user-$export_type-archive-$today_stamp"
mkdir /tmp/$archive_name
# Download the export and compress it
gam download export uid:$matter_id uid:$export_id targetfolder /tmp/$archive_name &>/dev/null
echo "-- Download complete, compressing.."
tar -cz -f /tmp/$archive_name.tar.gz -C /tmp/ ./$archive_name
rm -r /tmp/$archive_name
file_size=$(du -m /tmp/$archive_name.tar.gz | cut -f1)
echo "-- Archive is $file_size MB in size"
# Uploading to Google Drive
echo "-- Uploading the archive to the Google Drive location specified.."
echo " (this could take a while)"
upload_result=$(gam user $gam_admin add drivefile localfile /tmp/$archive_name.tar.gz parentid $drive_archive_folder_id | cut -d " " -f1)
if [[ $upload_result == "Successfully" ]]; then
echo "-- File uploaded to Google Drive, deleting temporary file"
rm -f /tmp/$archive_name.tar.gz
else
echo "-- Upload failed, leaving archive in /tmp/, logging error to $log_path/gam-archive-error.log"
echo "$time_stamp - Abort - Google Drive upload failed for $the_user" >> $log_path/gam-archive-error.log
exit 1
fi
}
# Proceed with chosen options
if [[ $to_archive == 'mail' ]]; then
echo "-- Now archiving Email for $the_user"
do_export mail
elif [[ $to_archive == 'drive' ]]; then
echo "-- Now archiving Google Drive files for $the_user"
do_export drive
elif [[ $to_archive == 'both' ]]; then
echo "-- Now archiving Email and Google Drive files for $the_user"
do_export mail
do_export drive
fi
# Delete user in G Suite if specified above
if [[ $delete_user == "yes" ]]; then
echo "-- Deleting Google Workspace account $the_user ..."
gam delete user "$the_user" &>/dev/null
fi
# Delete Vault export if specified above
if [[ $delete_export == "yes" ]]; then
echo "-- Deleting Vault export $export_id ..."
gam delete export uid:$matter_id uid:$export_id &>/dev/null
fi
echo "-- Archive process complete for $the_user"
exit 0
@NoSubstitute
Copy link
Author

Adjusted "G Suite" to "Google Workspace" all over, and added a setting and process to automatically delete the Vault export after successfully archiving it.

@pro4tlzz
Copy link

Nice!

@NoSubstitute
Copy link
Author

Zoë Kelly obviously did all the magic, I just adjusted the language, and added the delete export process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment