Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
5b23efd83f Bump cryptography in the pip group across 1 directory
Bumps the pip group with 1 update in the / directory: [cryptography](https://github.com/pyca/cryptography).


Updates `cryptography` from 46.0.3 to 46.0.5
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/46.0.3...46.0.5)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-version: 46.0.5
  dependency-type: direct:production
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-11 02:54:50 +00:00
65 changed files with 1489 additions and 3561 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,14 @@
name: Check for Google Root CA Updates name: Check for Google Root CA Updates
on: on:
push:
paths-ignore:
- 'wiki/**'
pull_request:
paths-ignore:
- 'wiki/**'
schedule: schedule:
- cron: '23 23 * * *' - cron: '23 23 * * *'
workflow_dispatch:
defaults: defaults:
run: run:
@@ -12,9 +17,9 @@ defaults:
jobs: jobs:
check-certs: check-certs:
runs-on: ubuntu-slim runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
with: with:
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token
fetch-depth: 0 # otherwise, you will failed to push refs to dest repo fetch-depth: 0 # otherwise, you will failed to push refs to dest repo
@@ -25,51 +30,9 @@ jobs:
echo "Current hash is: ${CURRENT_HASH}" echo "Current hash is: ${CURRENT_HASH}"
echo "CURRENT_HASH=${CURRENT_HASH}" >> $GITHUB_ENV echo "CURRENT_HASH=${CURRENT_HASH}" >> $GITHUB_ENV
- name: Generate GAM-specific bundle with LE + Google roots - name: Get latest cacerts.pem file from Google
run: | run: |
OUTPUT_FILE="cacerts.pem" curl -o ./cacerts.pem -vvvv https://pki.goog/roots.pem
> "$OUTPUT_FILE"
process_cert() {
local url="$1"
local op_ca="$2"
local label="$3"
local tmp_cert=$(mktemp)
curl "$url" > "$tmp_cert"
local issuer=$(openssl x509 -noout -issuer -in "$tmp_cert" | sed -e 's/^issuer= *//')
local subject=$(openssl x509 -noout -subject -in "$tmp_cert" | sed -e 's/^subject= *//')
local serial_hex=$(openssl x509 -noout -serial -in "$tmp_cert" | sed -e 's/^serial=//')
local serial_dec=$(python3 -c "print(int('$serial_hex', 16))")
local md5=$(openssl x509 -noout -fingerprint -md5 -in "$tmp_cert" | sed -e 's/.*=//' | tr '[:upper:]' '[:lower:]')
local sha1=$(openssl x509 -noout -fingerprint -sha1 -in "$tmp_cert" | sed -e 's/.*=//' | tr '[:upper:]' '[:lower:]')
local sha256=$(openssl x509 -noout -fingerprint -sha256 -in "$tmp_cert" | sed -e 's/.*=//' | tr '[:upper:]' '[:lower:]')
echo "# Operating CA: $op_ca" >> "$OUTPUT_FILE"
echo "# Issuer: $issuer" >> "$OUTPUT_FILE"
echo "# Subject: $subject" >> "$OUTPUT_FILE"
echo "# Label: \"$label\"" >> "$OUTPUT_FILE"
echo "# Serial: $serial_dec" >> "$OUTPUT_FILE"
echo "# MD5 Fingerprint: $md5" >> "$OUTPUT_FILE"
echo "# SHA1 Fingerprint: $sha1" >> "$OUTPUT_FILE"
echo "# SHA256 Fingerprint: $sha256" >> "$OUTPUT_FILE"
cat "$tmp_cert" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
rm "$tmp_cert"
}
echo "#" >> "$OUTPUT_FILE"
echo "# This is a custom certificate authority bundle for GAM" >> "$OUTPUT_FILE"
echo "# It's composed of Let's Encrypt Root CAs and Google's" >> "$OUTPUT_FILE"
echo "# certificate bundle. This should be the minimal list of" >> "$OUTPUT_FILE"
echo "# CAs required to talk to Google and Github." >> "$OUTPUT_FILE"
echo"" >> "$OUTPUT_FILE"
echo "Processing Let's Encrypt ISRG Root X1..."
process_cert "https://letsencrypt.org/certs/isrgrootx1.pem" "Let's Encrypt" "ISRG Root X1"
echo "Processing Let's Encrypt ISRG Root X2..."
process_cert "https://letsencrypt.org/certs/isrg-root-x2.pem" "Let's Encrypt" "ISRG Root X2"
echo "Appending Google's roots.pem..."
curl -s https://pki.goog/roots.pem >> "$OUTPUT_FILE"
echo "Done! The new bundle has been saved to $OUTPUT_FILE."
- name: Compare hashes - name: Compare hashes
run: | run: |
@@ -88,6 +51,6 @@ jobs:
git diff --quiet && git diff --staged --quiet || git commit -am '[ci skip] Updated cacerts.pem' git diff --quiet && git diff --staged --quiet || git commit -am '[ci skip] Updated cacerts.pem'
- name: Push changes - name: Push changes
uses: ad-m/github-push-action@77c5b412c50b723d2a4fbc6d71fb5723bcd439aa uses: ad-m/github-push-action@master
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -11,8 +11,8 @@ authors = [
#significant compile dependencies. #significant compile dependencies.
dependencies = [ dependencies = [
"arrow>=1.3.0", "arrow>=1.3.0",
"chardet==5.2.0", "chardet>=5.2.0",
"cryptography>=46.0.5", "cryptography==46.0.5",
"distro; sys_platform=='linux'", "distro; sys_platform=='linux'",
"filelock>=3.18.0", "filelock>=3.18.0",
"google-api-python-client>=2.167.0", "google-api-python-client>=2.167.0",
@@ -31,11 +31,11 @@ requires-python = ">=3.10"
classifiers = [ classifiers = [
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Operating System :: OS Independent", "Operating System :: OS Independent",
] ]
license = {text = "Apache License (2.0)"} license = {text = "Apache License (2.0)"}

View File

@@ -260,7 +260,6 @@ If an item contains spaces, it should be surrounded by ".
4tb | drive4tb | googledrivestorage4tb | Google-Drive-storage-4TB | 4tb | drive4tb | googledrivestorage4tb | Google-Drive-storage-4TB |
8tb | drive8tb | googledrivestorage8tb | Google-Drive-storage-8TB | 8tb | drive8tb | googledrivestorage8tb | Google-Drive-storage-8TB |
16tb | drive16tb | googledrivestorage16tb | Google-Drive-storage-16TB | 16tb | drive16tb | googledrivestorage16tb | Google-Drive-storage-16TB |
aiexpandedaccess | 1010470009 | AI Expanded Access |
aimeetingsandmessaging | 1010470007 | AI Meetings and Messaging | aimeetingsandmessaging | 1010470007 | AI Meetings and Messaging |
aisecurity | 1010470006 | AI Security | aisecurity | 1010470006 | AI Security |
appsheetcore | 1010380001 | AppSheet Core | appsheetcore | 1010380001 | AppSheet Core |
@@ -279,7 +278,7 @@ If an item contains spaces, it should be surrounded by ".
gaiproedu | geminiedu | 1010470004 | Google AI Pro for Education | gaiproedu | geminiedu | 1010470004 | Google AI Pro for Education |
geminibiz | 1010470003 | Gemini Business | geminibiz | 1010470003 | Gemini Business |
geminiedupremium| 1010470005 | Gemini Education Premium | geminiedupremium| 1010470005 | Gemini Education Premium |
geminient| duetai | 1010470001 | Gemini Enterprise - Legacy | geminient| duetai | 1010470001 | Gemini Enterprise |
geminiultra | 1010470008 | Google AI Ultra for Business | geminiultra | 1010470008 | Google AI Ultra for Business |
gsuitebasic | gafb | gafw | basic | Google-Apps-For-Business | gsuitebasic | gafb | gafw | basic | Google-Apps-For-Business |
gsuitebusiness | gau | gsb | unlimited | Google-Apps-Unlimited | gsuitebusiness | gau | gsb | unlimited | Google-Apps-Unlimited |
@@ -1430,8 +1429,6 @@ gam print addresses [todrive <ToDriveAttribute>*]
# Authorization # Authorization
gam info gcporgid
gam create gcpfolder <String> gam create gcpfolder <String>
gam create gcpfolder [admin <EmailAddress>] folder <String> gam create gcpfolder [admin <EmailAddress>] folder <String>
@@ -2993,8 +2990,6 @@ gam [<UserTypeEntity>] show classificationlabelpermissions <ClassificationLabelN
(combiningfunction <CAACombiningFunction>) | (combiningfunction <CAACombiningFunction>) |
(condition <CAAConditionAttribute>+ endcondition) (condition <CAAConditionAttribute>+ endcondition)
gam info gcporgid
gam create caalevel <String> [description <String>] (basic <CAABasicAttribute>+)|(custom <QueryCEL>)|<JSONData> gam create caalevel <String> [description <String>] (basic <CAABasicAttribute>+)|(custom <QueryCEL>)|<JSONData>
gam update caalevel <CAALevelName> [description <String>] (basic <CAABasicAttribute>+)|(custom <QueryCEL>)|<JSONData> gam update caalevel <CAALevelName> [description <String>] (basic <CAABasicAttribute>+)|(custom <QueryCEL>)|<JSONData>
gam delete caalevel <CAALevelName> gam delete caalevel <CAALevelName>
@@ -3514,6 +3509,13 @@ gam print guardian|guardians [todrive <ToDriveAttribute>*] [accepted|invitations
[showstudentemails] [showstudentemails]
[formatjson [quotechar <Character>]] [formatjson [quotechar <Character>]]
# Business Profile Accounts
gam show businessprofileaccounts
[type locationgroup|organization|personal|usergroup]
gam print businessprofileaccounts [todrive <ToDriveAttribute>*]
[type locationgroup|organization|personal|usergroup]
# Classroom User Profiles # Classroom User Profiles
gam <UserTypeEntity> print classroomprofile [todrive <ToDriveAttribute>*] gam <UserTypeEntity> print classroomprofile [todrive <ToDriveAttribute>*]
@@ -3542,10 +3544,6 @@ gam info customer [formatjson]
gam info instance [formatjson] gam info instance [formatjson]
gam info customerid
gam info gcporgid
# Data Transfers # Data Transfers
gam print|show transferapps gam print|show transferapps
@@ -3884,7 +3882,6 @@ gam create|add group <EmailAddress>
[copyfrom <GroupItem>] <GroupAttribute>* [copyfrom <GroupItem>] <GroupAttribute>*
[verifynotinvitable] [verifynotinvitable]
gam update group|groups <GroupEntity> [email <EmailAddress>] gam update group|groups <GroupEntity> [email <EmailAddress>]
[updateprimaryemail <RESearchPattern> <RESubstitution>]
[copyfrom <GroupItem>] <GroupAttribute>* [copyfrom <GroupItem>] <GroupAttribute>*
[security|makesecuritygroup] [security|makesecuritygroup]
[admincreated <Boolean>] [admincreated <Boolean>]
@@ -4112,7 +4109,6 @@ gam create cigroup <EmailAddress>
[security|makesecuritygroup] [locked] [security|makesecuritygroup] [locked]
[dynamic <QueryDynamicGroup>] [dynamic <QueryDynamicGroup>]
gam update cigroup <GroupEntity> [copyfrom <GroupItem>] <GroupAttribute> gam update cigroup <GroupEntity> [copyfrom <GroupItem>] <GroupAttribute>
[updateprimaryemail <RESearchPattern> <RESubstitution>]
[security|makesecuritygroup| [security|makesecuritygroup|
dynamicsecurity|makedynamicsecuritygroup| dynamicsecurity|makedynamicsecuritygroup|
lockedsecurity|makelockedsecuritygroup] lockedsecurity|makelockedsecuritygroup]
@@ -4339,14 +4335,14 @@ gam update deviceuserstate <DeviceUserEntity> [clientid <String>]
# Cloud Identity Policies # Cloud Identity Policies
gam info policies <CIPolicyNameEntity> gam info policies <CIPolicyNameEntity>
[nowarnings] [noappnames] [noidmappimg] [nowarnings] [noappnames]
[formatjson] [formatjson]
gam print policies [todrive <ToDriveAttribute>*] gam print policies [todrive <ToDriveAttribute>*]
[filter <String>] [nowarnings] [noappnames] [noidmappimg] [filter <String>] [nowarnings] [noappnames]
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>] [group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
[formatjson [quotechar <Character>]] [formatjson [quotechar <Character>]]
gam show policies gam show policies
[filter <String>] [nowarnings] [noappnames] [noidmappimg] [filter <String>] [nowarnings] [noappnames]
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>] [group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
[formatjson] [formatjson]
@@ -4572,8 +4568,8 @@ gam check ou|org <OrgUnitItem> [todrive <ToDriveAttribute>*]
usedriverlessconfig| usedriverlessconfig|
<PrinterFieldNameList> ::= "<PrinterFieldName>(,<PrinterFieldName>)*" <PrinterFieldNameList> ::= "<PrinterFieldName>(,<PrinterFieldName>)*"
gam create printer <PrinterAttribute>+ [nodetails|returnidonly] gam create printer <PrinterAttribute>+
gam update printer <PrinterID> <PrinterAttribute>+ [nodetails|returnidonly] gam update printer <PrinterID> <PrinterAttribute>+
gam delete printer gam delete printer
<PrinterIDList>| <PrinterIDList>|
<FileSelector>| <FileSelector>|
@@ -4666,9 +4662,6 @@ gam report <ActivityApplicationName> [todrive <ToDriveAttribute>*]
[event|events <EventNameList>] [ip <String>] [event|events <EventNameList>] [ip <String>]
[gmaileventtypes <NumberRangeList>] [gmaileventtypes <NumberRangeList>]
[groupidfilter <String>] [resourcedetailsfilter <String>] [groupidfilter <String>] [resourcedetailsfilter <String>]
[networkinfofilter <String>] [statusfilter <String>]
[applicationinfofilter <String>] [includesensitivedata]
[notimesort]
[maxactivities <Number>] [maxevents <Number>] [maxresults <Number>] [maxactivities <Number>] [maxevents <Number>] [maxresults <Number>]
[countsonly [bydate|summary] [eventrowfilter]] [countsonly [bydate|summary] [eventrowfilter]]
(addcsvdata <FieldName> <String>)* [shownoactivities] (addcsvdata <FieldName> <String>)* [shownoactivities]
@@ -4932,43 +4925,36 @@ gam print schema|schemas [todrive <ToDriveAttribute>*]
gam sendemail [recipient|to] <RecipientEntity> gam sendemail [recipient|to] <RecipientEntity>
[from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>] [from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage] [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
[subject <String>] [<MessageContent>] [html [<Boolean>]] [subject <String>]
[<MessageContent>]
(replace <Tag> <String>)* (replace <Tag> <String>)*
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)* (replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
(attach <FileName> [charset <Charset>])* [html [<Boolean>]] (attach <FileName> [charset <Charset>])*
(embedimage <FileName> <String>)* (embedimage <FileName> <String>)*
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>] [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)* (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
[threadid <String>]
gam <UserTypeEntity> sendemail recipient|to <RecipientEntity> gam <UserTypeEntity> sendemail recipient|to <RecipientEntity>
[replyto <EmailAddress>] [replyto <EmailAddress>]
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage] [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
[subject <String>] [<MessageContent>] [html [<Boolean>]] [subject <String>]
[<MessageContent>]
(replace <Tag> <String>)* (replace <Tag> <String>)*
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)* (replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
(attach <FileName> [charset <Charset>])* [html [<Boolean>]] (attach <FileName> [charset <Charset>])*
(embedimage <FileName> <String>)* (embedimage <FileName> <String>)*
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>] [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)* (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
[threadid <String>]
gam <UserTypeEntity> sendemail from <EmailAddress> gam <UserTypeEntity> sendemail from <EmailAddress>
[replyto <EmailAddress>] [replyto <EmailAddress>]
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage] [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
[subject <String>] [<MessageContent>] [html [<Boolean>]] [subject <String>]
[<MessageContent>]
(replace <Tag> <String>)* (replace <Tag> <String>)*
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)* (replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
(attach <FileName> [charset <Charset>])* [html [<Boolean>]] (attach <FileName> [charset <Charset>])*
(embedimage <FileName> <String>)* (embedimage <FileName> <String>)*
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>] [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)* (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
[threadid <String>]
gam <UserTypeEntity> sendreply
(((query <QueryGmail> [querytime<String> <Date>]*) [or|and])+) | (ids <MessageIDEntity>)
[replyto <EmailAddress>]
[subject <String>] [<MessageContent>] [html [<Boolean>]]
(attach <FileName> [charset <CharSet>])*
(embedimage <FileName> <String>)*
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
# Shared Drives - Administrator # Shared Drives - Administrator
@@ -5204,6 +5190,7 @@ gam create|add permissions <SharedDriveEntityAdmin> <DriveFilePermissionEntity>
<PermissionMatch>* [<PermissionMatchAction>] <PermissionMatch>* [<PermissionMatchAction>]
gam delete permissions <SharedDriveEntityAdmin> <DriveFilePermissionIDEntity> gam delete permissions <SharedDriveEntityAdmin> <DriveFilePermissionIDEntity>
<PermissionMatch>* [<PermissionMatchAction>] <PermissionMatch>* [<PermissionMatchAction>]
[enforceexpansiveaccess [<Boolean>]]
In these commands, you specify an administrator and then indicate that you want domain administrator access with the adminaccess option. In these commands, you specify an administrator and then indicate that you want domain administrator access with the adminaccess option.
@@ -5217,9 +5204,11 @@ gam <UserTypeEntity> create|add drivefileacl <SharedDriveEntityAdmin>
adminaccess adminaccess
gam <UserTypeEntity> update drivefileacl <SharedDriveEntityAdmin> <DriveFilePermissionIDorEmail> gam <UserTypeEntity> update drivefileacl <SharedDriveEntityAdmin> <DriveFilePermissionIDorEmail>
(role <DriveFileACLRole>) [expires|expiration <Time>] [removeexpiration [<Boolean>]] (role <DriveFileACLRole>) [expires|expiration <Time>] [removeexpiration [<Boolean>]]
[enforceexpansiveaccess [<Boolean>]]
[showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])] [showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])]
adminaccess adminaccess
gam <UserTypeEntity> delete drivefileacl <SharedDriveEntityAdmin> <DriveFilePermissionIDorEmail> gam <UserTypeEntity> delete drivefileacl <SharedDriveEntityAdmin> <DriveFilePermissionIDorEmail>
[enforceexpansiveaccess [<Boolean>]]
[showtitles] adminaccess [showtitles] adminaccess
gam <UserTypeEntity> info drivefileacl <SharedDriveEntityAdmin> <DriveFilePermissionIDorEmail> adminaccess gam <UserTypeEntity> info drivefileacl <SharedDriveEntityAdmin> <DriveFilePermissionIDorEmail> adminaccess
[showtitles] [showtitles]
@@ -5245,6 +5234,7 @@ gam <UserTypeEntity> create|add permissions <SharedDriveEntityAdmin> <DriveFileP
<PermissionMatch>* [<PermissionMatchAction>] <PermissionMatch>* [<PermissionMatchAction>]
gam <UserTypeEntity> delete permissions <SharedDriveEntityAdmin> <DriveFilePermissionIDEntity> adminaccess gam <UserTypeEntity> delete permissions <SharedDriveEntityAdmin> <DriveFilePermissionIDEntity> adminaccess
<PermissionMatch>* [<PermissionMatchAction>] <PermissionMatch>* [<PermissionMatchAction>]
[enforceexpansiveaccess [<Boolean>]]
In these commands, the Google administrator named in oauth2.txt is used. In these commands, the Google administrator named in oauth2.txt is used.
@@ -5702,7 +5692,6 @@ gam download storagefile <StorageBucketObjectName>
fullname| fullname|
gender| gender|
givenname|firstname| givenname|firstname|
guestaccountinfo|
id| id|
ims|im| ims|im|
includeinglobaladdresslist|gal| includeinglobaladdresslist|gal|
@@ -5710,7 +5699,6 @@ gam download storagefile <StorageBucketObjectName>
isdelegatedadmin|admin|isadmin| isdelegatedadmin|admin|isadmin|
isenforcedin2sv|is2svenforced| isenforcedin2sv|is2svenforced|
isenrolledin2sv|is2svenrolled| isenrolledin2sv|is2svenrolled|
isguestuser|
ismailboxsetup| ismailboxsetup|
keyword|keywords| keyword|keywords|
language|languages| language|languages|
@@ -5756,7 +5744,7 @@ gam download storagefile <StorageBucketObjectName>
(language clear|<LanguageList>)| (language clear|<LanguageList>)|
(lastname|familyname <String>)| (lastname|familyname <String>)|
(note clear|([text_html|text_plain] <UserNoteContent))| (note clear|([text_html|text_plain] <UserNoteContent))|
(ou|org|orgunitpath <OrgUnitPath>|<OrgUnitID>|root) (ou|org|orgunitpath <OrgUnitPath>|<OrgUnitID>)
(password (random [<Integer>])|(uniquerandom [<Integer>])| (password (random [<Integer>])|(uniquerandom [<Integer>])|
blocklogin| blocklogin|
prompt|uniqueprompt| prompt|uniqueprompt|
@@ -5812,12 +5800,12 @@ gam download storagefile <StorageBucketObjectName>
<UserClearAttribute> ::= <UserClearAttribute> ::=
(address clear)| (address clear)|
(otheremail clear)|
(externalid clear)| (externalid clear)|
(im clear)| (im clear)|
(keyword clear)| (keyword clear)|
(location clear)| (location clear)|
(organization clear)| (organization clear)|
(otheremail clear)|
(phone clear)| (phone clear)|
(posix clear)| (posix clear)|
(relation clear)| (relation clear)|
@@ -5830,18 +5818,6 @@ gam download storagefile <StorageBucketObjectName>
<UserMultiAttribute>| <UserMultiAttribute>|
<UserClearAttribute> <UserClearAttribute>
<UserMultiAttributeFilterName> ::=
address|addresses|
externalid|externalids|
im|ims|
keyword|keywords|
location|locations|
orgainzation|organizations|
otheremail|otheremails|
phone|phones|
relation|relations|
website|websites
gam create|add user <EmailAddress> [ignorenullpassword] <UserAttribute>* gam create|add user <EmailAddress> [ignorenullpassword] <UserAttribute>*
[verifynotinvitable|alwaysevict] [verifynotinvitable|alwaysevict]
(groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)* (groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)*
@@ -5896,8 +5872,6 @@ gam info user [<UserItem>]
[nolicenses|nolicences|licenses|licences] [nolicenses|nolicences|licenses|licences]
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)] [noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
[userview] <UserFieldName>* [fields <UserFieldNameList>] [userview] <UserFieldName>* [fields <UserFieldNameList>]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)] [(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
[formatjson] [formatjson]
@@ -5934,8 +5908,6 @@ gam info users <UserTypeEntity>
[nolicenses|nolicences|licenses|licences] [nolicenses|nolicences|licenses|licences]
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)] [noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
[userview] <UserFieldName>* [fields <UserFieldNameList>] [userview] <UserFieldName>* [fields <UserFieldNameList>]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)] [(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
[formatjson] [formatjson]
@@ -5972,8 +5944,6 @@ gam <UserTypeEntity> info users
[nolicenses|nolicences|licenses|licences] [nolicenses|nolicences|licenses|licences]
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)] [noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
[userview] <UserFieldName>* [fields <UserFieldNameList>] [userview] <UserFieldName>* [fields <UserFieldNameList>]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)] [(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
[formatjson] [formatjson]
@@ -5993,8 +5963,6 @@ gam print users [todrive <ToDriveAttribute>*]
[schemas|custom|customschemas all|<SchemaNameList>] [schemas|custom|customschemas all|<SchemaNameList>]
[emailpart|emailparts|username] [emailpart|emailparts|username]
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)] [userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]] [delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
[formatjson [quotechar <Character>]] [quoteplusphonenumbers] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>] [issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
@@ -6012,8 +5980,6 @@ gam print users [todrive <ToDriveAttribute>*] select <UserTypeEntity>
[schemas|custom|customschemas all|<SchemaNameList>] [schemas|custom|customschemas all|<SchemaNameList>]
[emailpart|emailparts|username] [emailpart|emailparts|username]
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)] [userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]] [delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
[formatjson [quotechar <Character>]] [quoteplusphonenumbers] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>] [issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
@@ -6029,8 +5995,6 @@ gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
[schemas|custom|customschemas all|<SchemaNameList>] [schemas|custom|customschemas all|<SchemaNameList>]
[emailpart|emailparts|username] [emailpart|emailparts|username]
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)] [userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]] [delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
[formatjson [quotechar <Character>]] [quoteplusphonenumbers] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>] [issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
@@ -6093,13 +6057,6 @@ gam <UserTypeEntity> show backupcodes|verificationcodes
gam <UserTypeEntity> print backupcodes|verificationcodes [todrive <ToDriveAttribute>*] gam <UserTypeEntity> print backupcodes|verificationcodes [todrive <ToDriveAttribute>*]
[delimiter <Character>] [countsonly] [delimiter <Character>] [countsonly]
# Users - Business Profile Accounts
gam <UserTypeEntity> show businessprofileaccounts
[type locationgroup|organization|personal|usergroup]
gam <UserTypeEntity> print businessprofileaccounts [todrive <ToDriveAttribute>*]
[type locationgroup|organization|personal|usergroup]
# Users - Calendars # Users - Calendars
<CalendarACLRole> ::= editor|freebusy|freebusyreader|owner|reader|writer <CalendarACLRole> ::= editor|freebusy|freebusyreader|owner|reader|writer
@@ -6530,8 +6487,7 @@ gam <UserTypeEntity> create chatspace
[description <String>] [guidelines <String>] [description <String>] [guidelines <String>]
[history <Boolean>] [history <Boolean>]
[<ChatContent>] [<ChatContent>]
[(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]] (addcsvdata <FieldName> <String>)*) | formatjson | returnidonly] [formatjson|returnidonly]
gam <UserTypeEntity> update chatspace <ChatSpace> gam <UserTypeEntity> update chatspace <ChatSpace>
[restricted|(audience <String>)]| [restricted|(audience <String>)]|
([displayname <String>] ([displayname <String>]
@@ -6950,7 +6906,6 @@ gam <UserTypeEntity> copy drivefile <DriveFileEntity>
[copyfilepermissions [<Boolean>]] [copyfilepermissions [<Boolean>]]
[copyfileinheritedpermissions [<Boolean>] [copyfileinheritedpermissions [<Boolean>]
[copyfilenoninheritedpermissions [<Boolean>] [copyfilenoninheritedpermissions [<Boolean>]
[copyfolderpermissions [<Boolean>]]
[copymergewithparentfolderpermissions [<Boolean>]] [copymergewithparentfolderpermissions [<Boolean>]]
[copymergedtopfolderpermissions [<Boolean>]] [copymergedtopfolderpermissions [<Boolean>]]
[copytopfolderpermissions [<Boolean>]] [copytopfolderpermissions [<Boolean>]]
@@ -6971,6 +6926,7 @@ gam <UserTypeEntity> copy drivefile <DriveFileEntity>
[sendemailifrequired [<Boolean>]] [sendemailifrequired [<Boolean>]]
[suppressnotselectedmessages [<Boolean>]] [suppressnotselectedmessages [<Boolean>]]
[verifyorganizer [<Boolean>]] [verifyorganizer [<Boolean>]]
[enforceexpansiveaccess [<Boolean>]]
gam <UserTypeEntity> move drivefile <DriveFileEntity> [newfilename <DriveFileName>] gam <UserTypeEntity> move drivefile <DriveFileEntity> [newfilename <DriveFileName>]
[summary [<Boolean>]] [showpermissionmessages [<Boolean>]] [summary [<Boolean>]] [showpermissionmessages [<Boolean>]]
@@ -6979,7 +6935,6 @@ gam <UserTypeEntity> move drivefile <DriveFileEntity> [newfilename <DriveFileNam
[createshortcutsfornonmovablefiles [<Boolean>]] [createshortcutsfornonmovablefiles [<Boolean>]]
[duplicatefiles overwriteolder|overwriteall|duplicatename|uniquename|skip] [duplicatefiles overwriteolder|overwriteall|duplicatename|uniquename|skip]
[duplicatefolders merge|duplicatename|uniquename|skip] [duplicatefolders merge|duplicatename|uniquename|skip]
[copyfolderpermissions [<Boolean>]]
[copymergewithparentfolderpermissions [<Boolean>]] [copymergewithparentfolderpermissions [<Boolean>]]
[copymergedtopfolderpermissions [<Boolean>]] [copymergedtopfolderpermissions [<Boolean>]]
[copytopfolderpermissions [<Boolean>]] [copytopfolderpermissions [<Boolean>]]
@@ -6995,6 +6950,7 @@ gam <UserTypeEntity> move drivefile <DriveFileEntity> [newfilename <DriveFileNam
[retainsourcefolders [<Boolean>]] [retainsourcefolders [<Boolean>]]
[sendemailifrequired [<Boolean>]] [sendemailifrequired [<Boolean>]]
[verifyorganizer [<Boolean>]] [verifyorganizer [<Boolean>]]
[enforceexpansiveaccess [<Boolean>]]
gam <UserTypeEntity> get document <DriveFileEntity> gam <UserTypeEntity> get document <DriveFileEntity>
[viewmode default|suggestions_inline|preview_suggestions_accepted|preview_without_suggestions] [viewmode default|suggestions_inline|preview_suggestions_accepted|preview_without_suggestions]
@@ -7101,10 +7057,10 @@ gam <UserTypeEntity> create|add drivefileacl <DriveFileEntity> [adminaccess|asad
[showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])] [showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])]
gam <UserTypeEntity> update drivefileacl <DriveFileEntity> <DriveFilePermissionIDorEmail> gam <UserTypeEntity> update drivefileacl <DriveFileEntity> <DriveFilePermissionIDorEmail>
(role <DriveFileACLRole>) [expires|expiration <Time>] [removeexpiration [<Boolean>]] (role <DriveFileACLRole>) [expires|expiration <Time>] [removeexpiration [<Boolean>]]
[updatesheetprotectedranges [<Boolean>]] [updatesheetprotectedranges [<Boolean>]] [enforceexpansiveaccess [<Boolean>]]
[showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])] [showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])]
gam <UserTypeEntity> delete drivefileacl <DriveFileEntity> <DriveFilePermissionIDorEmail> gam <UserTypeEntity> delete drivefileacl <DriveFileEntity> <DriveFilePermissionIDorEmail>
[updatesheetprotectedranges [<Boolean>]] [updatesheetprotectedranges [<Boolean>]] [enforceexpansiveaccess [<Boolean>]]
[showtitles] [showtitles]
gam <UserTypeEntity> info drivefileacl <DriveFileEntity> <DriveFilePermissionIDorEmail> gam <UserTypeEntity> info drivefileacl <DriveFileEntity> <DriveFilePermissionIDorEmail>
[showtitles] [showtitles]
@@ -7228,6 +7184,7 @@ gam <UserTypeEntity> print filerevisions <DriveFileEntity> [todrive <ToDriveAttr
gam <UserTypeEntity> transfer ownership <DriveFileEntity> <UserItem> gam <UserTypeEntity> transfer ownership <DriveFileEntity> <UserItem>
[<DriveFileParentAttribute>] [includetrashed] [norecursion [<Boolean>]] [<DriveFileParentAttribute>] [includetrashed] [norecursion [<Boolean>]]
[enforceexpansiveaccess [<Boolean>]]
(orderby <DriveFileOrderByFieldName> [ascending|descending])* (orderby <DriveFileOrderByFieldName> [ascending|descending])*
[preview] [filepath] [pathdelimiter <Character>] [buildtree] [preview] [filepath] [pathdelimiter <Character>] [buildtree]
[todrive <ToDriveAttribute>*] [todrive <ToDriveAttribute>*]
@@ -7236,6 +7193,7 @@ gam <UserTypeEntity> claim ownership <DriveFileEntity>
[skipids <DriveFileEntity>] [onlyusers|skipusers <UserTypeEntity>] [subdomains <DomainNameEntity>] [skipids <DriveFileEntity>] [onlyusers|skipusers <UserTypeEntity>] [subdomains <DomainNameEntity>]
[restricted [<Boolean>]] [writerscanshare|writerscantshare [<Boolean>]] [restricted [<Boolean>]] [writerscanshare|writerscantshare [<Boolean>]]
[keepuser | (retainrole commenter|reader|writer|editor|fileorganizer|none)] [noretentionmessages] [keepuser | (retainrole commenter|reader|writer|editor|fileorganizer|none)] [noretentionmessages]
[enforceexpansiveaccess [<Boolean>]]
(orderby <DriveFileOrderByFieldName> [ascending|descending])* (orderby <DriveFileOrderByFieldName> [ascending|descending])*
[preview] [filepath] [pathdelimiter <Character>] [buildtree] [preview] [filepath] [pathdelimiter <Character>] [buildtree]
[todrive <ToDriveAttribute>*] [todrive <ToDriveAttribute>*]
@@ -7243,6 +7201,7 @@ gam <UserTypeEntity> claim ownership <DriveFileEntity>
gam <UserTypeEntity> transfer drive <UserItem> [select <DriveFileEntity>] gam <UserTypeEntity> transfer drive <UserItem> [select <DriveFileEntity>]
[(targetfolderid <DriveFolderID>)|(targetfoldername <DriveFolderName>)] [(targetfolderid <DriveFolderID>)|(targetfoldername <DriveFolderName>)]
[targetuserfoldername <DriveFolderName>] [targetuserorphansfoldername <DriveFolderName>] [targetuserfoldername <DriveFolderName>] [targetuserorphansfoldername <DriveFolderName>]
[enforceexpansiveaccess [<Boolean>]]
[mergewithtarget [<Boolean>]] [mergewithtarget [<Boolean>]]
[skipids <DriveFileEntity>] [skipids <DriveFileEntity>]
[keepuser | (retainrole reader|commenter|writer|editor|fileorganizer|none)] [noretentionmessages] [keepuser | (retainrole reader|commenter|writer|editor|fileorganizer|none)] [noretentionmessages]
@@ -7534,7 +7493,7 @@ gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
[filenamematchpattern <REMatchPattern>] [filenamematchpattern <REMatchPattern>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed] [excludetrashed]
[showsize] [showsizeunits] [showmimetypesize] [showsize] [showmimetypesize]
[showlastmodification] [pathdelimiter <Character>] [showlastmodification] [pathdelimiter <Character>]
(addcsvdata <FieldName> <String>)* (addcsvdata <FieldName> <String>)*
[summary none|only|plus] [summaryuser <String>] [summary none|only|plus] [summaryuser <String>]
@@ -7550,7 +7509,7 @@ gam <UserTypeEntity> show filecounts
[filenamematchpattern <REMatchPattern>] [filenamematchpattern <REMatchPattern>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed] [excludetrashed]
[showsize] [showsizeunits] [showmimetypesize] [showsize] [showmimetypesize]
[showlastmodification] [pathdelimiter <Character>] [showlastmodification] [pathdelimiter <Character>]
[summary none|only|plus] [summaryuser <String>] [summary none|only|plus] [summaryuser <String>]
@@ -7620,7 +7579,7 @@ gam <UserTypeEntity> print filelist [todrive <ToDriveAttribute>*]
[excludetrashed] [excludetrashed]
[maxfiles <Integer>] [nodataheaders <String>] [maxfiles <Integer>] [nodataheaders <String>]
[countsonly [summary none|only|plus] [summaryuser <String>] [countsonly [summary none|only|plus] [summaryuser <String>]
[showsource] [showsize] [showsizeunits] [showmimetypesize]] [showsource] [showsize] [showmimetypesize]]
[countsrowfilter] [countsrowfilter]
[filepath|fullpath [folderpathonly [<Boolean>]] [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree] [filepath|fullpath [folderpathonly [<Boolean>]] [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree]
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)] [allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
@@ -8917,21 +8876,19 @@ gam <UserTypeEntity> show sheetrange <DriveFileEntity>
gam <UserTypeEntity> delete tokens clientid <ClientID> gam <UserTypeEntity> delete tokens clientid <ClientID>
gam info gcporgid
gam <UserTypeEntity> print tokens|token [todrive <ToDriveAttribute>*] [clientid <ClientID>] gam <UserTypeEntity> print tokens|token [todrive <ToDriveAttribute>*] [clientid <ClientID>]
[usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)] [usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)]
[delimiter <Character>] [gcpdetails] [delimiter <Character>]
gam <UserTypeEntity> show tokens|token|3lo|oauth [clientid <ClientID>] gam <UserTypeEntity> show tokens|token|3lo|oauth [clientid <ClientID>]
[usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)] [usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)]
[delimiter <Character>] [gcpdetails] [delimiter <Character>]
gam print tokens|token [todrive <ToDriveAttribute>*] [clientid <ClientID>] gam print tokens|token [todrive <ToDriveAttribute>*] [clientid <ClientID>]
[usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)] [usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)]
[delimiter <Character>] [gcpdetails] [delimiter <Character>]
[<UserTypeEntity>] [<UserTypeEntity>]
gam show tokens|token [clientid <ClientID>] gam show tokens|token [clientid <ClientID>]
[usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)] [usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)]
[delimiter <Character>] [gcpdetails] [delimiter <Character>]
[<UserTypeEntity>] [<UserTypeEntity>]
# Users - YouTube # Users - YouTube

View File

@@ -1,387 +1,3 @@
7.40.00
Updated `gam print|show businessprofileaccounts` (client access) to
`gam <UserTypeEntity> print|show businessprofileaccounts` (service account access).
You'll need to run `gam user user@domain.com update serviceaccount` and
select `2) Business Account Management API`.
7.39.08
Fixed bug in `gam oauth create` that caused a trap when `0) Business Account Management API` was selected.
Upgraded to Python 3.14.4 on macOS and Windows; Linux is still 3.14.3.
7.39.07
Upgraded to OpenSSL 3.6.2.
7.39.06
Fixed bug in `gam version checkrc`.
7.39.05
Added optional argument `preview` to `updateprimaryemail <RegularExpression> <EmailReplacement> [preview]`
for the following commands that causes GAM to preview, but not perform, primary email address changes.
This allows verification of the primary email address changes before commiting the changes.
```
gam update group <GroupEntity>
gam update cigroup <GroupEntity>
gam <UserTypeEntity> update user
```
7.39.04
Added `updateprimaryemail <RegularExpression> <EmailReplacement>` option to
`gam update group <GroupEntity>` and `gam update cigroup <GroupEntity>` to allow modifying
the group's current primary email address.
For example, to change the domain of a set of groups from the current domain.com to newdomain.com:
```
gam update group csvfile Groups.csv:email updateprimaryemail "^(.+)@domain.com$" "\1@newdomain.com"
```
7.39.03
Added the following options to `gam <UserTypeEntity> create chatspace` that can be used to capture
space details when creating chat spaces in bulk.
```
csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]] (addcsvdata <FieldName> <String>)*
```
See: https://github.com/GAM-team/GAM/wiki/Users-Chat#bulk-build-chat-spaces
7.39.02
Fixed progress messages for `gam <UserTypeEntity> print filelist` when permissions were being
displayed/matched for Shared Drives.
7.39.01
Updated `gam <UserTypeEntity> transfer drive <UserItem>` to handle the following error:
```
ERROR: 403: cannotDeletePermission - The authenticated user cannot delete the permission.
```
7.39.00
Deleted variable `enforce_expansive_access` from `gam.cfg` and removed option `enforceexpansiveaccess`
from the following commands as expansive access is now always enforced by Google on My Drives.
```
gam <UserTypeEntity> delete permissions
gam <UserTypeEntity> delete drivefileacl
gam <UserTypeEntity> update drivefileacl
gam <UserTypeEntity> copy drivefile
gam <UserTypeEntity> move drivefile
gam <UserTypeEntity> transfer ownership
gam <UserTypeEntity> claim ownership
```
7.38.02
Added license SKU `1010470009` for `AI Expanded Access`; abbreviation `aiexpandedaccess`.
Renamed license SKU `1010470001` from `Gemini Enterprise` to `Gemini Enterprise - Legacy`.
7.38.01
Added `root` as a synonym for '/' in command line arguments that specify an OU.
This is to avoid issues where a stand-alone `/` on the command line may be mis-interpreted
by the command line interpreter as a reference to the file system root.
7.38.00
Added variable `gcp_org_id` to `gam.cfg` that is used by the following commands;
by setting the value, additional API calls are eliminated.
```
gam create project
gam create gcpfolder
gam create|update|delete caalevel
gam print|show caalevels
gam print|show tokens gcpdetails
```
You can get and set the `gam.cfg/gcp_org_id` value with these commands:
```
$ gam info gcporgid
organizations/906207637890
$ gam config gcp_org_id organizations/906207637890 save
```
You can get and set the `gam.cfg/customer_id` value with these commands:
```
$ gam info customerid
C78abc9de
$ gam config customer_id C78abc9de save
```
Added the following options to `gam report <ActivityApplicationName>`.
```
applicationinfofilter <String>
networkinfofilter <String>
statusfilter <String>
includesensitivedata
```
7.37.00
Added new client access scopes used by `gam print tokens`.
```
[*] 52) Resource Manager API - Organizations readonly
[*] 53) Resource Manager API - Projects readonly
```
Added option `gcpdetails` to `gam print tokens` that uses these scopes to get additional project information.
7.36.03
Added command to send email replies that causes Gmail to recognize the message
in conversation mode for the user sending the reply and the user receiving the reply;
GAM supplies the necessary headers and options.
```
gam <UserTypeEntity> sendreply
(((query <QueryGmail> [querytime<String> <Date>]*) [or|and])+) | (ids <MessageIDEntity>)
[replyto <EmailAddress>]
[subject <String>] [<MessageContent>] [html [<Boolean>]]
(attach <FileName> [charset <CharSet>])*
(embedimage <FileName> <String>)*
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
gam user user@domain.com sendreply query "rfc822MsgId:<CAAMmEdqj43...1OsQ@mail.gmail.com>" textmessage "Thanks for the information"
gam user user@domain.com sendreply ids 19cfc3506c02c22b textmessage "Thanks for the information"
```
* See: https://github.com/GAM-team/GAM/wiki/Send-Email#conversation-mode
7.36.02
Added option `threadid <String>` to `gam [<UserTypeEntity>] sendemail` that causes Gmail to recognize the message
in conversation mode in for the user sending the message.
* See: https://github.com/GAM-team/GAM/wiki/Send-Email#conversation-mode
7.36.01
Fixed bug in `gam info|print|show policies` where the `policyQuery/query` field was not displayed.
Added option `noidmapping` to `gam info|print|show policies` to suppress adding the `policyQuery/groupEmail` and
`policyQuery/orgUnitPath` name fields that are mapped from the `policyQuery/group` and `policyQuery/orgInit` id fields.
7.36.00
Added options `filtermultiattrtype` and filtermultiattrcustom` to `gam info user` and
`gam print users` that support filtering `<UserMultiAttribute>` display based on `type` or `customType`.
```
<UserMultiAttributeFilterName> ::=
address|addresses|
externalid|externalids|
im|ims|
keyword|keywords|
location|locations|
orgainzation|organizations|
otheremail|otheremails|
phone|phones|
relation|relations|
website|websites
```
* `filtermultiattrtype <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `type` is `<String>`
* `filtermultiattrcustom <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `customType` is `<String>`
```
gam info user user@domain.com quick filtermultiattrtype organizations work filtermultiattrcustom phones private
```
7.35.03
Updated `gam <UserTypeEntity> print filelist|filecounts` to handle options `showsize` and `showsizeunits` as independent options.
* `showsize` - Display a column `Size` with a byte count
* `showsizeunits` - Display a column `SizeUnits` with a formatted size with units
If you select both options, you can sort multiple rows using the `Size` column.
7.35.02
Added option `showsizeunits` to `gam gam <UserTypeEntity> print filelist|filecounts` as an alternative to option `showsize`.
* `showsize` - 31549200951 - This is a byte count
* `showsizeunits` - 31.55 GB - This is as shown in the Admin console
7.35.01
The following commands have been updated to not verify the existence of `gam.cfg` credentials files
as the WARNING messages about the missing files can be confusing to new users setting up GAM.
```
gam checkconn
gam oauth|oauth2
gam version
```
7.35.00
Windows `gam-7.wx.yz-x86_64.msi` has been replaced with `gam-7.wx.yz-x86_64.exe`.
Windows `gam-7.wx.yz-arm64.msi` has been replaced with `gam-7.wx.yz-arm64.exe`.
Updated cacerts.pem to avoid to following error in `gam checkconn`.
```
Checking raw.githubusercontent.com (185.199.110.133) (2)... ERROR
Certificate verification failed. If you are behind a firewall / proxy server that does TLS / SSL inspection you may need to point GAM at your certificate authority file by setting cacerts_pem = /path/to/your/certauth.pem in gam.cfg.
```
If you have customized cacerts.pem, update your version with the `Operating CA: Let's Encrypt` values from the GAM default version.
7.34.13
Fixed bug in `gam info policies <CIPolicyNameEntity> ... formatjson` where extraneous line
`Show Info 1 Policy` was displayed.
7.34.12
Fixed build errors that prevented Windows zip files from being created.
Added option `returnidonly` to `gam create|update printer` that causes GAM to return just the ID
of the printer.
7.34.11
Updated gam-install.sh script for macOS/Linux to properly config GAM when the answer to the following question is No.
```
Can you run a full browser on this machine? (usually Y for macOS, N for Linux if you SSH into this machine)
```
7.34.10
Fixed bug where `formatjson quotechar <Character>` on the command line did not override `redirect csv <FileName> multiprocess quotechar <Character>`.
7.34.09
Updated `gam <UserTypeEntity> update photo` to delete the user's existing photo
before performing the update as the API update will succeed but not replace a user's existing self-set photo.
7.34.08
Rebuild to avoid the following error:
```
requests/__init__.py:113: RequestsDependencyWarning: urllib3 (2.6.3) or chardet (6.0.0.post1)/charset_normalizer (3.4.4) doesn't match a supported version!
```
7.34.07
Added the following command to create a guest user.
* See: https://support.google.com/a/answer/16558545
```
gam create guestuser <EmailAddress>
```
Added the following items to `<UserFieldName>`:
* `guestaccountinfo` - Additional guest-related metadata fields
* `isguestuser` - Indicates if the inserted user is a guest
7.34.06
Added option `copyfolderpermissions [<Boolean>]` to `gam <UserTypeEntity> copy|move drivefile`.
When `copyfolderpermissions false` is specified, no folder permissions are copied; this simplifies
disabling all folder permission copying.
When not specified or `copyfolderpermissions [true]` is specified, folder permissions are copied based on the following options:
```
copymergewithparentfolderpermissions [<Boolean>]
copymergedtopfolderpermissions [<Boolean>]
copytopfolderpermissions [<Boolean>]
copytopfolderiheritedpermissions [<Boolean>]
copytopfoldernoniheritedpermissions never|always|syncallfolders|syncupdatedfolders
copymergedsubfolderpermissions [<Boolean>]
copysubfolderpermissions [<Boolean>]
copysubfolderinheritedpermissions [<Boolean>]
copysubfoldernoniheritedpermissions never|always|syncallfolders|syncupdatedfolders
```
7.34.05
Updated `gam report <ActivityApplictionName>` to perform a reverse chronological sort
on all rows across multiple users and/or event names; this is consistent with the behavior
in the Admin console. Use option `notimesort` to suppress this sort.
7.34.04
Updated `gam <UserTypeEntity> create drivefileacl <DriveFileEntity> user <UserItem> role owner` to better
handle the case where the current owner of a file is suspended. Previously, the command was displayed as an error
even though the ownership was changed.
```
gam user currentowner@domain.com add drivefileacl <DriveFileID> user newowner@domain.com role owner
User: currentowner@domain.com, Add 1 Drive File/Folder ACL
User: currentowner@domain.com, Drive File/Folder ID: <DriveFileID>, Permission ID: newowner@domain.com, Add Failed: Sorry, the items were successfully shared but emails could not be sent to newowner@domain.com.
```
Now the command is displayed as a success with a note indicating that the ownership change email was not sent.
```
gam user currentowner@domain.com add drivefileacl <DriveFileID> user newowner@domain.com role owner
User: currentowner@domain.com, Add 1 Drive File/Folder ACL
User: currentowner@domain.com, Drive File/Folder ID: <DriveFileID>, Permission ID: newowner@domain.com, Added: Sorry, the items were successfully shared but emails could not be sent to newowner@domain.com.
New Owner
id: 10834698115409747890
type: user
emailAddress: newowner@domain.com
domain: domain.com
role: owner
permissionDetails:
role: writer
type: file
inherited: True
inheritedFrom: Unknown
role: owner
type: file
inherited: False
deleted: False
pendingOwner: False
```
7.34.03
Updated to Python 3.14.3
Updated Cryptography to 46.0.5
Updated `gam course <CourseID> create student|teacher <EmailAddress>` error message when
`<EmailAddress>` is not in a trusted domain to remove suggestion about creating an invitation.
7.34.02
Updated GAM to prevent errors like the following:
```
ERROR: Unable to find the server at oauth2.googleapis.com
ERROR: Unable to find the server at gmail.googleapis.com
```
If you experience any unexpected errors, post a message to:
* The GAM Discussion Forum (google-apps-manager@googlegroups.com)
* The GAM Public Chat Room (https://chat.google.com/app/chat/AAAA4BULhWo)
7.34.01
Updated `gam create|update adminrole` to handle the following errors:
```
ERROR: 400: invalid - Invalid Role privileges
ERROR: 400: required - Required parameter: [resource.privileges[n].service_id]
```
7.34.00
Added variable `csv_output_header_required` to `gam.cfg` that is a comma separated list of `<Strings>`
that are required to be in the list of column headers in the CSV file written by a gam print command.
This will typically be used to specify headers that are required in subsequent commands that process
the CSV file even if the API didn't return any data for those columns.
Updated the following commands to not require the `Directory API - Domains` scope
unless the `internal` or `external` options are used to request the member category.
```
gam info|print groups
gam print|show group-members
gam info|print cigroups
gam print|show cigroup-members
gam <UserTypeEntity> print|show filesharecounts
```
7.33.03 7.33.03
Fixed bug in `gam [<UserTypeEntity>] sendemail ... from <EmailAddress> replyto <EmailAddress>` Fixed bug in `gam [<UserTypeEntity>] sendemail ... from <EmailAddress> replyto <EmailAddress>`
@@ -1777,7 +1393,7 @@ Re-run the command specify a new service account name with: saname <ServiceAccou
Native support for Windows 11 Arm-based devices. Native support for Windows 11 Arm-based devices.
Renamed some macOS and Linux binary installer files to align on terminology. Everything is "arm64" now, no "aarch64". Renamed some MacOS and Linux binary installer files to align on terminology. Everything is "arm64" now, no "aarch64".
7.06.05 7.06.05
@@ -2386,7 +2002,7 @@ for `[R] 35) Meet API (supports readonly)` as it is a special case.
7.00.39 7.00.39
Supported macOS versions are now in the download filename. Supported MacOS versions are now in the download filename.
Minor code fixes. Minor code fixes.
@@ -4189,11 +3805,11 @@ See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Drive-Files-Display#fil
6.65.12 6.65.12
Additional updates on macOS when a `gam csv` command is interrupted with a contol-C. Additional updates on MacOS when a `gam csv` command is interrupted with a contol-C.
6.65.11 6.65.11
Updated multiprocessing to handle the following error that occurs on macOS when a `gam csv` command Updated multiprocessing to handle the following error that occurs on MacOS when a `gam csv` command
is interrupted with a contol-C. is interrupted with a contol-C.
``` ```
multiprocessing/resource_tracker.py:224: UserWarning: resource_tracker: There appear to be N leaked semaphore objects to clean up at shutdown multiprocessing/resource_tracker.py:224: UserWarning: resource_tracker: There appear to be N leaked semaphore objects to clean up at shutdown
@@ -6354,7 +5970,7 @@ Improved code for `gam [<UserTypeEntity>] create teamdrive <Name> ou <OrgUnitIte
6.29.04 6.29.04
Updated multiprocessing on macOS to use `spawn` instead of `fork` when starting subprocesses Updated multiprocessing on MacOS to use `spawn` instead of `fork` when starting subprocesses
as `fork` was unreliable when large numbers (>20) of threads were used; subprocesses would as `fork` was unreliable when large numbers (>20) of threads were used; subprocesses would
hang and never complete. hang and never complete.
@@ -6476,7 +6092,7 @@ then filters the list to only those in `<PeopleContactGroupItem>`; quota limits
6.28.03 6.28.03
Build macOS x86_64 and arm64 executables. Build MacOS x86_64 and arm64 executables.
6.28.02 6.28.02
@@ -6714,7 +6330,7 @@ This addresses the following issue:
Updated `gam <UserTypeEntity> add|delete|update|print|show datastudiopermissions` to display an appropriate Updated `gam <UserTypeEntity> add|delete|update|print|show datastudiopermissions` to display an appropriate
error message, `The caller does not have permission`, when the user doesn't have permission to execute the command. error message, `The caller does not have permission`, when the user doesn't have permission to execute the command.
Previously, the following incorrect error message was displayed: Previously, the following incorrect error message was displayed:
`ERROR: Data Studio API not enabled. Please run "gam update project" and "gam user user@domain.com update serviceaccount"` `ERROR: Data Studio API not enabled. Please run "gam update project" and "gam user user@domain.com check serviceaccount"`
6.26.14 6.26.14
@@ -6823,7 +6439,7 @@ Added command that allows checking if a user is a member of specific groups and
6.26.00 6.26.00
Build macOS universal version. Build MacOS universal version.
* Upgraded to OpenSSL 3.0.5 where possible. * Upgraded to OpenSSL 3.0.5 where possible.
@@ -6996,7 +6612,7 @@ and display drive labels on files. Please test/experiment and report any issues.
To use these commands you must add the 'Drive Labels API' to your project and update your service account authorization. To use these commands you must add the 'Drive Labels API' to your project and update your service account authorization.
``` ```
gam update project gam update project
gam user user@domain.com update serviceaccount gam user user@domain.com check serviceaccount
``` ```
Supported editions for this feature: Business Standard and Business Plus; Enterprise; Education Standard and Education Plus; G Suite Business; Essentials. Supported editions for this feature: Business Standard and Business Plus; Enterprise; Education Standard and Education Plus; G Suite Business; Essentials.
@@ -7194,7 +6810,7 @@ ERROR: 403: permissionDenied - Google Forms API has not been used in project XXX
``` ```
is replaced with is replaced with
``` ```
ERROR: Forms API not enabled. Please run "gam update project" and "gam user user@domain.com update serviceaccount" ERROR: Forms API not enabled. Please run "gam update project" and "gam user user@domain.com check serviceaccount"
``` ```
6.23.00 6.23.00
@@ -9552,7 +9168,7 @@ To use this feature you must add the `People API` to your project and authorize
* `People API - Other Contacts - read only`: https://www.googleapis.com/auth/contacts.other.readonly * `People API - Other Contacts - read only`: https://www.googleapis.com/auth/contacts.other.readonly
``` ```
gam update project gam update project
gam user user@domain.com update serviceaccount gam user user@domain.com check serviceaccount
``` ```
Added commands to display user's contact groups using the People API. Added commands to display user's contact groups using the People API.
@@ -9593,7 +9209,7 @@ To use these features you must add the `People API` to your project and authoriz
``` ```
gam update project gam update project
gam oauth create gam oauth create
gam user user@domain.com update serviceaccount gam user user@domain.com check serviceaccount
``` ```
Following Jay's lead, added new license SKU `Cloud Search`. Following Jay's lead, added new license SKU `Cloud Search`.
@@ -9632,7 +9248,7 @@ Added commands to display Data Studio assets and display/manage Data Studio perm
To use these commands you must add the `Data Studio API` to your project and update your service account authorization. To use these commands you must add the `Data Studio API` to your project and update your service account authorization.
``` ```
gam update project gam update project
gam user user@domain.com update serviceaccount gam user user@domain.com check serviceaccount
``` ```
This is a first release from me, experiment and use with caution. This is a first release from me, experiment and use with caution.
@@ -10675,7 +10291,7 @@ Added commands to support the new Device Management API.
To use these commands you must update your service account authorization. To use these commands you must update your service account authorization.
``` ```
gam user user@domain.com update serviceaccount gam user user@domain.com check serviceaccount
``` ```
In the following places a Google Admin email address is required; by default the admin email address in `oauth2.txt` is used. In the following places a Google Admin email address is required; by default the admin email address in `oauth2.txt` is used.
@@ -11665,7 +11281,7 @@ ID of the created Team Drive as output. This will be useful in scripts that crea
want to perform subsequent GAM command on the Team Drive. This ID will only be valid when the return code want to perform subsequent GAM command on the Team Drive. This ID will only be valid when the return code
of the command is 0; program accordingly. of the command is 0; program accordingly.
``` ```
Linux/macOS Linux/MacOS
teamDriveId=`gam user user@domain.com create teamdrive ... returnidonly` teamDriveId=`gam user user@domain.com create teamdrive ... returnidonly`
Windows PowerShell Windows PowerShell
$teamDriveId = & gam user user@domain.com create teamdrive ... returnidonly` $teamDriveId = & gam user user@domain.com create teamdrive ... returnidonly`
@@ -11757,7 +11373,7 @@ file ID of the created file as output. This will be useful in scripts that creat
want to perform subsequent GAM command on the file. This file ID will only be valid when the return code want to perform subsequent GAM command on the file. This file ID will only be valid when the return code
of the command is 0; program accordingly. of the command is 0; program accordingly.
``` ```
Linux/macOS Linux/MacOS
fileId=`gam user user@domain.com create drivefile ... returnidonly` fileId=`gam user user@domain.com create drivefile ... returnidonly`
Windows PowerShell Windows PowerShell
$fileId = & gam user user@domain.com create drivefile ... returnidonly` $fileId = & gam user user@domain.com create drivefile ... returnidonly`
@@ -15840,7 +15456,7 @@ gam print group-members [todrive [<ToDriveAttribute>]]
4.55.44 4.55.44
Improve macOS version of GAM's use of OpenSSL 1.0.2n. Improve MacOS version of GAM's use of OpenSSL 1.0.2n.
Recode pyinstaller .spec files. Recode pyinstaller .spec files.
4.55.43 4.55.43
@@ -15867,7 +15483,7 @@ Fixed bug that made some gam print commands throw an exception.
4.55.40 4.55.40
Update macOS version of GAM to use OpenSSL 1.0.2n. Update MacOS version of GAM to use OpenSSL 1.0.2n.
4.55.39 4.55.39
@@ -18693,7 +18309,7 @@ Changed gam info user formatjson to show licenses in SKU ID (SKU Display Name) f
4.42.00 4.42.00
Fixed problem where control-C was not recognized when multiple processes were running via gam batch/csv. Fixed problem where control-C was not recognized when multiple processes were running via gam batch/csv.
Gam terminates cleanly on Linux/macOS when you hit control-C in this situation; on Windows exceptions are Gam terminates cleanly on Linux/MacOS when you hit control-C in this situation; on Windows exceptions are
thrown but Gam does terminate. thrown but Gam does terminate.
4.41.08 4.41.08

View File

@@ -10,7 +10,7 @@ OPTIONS:
-d Directory where gam folder will be installed. Default is \$HOME/bin/ -d Directory where gam folder will be installed. Default is \$HOME/bin/
-a Architecture to install (x86_64, arm64). Default is to detect your arch with "uname -m". -a Architecture to install (x86_64, arm64). Default is to detect your arch with "uname -m".
-o OS we are running (linux, macos). Default is to detect your OS with "uname -s". -o OS we are running (linux, macos). Default is to detect your OS with "uname -s".
-b OS version. Default is to detect on macOS and Linux. -b OS version. Default is to detect on MacOS and Linux.
-l Just upgrade GAM to latest version. Skips project creation and auth. -l Just upgrade GAM to latest version. Skips project creation and auth.
-p Profile update (true, false). Should script add gam command to environment. Default is true. -p Profile update (true, false). Should script add gam command to environment. Default is true.
-u Admin user email address to use with GAM. Default is to prompt. -u Admin user email address to use with GAM. Default is to prompt.
@@ -247,7 +247,7 @@ case $gamos in
archgrep="-arm64\|-aarch64" archgrep="-arm64\|-aarch64"
;; ;;
*) *)
echo_red "ERROR: this installer currently only supports x86_64 and arm64 macOS. Looks like you're running on ${gamarch}. Exiting." echo_red "ERROR: this installer currently only supports x86_64 and arm64 MacOS. Looks like you're running on ${gamarch}. Exiting."
exit exit
;; ;;
esac esac
@@ -256,19 +256,19 @@ case $gamos in
versionless_urls=$(echo -e "$gam_macos_urls" | \ versionless_urls=$(echo -e "$gam_macos_urls" | \
grep -e "-macos-") grep -e "-macos-")
if [ "$versionless_urls" == "" ]; then if [ "$versionless_urls" == "" ]; then
# versions after 7.00.38 include macOS version info # versions after 7.00.38 include MacOS version info
gam_macos_vers=$(echo -e "$gam_macos_urls" | \ gam_macos_vers=$(echo -e "$gam_macos_urls" | \
grep --only-matching -e '-macos[0-9\.]*' | \ grep --only-matching -e '-macos[0-9\.]*' | \
cut -c 7-10) cut -c 7-10)
for gam_mac_ver in $gam_macos_vers; do for gam_mac_ver in $gam_macos_vers; do
if version_gt $currentversion $gam_mac_ver; then if version_gt $currentversion $gam_mac_ver; then
download_url=$(echo -e "$gam_macos_urls" | grep "$gam_mac_ver") download_url=$(echo -e "$gam_macos_urls" | grep "$gam_mac_ver")
echo_green "You are running macOS ${currentversion} Using GAM compiled against ${gam_mac_ver}" echo_green "You are running MacOS ${currentversion} Using GAM compiled against ${gam_mac_ver}"
break break
fi fi
done done
if [ -z ${download_url+x} ]; then if [ -z ${download_url+x} ]; then
echo_red "Sorry, you are running macOS ${osversion} but GAM on ${gamarch} requires macOS ${gam_mac_ver} or newer. Exiting." echo_red "Sorry, you are running MacOS ${osversion} but GAM on ${gamarch} requires MacOS ${gam_mac_ver} or newer. Exiting."
exit exit
fi fi
else else
@@ -283,13 +283,13 @@ case $gamos in
esac esac
download_url=$(echo -e "$download_urls" | grep -e $archgrep) download_url=$(echo -e "$download_urls" | grep -e $archgrep)
if version_gt "$osversion" "$minimum_version"; then if version_gt "$osversion" "$minimum_version"; then
echo_green "You are running macOS ${osversion}, good. Downloading GAM from ${download_url}." echo_green "You are running MacOS ${osversion}, good. Downloading GAM from ${download_url}."
else else
echo_red "Sorry, you are running macOS ${osversion} but GAM on ${gamarch} requires macOS ${minimum_version}. Exiting." echo_red "Sorry, you are running MacOS ${osversion} but GAM on ${gamarch} requires MacOS ${minimum_version}. Exiting."
exit exit
fi fi
if [ -z ${download_url+x} ]; then if [ -z ${download_url+x} ]; then
echo_red "Sorry, you are running macOS ${currentversion} but GAM on ${gamarch} requires macOS ${minimum_version}. Exiting." echo_red "Sorry, you are running MacOS ${currentversion} but GAM on ${gamarch} requires MacOS ${minimum_version}. Exiting."
exit exit
fi fi
fi fi
@@ -302,7 +302,7 @@ case $gamos in
grep ".zip") grep ".zip")
;; ;;
*) *)
echo_red "Sorry, this installer currently only supports Linux and macOS. Looks like you're running on ${gamos}. Exiting." echo_red "Sorry, this installer currently only supports Linux and MacOS. Looks like you're running on ${gamos}. Exiting."
exit exit
;; ;;
esac esac
@@ -368,15 +368,18 @@ if [ "$upgrade_only" = true ]; then
exit exit
fi fi
# Set config command
#config_cmd="config no_browser false"
while true; do while true; do
read -p "Can you run a full browser on this machine? (usually Y for macOS, N for Linux if you SSH into this machine) " yn read -p "Can you run a full browser on this machine? (usually Y for MacOS, N for Linux if you SSH into this machine) " yn
case $yn in case $yn in
[Yy]*) [Yy]*)
"$target_gam" config no_browser false save
break break
;; ;;
[Nn]*) [Nn]*)
"$target_gam" config no_browser true save # config_cmd="config no_browser true"
touch "$target_folder/nobrowser.txt" > /dev/null 2>&1
break break
;; ;;
*) *)
@@ -394,6 +397,7 @@ while true; do
if [ "$adminuser" == "" ]; then if [ "$adminuser" == "" ]; then
read -p "Please enter your Google Workspace admin email address: " adminuser read -p "Please enter your Google Workspace admin email address: " adminuser
fi fi
# "$target_gam" $config_cmd create project $adminuser
"$target_gam" create project $adminuser "$target_gam" create project $adminuser
rc=$? rc=$?
if (( $rc == 0 )); then if (( $rc == 0 )); then
@@ -419,6 +423,7 @@ while $project_created; do
read -p "Are you ready to authorize GAM to perform Google Workspace management operations as your admin account? (yes or no) " yn read -p "Are you ready to authorize GAM to perform Google Workspace management operations as your admin account? (yes or no) " yn
case $yn in case $yn in
[Yy]*) [Yy]*)
# "$target_gam" $config_cmd oauth create $adminuser
"$target_gam" oauth create $adminuser "$target_gam" oauth create $adminuser
rc=$? rc=$?
if (( $rc == 0 )); then if (( $rc == 0 )); then
@@ -448,6 +453,7 @@ while $admin_authorized; do
read -p "Please enter the email address of a regular Google Workspace user: " regularuser read -p "Please enter the email address of a regular Google Workspace user: " regularuser
fi fi
echo_yellow "Great! Checking service account scopes.This will fail the first time. Follow the steps to authorize and retry. It can take a few minutes for scopes to PASS after they've been authorized in the admin console." echo_yellow "Great! Checking service account scopes.This will fail the first time. Follow the steps to authorize and retry. It can take a few minutes for scopes to PASS after they've been authorized in the admin console."
# "$target_gam" $config_cmd user $regularuser check serviceaccount
"$target_gam" user $regularuser check serviceaccount "$target_gam" user $regularuser check serviceaccount
rc=$? rc=$?
if (( $rc == 0 )); then if (( $rc == 0 )); then
@@ -469,6 +475,7 @@ while $admin_authorized; do
done done
echo_green "Here's information about your new GAM installation:" echo_green "Here's information about your new GAM installation:"
#"$target_gam" $config_cmd save version extended
"$target_gam" version extended "$target_gam" version extended
rc=$? rc=$?
if (( $rc != 0 )); then if (( $rc != 0 )); then

View File

@@ -1,116 +0,0 @@
; --- 1. PREPROCESSOR DEFINITIONS ---
#define AppVersion GetEnv("GAMVERSION")
#if AppVersion == ""
#define AppVersion "7.0.0"
#endif
; Pull architecture directly from GitHub Actions environment variable
#define RunnerArch GetEnv("RUNNER_ARCH")
[Setup]
; --- 2. CORE APPLICATION INFO ---
AppId={{D86B52B2-EFE9-4F9D-8BA3-9D84B9B2D319}
AppName=GAM7
AppVersion={#AppVersion}
AppPublisher=GAM Team - google-apps-manager@googlegroups.com
DefaultDirName={sd}\GAM7
LicenseFile=dist\gam\gam7\LICENSE
PrivilegesRequired=admin
ChangesEnvironment=yes
; Tell Inno Setup to use a custom signtool defined via the command line
SignTool=gamsigntool
; --- 3. COMPRESSION & OPTIMIZATION ---
Compression=lzma2/ultra64
SolidCompression=yes
; --- 4. DYNAMIC ARCHITECTURE CONFIGURATION ---
; GitHub Actions RUNNER_ARCH is typically uppercase "ARM64" or "X64"
#if RunnerArch == "ARM64" || RunnerArch == "arm64"
ArchitecturesAllowed=arm64
ArchitecturesInstallIn64BitMode=arm64
OutputBaseFilename=gam-{#AppVersion}-windows-arm64
#else
ArchitecturesAllowed=x64compatible
ArchitecturesInstallIn64BitMode=x64compatible
OutputBaseFilename=gam-{#AppVersion}-windows-x86_64
#endif
[Messages]
; Custom error if an admin tries to run the ARM64 installer on an Intel machine
#if RunnerArch == "ARM64" || RunnerArch == "arm64"
WindowsVersionNotSupported=You downloaded the ARM64 version of GAM, but this computer has an Intel or AMD processor.%n%nPlease go back to the release page and download the x86_64 installer instead.
#endif
[Files]
; --- 5. DYNAMIC FILE INCLUSION ---
Source: "dist\gam\gam7\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
[Registry]
; --- 6. PATH ENVIRONMENT VARIABLE ---
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \
ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};{app}"; \
Check: NeedsAddPath(ExpandConstant('{app}'))
[Code]
const
ERROR_SUCCESS = 0;
function MsiEnumRelatedProducts(lpUpgradeCode: string; dwReserved: Integer; iProductIndex: Integer; lpProductBuf: string): Integer;
external 'MsiEnumRelatedProductsW@msi.dll stdcall';
function UninstallWixMSI(): Boolean;
var
UpgradeCode: string;
ProductCode: string;
ResultCode: Integer;
begin
UpgradeCode := '{D86B52B2-EFE9-4F9D-8BA3-9D84B9B2D319}';
ProductCode := StringOfChar(' ', 39);
ResultCode := MsiEnumRelatedProducts(UpgradeCode, 0, 0, ProductCode);
if ResultCode = ERROR_SUCCESS then
begin
ProductCode := Trim(ProductCode);
Exec('msiexec.exe', '/x ' + ProductCode + ' /qn /norestart', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
end;
Result := True;
end;
function InitializeSetup(): Boolean;
begin
// --- Architecture Warning for Emulation ---
#if RunnerArch != "ARM64" && RunnerArch != "arm64"
if IsArm64() then
begin
if MsgBox('Notice: You are installing the Intel (x86_64) build of GAM on an ARM processor.' + #13#10#13#10 +
'While this will work via Windows emulation, it will perform worse than the native ARM64 version.' + #13#10#13#10 +
'Do you want to continue with the installation anyway?',
mbConfirmation, MB_YESNO) = idNo then
begin
Result := False;
Exit;
end;
end;
#endif
UninstallWixMSI();
Result := True;
end;
function NeedsAddPath(Param: string): boolean;
var
OrigPath: string;
begin
if not RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
'Path', OrigPath)
then begin
Result := True;
exit;
end;
Result := Pos(';' + Param + ';', ';' + OrigPath + ';') = 0;
end;

View File

@@ -8,7 +8,7 @@
Manufacturer="GAM Team - google-apps-manager@googlegroups.com" Manufacturer="GAM Team - google-apps-manager@googlegroups.com"
UpgradeCode="D86B52B2-EFE9-4F9D-8BA3-9D84B9B2D319"> UpgradeCode="D86B52B2-EFE9-4F9D-8BA3-9D84B9B2D319">
<Package <Package
InstallerVersion="500" Compressed="yes" InstallScope="perMachine" /> InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade <MajorUpgrade
DowngradeErrorMessage= DowngradeErrorMessage=

File diff suppressed because it is too large Load Diff

View File

@@ -1,72 +1,3 @@
#
# This is a custom certificate authority bundle for GAM
# It's composed of Let's Encrypt Root CAs and Google's
# certificate bundle. This should be the minimal list of
# CAs required to talk to Google and Github.
# Operating CA: Let's Encrypt
# Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X1
# Subject: C = US, O = Internet Security Research Group, CN = ISRG Root X1
# Label: "ISRG Root X1"
# Serial: 172886928669790476064670243504169061120
# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e
# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8
# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
# Operating CA: Let's Encrypt
# Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X2
# Subject: C = US, O = Internet Security Research Group, CN = ISRG Root X2
# Label: "ISRG Root X2"
# Serial: 87493402998870891108772069816698636114
# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5
# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af
# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70
-----BEGIN CERTIFICATE-----
MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
/q4AaOeMSQ+2b1tbFfLn
-----END CERTIFICATE-----
# Operating CA: DigiCert # Operating CA: DigiCert
# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com # Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2026 Ross Scroggs All Rights Reserved. # Copyright (C) 2024 Ross Scroggs All Rights Reserved.
# #
# All Rights Reserved. # All Rights Reserved.
# #
@@ -107,7 +107,6 @@ class GamAction():
SAVE = 'save' SAVE = 'save'
SEND = 'send' SEND = 'send'
SENDEMAIL = 'snem' SENDEMAIL = 'snem'
SENDREPLY = 'sner'
SET = 'set ' SET = 'set '
SETUP = 'setu' SETUP = 'setu'
SHARE = 'shar' SHARE = 'shar'
@@ -226,7 +225,6 @@ class GamAction():
SAVE: ['Saved', 'Save'], SAVE: ['Saved', 'Save'],
SEND: ['Sent', 'Send'], SEND: ['Sent', 'Send'],
SENDEMAIL: ['Email Sent', 'Send Email'], SENDEMAIL: ['Email Sent', 'Send Email'],
SENDREPLY: ['Reply Sent', 'Send Reply'],
SET: ['Set', 'Set'], SET: ['Set', 'Set'],
SETUP: ['Set Up', 'Set Up'], SETUP: ['Set Up', 'Set Up'],
SHARE: ['Shared', 'Share'], SHARE: ['Shared', 'Share'],

View File

@@ -54,7 +54,6 @@ CLOUDIDENTITY_POLICY = 'cloudidentitypolicy'
CLOUDIDENTITY_POLICY_BETA = 'cloudidentitypolicybeta' CLOUDIDENTITY_POLICY_BETA = 'cloudidentitypolicybeta'
CLOUDIDENTITY_USERINVITATIONS = 'cloudidentityuserinvitations' CLOUDIDENTITY_USERINVITATIONS = 'cloudidentityuserinvitations'
CLOUDRESOURCEMANAGER = 'cloudresourcemanager' CLOUDRESOURCEMANAGER = 'cloudresourcemanager'
CLOUDRESOURCEMANAGERV1 = 'cloudresourcemanagerv1'
CONTACTS = 'contacts' CONTACTS = 'contacts'
CONTACTDELEGATION = 'contactdelegation' CONTACTDELEGATION = 'contactdelegation'
DATATRANSFER = 'datatransfer' DATATRANSFER = 'datatransfer'
@@ -104,6 +103,7 @@ TASKS = 'tasks'
VAULT = 'vault' VAULT = 'vault'
YOUTUBE = 'youtube' YOUTUBE = 'youtube'
# #
BUSINESSACCOUNTMANAGEMENT_SCOPE = 'https://www.googleapis.com/auth/business.manage'
CHROMEVERSIONHISTORY_URL = 'https://versionhistory.googleapis.com/v1/chrome/platforms' CHROMEVERSIONHISTORY_URL = 'https://versionhistory.googleapis.com/v1/chrome/platforms'
DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive' DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive'
DRIVE_FILE_SCOPE = 'https://www.googleapis.com/auth/drive.file' DRIVE_FILE_SCOPE = 'https://www.googleapis.com/auth/drive.file'
@@ -119,6 +119,7 @@ STORAGE_READONLY_SCOPE = 'https://www.googleapis.com/auth/devstorage.read_only'
STORAGE_READWRITE_SCOPE = 'https://www.googleapis.com/auth/devstorage.read_write' STORAGE_READWRITE_SCOPE = 'https://www.googleapis.com/auth/devstorage.read_write'
USERINFO_EMAIL_SCOPE = 'https://www.googleapis.com/auth/userinfo.email' # email USERINFO_EMAIL_SCOPE = 'https://www.googleapis.com/auth/userinfo.email' # email
USERINFO_PROFILE_SCOPE = 'https://www.googleapis.com/auth/userinfo.profile' # profile USERINFO_PROFILE_SCOPE = 'https://www.googleapis.com/auth/userinfo.profile' # profile
VAULT_SCOPES = ['https://www.googleapis.com/auth/ediscovery', 'https://www.googleapis.com/auth/ediscovery.readonly']
REQUIRED_SCOPES = [USERINFO_EMAIL_SCOPE, USERINFO_PROFILE_SCOPE] REQUIRED_SCOPES = [USERINFO_EMAIL_SCOPE, USERINFO_PROFILE_SCOPE]
REQUIRED_SCOPES_SET = set(REQUIRED_SCOPES) REQUIRED_SCOPES_SET = set(REQUIRED_SCOPES)
NUM_CLIENT_SCOPES_ERROR_LIMIT = 48 NUM_CLIENT_SCOPES_ERROR_LIMIT = 48
@@ -137,20 +138,6 @@ SCOPELESS_APIS = {
SERVICEACCOUNTLOOKUP, SERVICEACCOUNTLOOKUP,
} }
# #
# Scopes not in the discovery doc that are still valid for the API.
EXTRA_SCOPES = {
CLOUDRESOURCEMANAGER: ['https://www.googleapis.com/auth/cloudplatformfolders',
'https://www.googleapis.com/auth/cloudplatformfolders.readonly',
'https://www.googleapis.com/auth/cloudplatformprojects',
'https://www.googleapis.com/auth/cloudplatformprojects.readonly',
'https://www.googleapis.com/auth/cloudplatformorganizations',
'https://www.googleapis.com/auth/cloudplatformorganizations.readonly',
],
VAULT: ['https://www.googleapis.com/auth/ediscovery', 'https://www.googleapis.com/auth/ediscovery.readonly'],
}
EXTRA_SCOPES[CLOUDRESOURCEMANAGERV1] = EXTRA_SCOPES[CLOUDRESOURCEMANAGER]
APIS_NEEDING_ACCESS_TOKEN = { APIS_NEEDING_ACCESS_TOKEN = {
CBCM: ['https://www.googleapis.com/auth/admin.directory.device.chromebrowsers'] CBCM: ['https://www.googleapis.com/auth/admin.directory.device.chromebrowsers']
} }
@@ -263,8 +250,7 @@ _INFO = {
CLOUDIDENTITY_POLICY: {'name': 'Cloud Identity API - Policy', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, CLOUDIDENTITY_POLICY: {'name': 'Cloud Identity API - Policy', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDIDENTITY_POLICY_BETA: {'name': 'Cloud Identity API - Policy Beta', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, CLOUDIDENTITY_POLICY_BETA: {'name': 'Cloud Identity API - Policy Beta', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDIDENTITY_USERINVITATIONS: {'name': 'Cloud Identity API - User Invitations', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, CLOUDIDENTITY_USERINVITATIONS: {'name': 'Cloud Identity API - User Invitations', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDRESOURCEMANAGER: {'name': 'Resource Manager API v3', 'version': 'v3', 'v2discovery': True}, CLOUDRESOURCEMANAGER: {'name': 'Cloud Resource Manager API v3', 'version': 'v3', 'v2discovery': True},
CLOUDRESOURCEMANAGERV1: {'name': 'Resource Manager API v1', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudresourcemanager'},
CONTACTS: {'name': 'Contacts API', 'version': 'v3', 'v2discovery': False}, CONTACTS: {'name': 'Contacts API', 'version': 'v3', 'v2discovery': False},
CONTACTDELEGATION: {'name': 'Contact Delegation API', 'version': 'v1', 'v2discovery': True, 'localjson': True}, CONTACTDELEGATION: {'name': 'Contact Delegation API', 'version': 'v1', 'v2discovery': True, 'localjson': True},
DATATRANSFER: {'name': 'Data Transfer API', 'version': 'datatransfer_v1', 'v2discovery': True, 'mappedAPI': 'admin'}, DATATRANSFER: {'name': 'Data Transfer API', 'version': 'datatransfer_v1', 'v2discovery': True, 'mappedAPI': 'admin'},
@@ -317,6 +303,11 @@ _INFO = {
READONLY = ['readonly',] READONLY = ['readonly',]
_CLIENT_SCOPES = [ _CLIENT_SCOPES = [
{'name': 'Business Account Management API',
'api': BUSINESSACCOUNTMANAGEMENT,
'subscopes': [],
'offByDefault': True,
'scope': BUSINESSACCOUNTMANAGEMENT_SCOPE},
{'name': 'Calendar API', {'name': 'Calendar API',
'api': CALENDAR, 'api': CALENDAR,
'subscopes': READONLY, 'subscopes': READONLY,
@@ -327,9 +318,11 @@ _CLIENT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/admin.directory.device.chromebrowsers'}, 'scope': 'https://www.googleapis.com/auth/admin.directory.device.chromebrowsers'},
{'name': 'Chrome Management API - read only', {'name': 'Chrome Management API - read only',
'api': CHROMEMANAGEMENT, 'api': CHROMEMANAGEMENT,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/chrome.management.reports.readonly'}, 'scope': 'https://www.googleapis.com/auth/chrome.management.reports.readonly'},
{'name': 'Chrome Management API - AppDetails read only', {'name': 'Chrome Management API - AppDetails read only',
'api': CHROMEMANAGEMENT_APPDETAILS, 'api': CHROMEMANAGEMENT_APPDETAILS,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/chrome.management.appdetails.readonly'}, 'scope': 'https://www.googleapis.com/auth/chrome.management.appdetails.readonly'},
{'name': 'Chrome Management API - Profiles', {'name': 'Chrome Management API - Profiles',
'api': CHROMEMANAGEMENT_CHROMEPROFILES, 'api': CHROMEMANAGEMENT_CHROMEPROFILES,
@@ -337,6 +330,7 @@ _CLIENT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/chrome.management.profiles'}, 'scope': 'https://www.googleapis.com/auth/chrome.management.profiles'},
{'name': 'Chrome Management API - Telemetry read only', {'name': 'Chrome Management API - Telemetry read only',
'api': CHROMEMANAGEMENT_TELEMETRY, 'api': CHROMEMANAGEMENT_TELEMETRY,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/chrome.management.telemetry.readonly'}, 'scope': 'https://www.googleapis.com/auth/chrome.management.telemetry.readonly'},
{'name': 'Chrome Policy API', {'name': 'Chrome Policy API',
'api': CHROMEPOLICY, 'api': CHROMEPOLICY,
@@ -348,6 +342,7 @@ _CLIENT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/admin.chrome.printers'}, 'scope': 'https://www.googleapis.com/auth/admin.chrome.printers'},
{'name': 'Chrome Version History API', {'name': 'Chrome Version History API',
'api': CHROMEVERSIONHISTORY, 'api': CHROMEVERSIONHISTORY,
'subscopes': [],
'scope': ''}, 'scope': ''},
{'name': 'Classroom API - Courses', {'name': 'Classroom API - Courses',
'api': CLASSROOM, 'api': CLASSROOM,
@@ -375,9 +370,11 @@ _CLIENT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/classroom.guardianlinks.students'}, 'scope': 'https://www.googleapis.com/auth/classroom.guardianlinks.students'},
{'name': 'Classroom API - Profile Emails', {'name': 'Classroom API - Profile Emails',
'api': CLASSROOM, 'api': CLASSROOM,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/classroom.profile.emails'}, 'scope': 'https://www.googleapis.com/auth/classroom.profile.emails'},
{'name': 'Classroom API - Profile Photos', {'name': 'Classroom API - Profile Photos',
'api': CLASSROOM, 'api': CLASSROOM,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/classroom.profile.photos'}, 'scope': 'https://www.googleapis.com/auth/classroom.profile.photos'},
{'name': 'Classroom API - Rosters', {'name': 'Classroom API - Rosters',
'api': CLASSROOM, 'api': CLASSROOM,
@@ -407,6 +404,7 @@ _CLIENT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'}, 'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
{'name': 'Cloud Identity API - Policy Beta', {'name': 'Cloud Identity API - Policy Beta',
'api': CLOUDIDENTITY_POLICY_BETA, 'api': CLOUDIDENTITY_POLICY_BETA,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'}, 'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
{'name': 'Cloud Identity API - User Invitations', {'name': 'Cloud Identity API - User Invitations',
@@ -415,14 +413,17 @@ _CLIENT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/cloud-identity.userinvitations'}, 'scope': 'https://www.googleapis.com/auth/cloud-identity.userinvitations'},
{'name': 'Cloud Storage API (Read Only, Vault/Takeout Download, Cloud Storage)', {'name': 'Cloud Storage API (Read Only, Vault/Takeout Download, Cloud Storage)',
'api': STORAGEREAD, 'api': STORAGEREAD,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': STORAGE_READONLY_SCOPE}, 'scope': STORAGE_READONLY_SCOPE},
{'name': 'Cloud Storage API (Read/Write, Vault/Takeout Copy/Download, Cloud Storage)', {'name': 'Cloud Storage API (Read/Write, Vault/Takeout Copy/Download, Cloud Storage)',
'api': STORAGEWRITE, 'api': STORAGEWRITE,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': STORAGE_READWRITE_SCOPE}, 'scope': STORAGE_READWRITE_SCOPE},
{'name': 'Contacts API - Domain Shared Contacts', {'name': 'Contacts API - Domain Shared Contacts',
'api': CONTACTS, 'api': CONTACTS,
'subscopes': [],
'scope': 'https://www.google.com/m8/feeds'}, 'scope': 'https://www.google.com/m8/feeds'},
{'name': 'Contact Delegation API', {'name': 'Contact Delegation API',
'api': CONTACTDELEGATION, 'api': CONTACTDELEGATION,
@@ -450,7 +451,7 @@ _CLIENT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/admin.directory.group'}, 'scope': 'https://www.googleapis.com/auth/admin.directory.group'},
{'name': 'Directory API - Mobile Devices Directory', {'name': 'Directory API - Mobile Devices Directory',
'api': DIRECTORY, 'api': DIRECTORY,
'subscopes': ['readonly', 'actiononly'], 'subscopes': ['readonly', 'action'],
'scope': 'https://www.googleapis.com/auth/admin.directory.device.mobile'}, 'scope': 'https://www.googleapis.com/auth/admin.directory.device.mobile'},
{'name': 'Directory API - Organizational Units', {'name': 'Directory API - Organizational Units',
'api': DIRECTORY, 'api': DIRECTORY,
@@ -470,6 +471,7 @@ _CLIENT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/admin.directory.userschema'}, 'scope': 'https://www.googleapis.com/auth/admin.directory.userschema'},
{'name': 'Directory API - User Security', {'name': 'Directory API - User Security',
'api': DIRECTORY, 'api': DIRECTORY,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/admin.directory.user.security'}, 'scope': 'https://www.googleapis.com/auth/admin.directory.user.security'},
{'name': 'Directory API - Users', {'name': 'Directory API - Users',
'api': DIRECTORY, 'api': DIRECTORY,
@@ -477,19 +479,24 @@ _CLIENT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/admin.directory.user'}, 'scope': 'https://www.googleapis.com/auth/admin.directory.user'},
{'name': 'Email Audit API', {'name': 'Email Audit API',
'api': EMAIL_AUDIT, 'api': EMAIL_AUDIT,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': 'https://apps-apis.google.com/a/feeds/compliance/audit/'}, 'scope': 'https://apps-apis.google.com/a/feeds/compliance/audit/'},
{'name': 'Groups Migration API', {'name': 'Groups Migration API',
'api': GROUPSMIGRATION, 'api': GROUPSMIGRATION,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/apps.groups.migration'}, 'scope': 'https://www.googleapis.com/auth/apps.groups.migration'},
{'name': 'Groups Settings API', {'name': 'Groups Settings API',
'api': GROUPSSETTINGS, 'api': GROUPSSETTINGS,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/apps.groups.settings'}, 'scope': 'https://www.googleapis.com/auth/apps.groups.settings'},
{'name': 'License Manager API', {'name': 'License Manager API',
'api': LICENSING, 'api': LICENSING,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/apps.licensing'}, 'scope': 'https://www.googleapis.com/auth/apps.licensing'},
{'name': 'People Directory API - read only', {'name': 'People Directory API - read only',
'api': PEOPLE_DIRECTORY, 'api': PEOPLE_DIRECTORY,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/directory.readonly'}, 'scope': 'https://www.googleapis.com/auth/directory.readonly'},
{'name': 'People API', {'name': 'People API',
'api': PEOPLE, 'api': PEOPLE,
@@ -497,31 +504,29 @@ _CLIENT_SCOPES = [
'scope': PEOPLE_SCOPE}, 'scope': PEOPLE_SCOPE},
{'name': 'Pub / Sub API', {'name': 'Pub / Sub API',
'api': PUBSUB, 'api': PUBSUB,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': 'https://www.googleapis.com/auth/pubsub'}, 'scope': 'https://www.googleapis.com/auth/pubsub'},
{'name': 'Reports API - Audit Reports readonly', {'name': 'Reports API - Audit Reports',
'api': REPORTS, 'api': REPORTS,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/admin.reports.audit.readonly'}, 'scope': 'https://www.googleapis.com/auth/admin.reports.audit.readonly'},
{'name': 'Reports API - Usage Reports readonly', {'name': 'Reports API - Usage Reports',
'api': REPORTS, 'api': REPORTS,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/admin.reports.usage.readonly'}, 'scope': 'https://www.googleapis.com/auth/admin.reports.usage.readonly'},
{'name': 'Reseller API', {'name': 'Reseller API',
'api': RESELLER, 'api': RESELLER,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': 'https://www.googleapis.com/auth/apps.order'}, 'scope': 'https://www.googleapis.com/auth/apps.order'},
{'name': 'Resource Manager API - Organizations readonly',
'api': CLOUDRESOURCEMANAGER,
'offByDefault': True,
'scope': 'https://www.googleapis.com/auth/cloudplatformorganizations.readonly'},
{'name': 'Resource Manager API - Projects readonly',
'api': CLOUDRESOURCEMANAGER,
'offByDefault': True,
'scope': 'https://www.googleapis.com/auth/cloudplatformprojects.readonly'},
{'name': 'Service Account Lookup pseudo-API', {'name': 'Service Account Lookup pseudo-API',
'api': SERVICEACCOUNTLOOKUP, 'api': SERVICEACCOUNTLOOKUP,
'subscopes': [],
'scope': ''}, 'scope': ''},
{'name': 'Site Verification API', {'name': 'Site Verification API',
'api': SITEVERIFICATION, 'api': SITEVERIFICATION,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': 'https://www.googleapis.com/auth/siteverification'}, 'scope': 'https://www.googleapis.com/auth/siteverification'},
{'name': 'Vault API', {'name': 'Vault API',
@@ -533,24 +538,30 @@ _CLIENT_SCOPES = [
_COMMANDDATA_CLIENT_SCOPES = [ _COMMANDDATA_CLIENT_SCOPES = [
{'name': 'Drive API - commanddata_clientaccess', {'name': 'Drive API - commanddata_clientaccess',
'api': DRIVE3, 'api': DRIVE3,
'subscopes': [],
'scope': DRIVE_READONLY_SCOPE}, 'scope': DRIVE_READONLY_SCOPE},
{'name': 'Sheets API - commanddata_clientaccess readonly', {'name': 'Sheets API - commanddata_clientaccess',
'api': SHEETS, 'api': SHEETS,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/spreadsheets.readonly'}, 'scope': 'https://www.googleapis.com/auth/spreadsheets.readonly'},
] ]
_TODRIVE_CLIENT_SCOPES = [ _TODRIVE_CLIENT_SCOPES = [
{'name': 'Drive API - todrive_clientaccess', {'name': 'Drive API - todrive_clientaccess',
'api': DRIVE3, 'api': DRIVE3,
'subscopes': [],
'scope': DRIVE_SCOPE}, 'scope': DRIVE_SCOPE},
{'name': 'Drive File API - todrive_clientaccess', {'name': 'Drive File API - todrive_clientaccess',
'api': DRIVE3, 'api': DRIVE3,
'subscopes': [],
'scope': DRIVE_FILE_SCOPE}, 'scope': DRIVE_FILE_SCOPE},
{'name': 'Gmail API - todrive_clientaccess', {'name': 'Gmail API - todrive_clientaccess',
'api': GMAIL, 'api': GMAIL,
'subscopes': [],
'scope': GMAIL_SEND_SCOPE}, 'scope': GMAIL_SEND_SCOPE},
{'name': 'Sheets API - todrive_clientaccess', {'name': 'Sheets API - todrive_clientaccess',
'api': SHEETS, 'api': SHEETS,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/spreadsheets'}, 'scope': 'https://www.googleapis.com/auth/spreadsheets'},
] ]
@@ -559,14 +570,12 @@ OAUTH2SA_SCOPES = 'us_scopes'
_SVCACCT_SCOPES = [ _SVCACCT_SCOPES = [
{'name': 'AlertCenter API', {'name': 'AlertCenter API',
'api': ALERTCENTER, 'api': ALERTCENTER,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/apps.alerts'}, 'scope': 'https://www.googleapis.com/auth/apps.alerts'},
{'name': 'Analytics Admin API - read only', {'name': 'Analytics Admin API - read only',
'api': ANALYTICS_ADMIN, 'api': ANALYTICS_ADMIN,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/analytics.readonly'}, 'scope': 'https://www.googleapis.com/auth/analytics.readonly'},
{'name': 'Business Account Management API',
'api': BUSINESSACCOUNTMANAGEMENT,
'offByDefault': True,
'scope': 'https://www.googleapis.com/auth/business.manage'},
{'name': 'Calendar API', {'name': 'Calendar API',
'api': CALENDAR, 'api': CALENDAR,
'subscopes': READONLY, 'subscopes': READONLY,
@@ -602,9 +611,11 @@ _SVCACCT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/chat.admin.spaces'}, 'scope': 'https://www.googleapis.com/auth/chat.admin.spaces'},
{'name': 'Chat API - Spaces Delete', {'name': 'Chat API - Spaces Delete',
'api': CHAT_SPACES_DELETE, 'api': CHAT_SPACES_DELETE,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/chat.delete'}, 'scope': 'https://www.googleapis.com/auth/chat.delete'},
{'name': 'Chat API - Spaces Delete Admin', {'name': 'Chat API - Spaces Delete Admin',
'api': CHAT_SPACES_DELETE_ADMIN, 'api': CHAT_SPACES_DELETE_ADMIN,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/chat.admin.delete'}, 'scope': 'https://www.googleapis.com/auth/chat.admin.delete'},
{'name': 'Classroom API - Course Announcements', {'name': 'Classroom API - Course Announcements',
'api': CLASSROOM, 'api': CLASSROOM,
@@ -624,9 +635,11 @@ _SVCACCT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/classroom.coursework.students'}, 'scope': 'https://www.googleapis.com/auth/classroom.coursework.students'},
{'name': 'Classroom API - Profile Emails', {'name': 'Classroom API - Profile Emails',
'api': CLASSROOM, 'api': CLASSROOM,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/classroom.profile.emails'}, 'scope': 'https://www.googleapis.com/auth/classroom.profile.emails'},
{'name': 'Classroom API - Profile Photos', {'name': 'Classroom API - Profile Photos',
'api': CLASSROOM, 'api': CLASSROOM,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/classroom.profile.photos'}, 'scope': 'https://www.googleapis.com/auth/classroom.profile.photos'},
{'name': 'Classroom API - Rosters', {'name': 'Classroom API - Rosters',
'api': CLASSROOM, 'api': CLASSROOM,
@@ -636,21 +649,13 @@ _SVCACCT_SCOPES = [
'api': CLOUDIDENTITY_DEVICES, 'api': CLOUDIDENTITY_DEVICES,
'subscopes': READONLY, 'subscopes': READONLY,
'scope': 'https://www.googleapis.com/auth/cloud-identity.devices'}, 'scope': 'https://www.googleapis.com/auth/cloud-identity.devices'},
# {'name': 'Cloud Identity API - Policy',
# 'api': CLOUDIDENTITY_POLICY,
# 'subscopes': READONLY,
# 'roByDefault': True,
# 'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
# {'name': 'Cloud Identity API - Policy Beta',
# 'api': CLOUDIDENTITY_POLICY_BETA,
# 'offByDefault': True,
# 'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
# {'name': 'Cloud Identity User Invitations API', # {'name': 'Cloud Identity User Invitations API',
# 'api': CLOUDIDENTITY_USERINVITATIONS, # 'api': CLOUDIDENTITY_USERINVITATIONS,
# 'subscopes': READONLY, # 'subscopes': READONLY,
# 'scope': 'https://www.googleapis.com/auth/cloud-identity'}, # 'scope': 'https://www.googleapis.com/auth/cloud-identity'},
# {'name': 'Contacts API - Users', # {'name': 'Contacts API - Users',
# 'api': CONTACTS, # 'api': CONTACTS,
# 'subscopes': [],
# 'scope': 'https://www.google.com/m8/feeds'}, # 'scope': 'https://www.google.com/m8/feeds'},
{'name': 'Drive API', {'name': 'Drive API',
'api': DRIVE3, 'api': DRIVE3,
@@ -658,6 +663,7 @@ _SVCACCT_SCOPES = [
'scope': DRIVE_SCOPE}, 'scope': DRIVE_SCOPE},
{'name': 'Drive Activity API v2 - must pair with Drive API', {'name': 'Drive Activity API v2 - must pair with Drive API',
'api': DRIVEACTIVITY, 'api': DRIVEACTIVITY,
'subscopes': [],
'scope': [DRIVE_READONLY_SCOPE, 'scope': [DRIVE_READONLY_SCOPE,
'https://www.googleapis.com/auth/drive.activity']}, 'https://www.googleapis.com/auth/drive.activity']},
{'name': 'Drive Labels API - Admin', {'name': 'Drive Labels API - Admin',
@@ -674,24 +680,30 @@ _SVCACCT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/documents'}, 'scope': 'https://www.googleapis.com/auth/documents'},
{'name': 'Forms API - must pair with Drive API', {'name': 'Forms API - must pair with Drive API',
'api': FORMS, 'api': FORMS,
'subscopes': [],
'scope': [DRIVE_READONLY_SCOPE, 'scope': [DRIVE_READONLY_SCOPE,
'https://www.googleapis.com/auth/forms.body', 'https://www.googleapis.com/auth/forms.body',
'https://www.googleapis.com/auth/forms.responses.readonly']}, 'https://www.googleapis.com/auth/forms.responses.readonly']},
{'name': 'Gmail API - Full Access (Labels, Messages)', {'name': 'Gmail API - Full Access (Labels, Messages)',
'api': GMAIL, 'api': GMAIL,
'subscopes': [],
'scope': 'https://mail.google.com/'}, 'scope': 'https://mail.google.com/'},
{'name': 'Gmail API - Full Access (Labels, Messages) except delete message', {'name': 'Gmail API - Full Access (Labels, Messages) except delete message',
'api': GMAIL, 'api': GMAIL,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/gmail.modify'}, 'scope': 'https://www.googleapis.com/auth/gmail.modify'},
{'name': 'Gmail API - Basic Settings (Filters, IMAP, Language, POP, Vacation) - read/write, Sharing Settings (Delegates, Forwarding, SendAs) - read', {'name': 'Gmail API - Basic Settings (Filters, IMAP, Language, POP, Vacation) - read/write, Sharing Settings (Delegates, Forwarding, SendAs) - read',
'api': GMAIL, 'api': GMAIL,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/gmail.settings.basic'}, 'scope': 'https://www.googleapis.com/auth/gmail.settings.basic'},
{'name': 'Gmail API - Sharing Settings (Delegates, Forwarding, SendAs) - write', {'name': 'Gmail API - Sharing Settings (Delegates, Forwarding, SendAs) - write',
'api': GMAIL, 'api': GMAIL,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/gmail.settings.sharing'}, 'scope': 'https://www.googleapis.com/auth/gmail.settings.sharing'},
# {'name': 'Identity and Access Management API', # {'name': 'Identity and Access Management API',
# 'api': IAM, # 'api': IAM,
# 'offByDefault': True, # 'offByDefault': True,
# 'subscopes': [],
# 'scope': CLOUD_PLATFORM_SCOPE}, # 'scope': CLOUD_PLATFORM_SCOPE},
{'name': 'Keep API', {'name': 'Keep API',
'api': KEEP, 'api': KEEP,
@@ -703,13 +715,16 @@ _SVCACCT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/datastudio'}, 'scope': 'https://www.googleapis.com/auth/datastudio'},
{'name': 'Meet API - Manage/Display Meeting Spaces', {'name': 'Meet API - Manage/Display Meeting Spaces',
'api': MEET_SPACES, 'api': MEET_SPACES,
'subscopes': [],
'scope': ['https://www.googleapis.com/auth/meetings.space.created', 'scope': ['https://www.googleapis.com/auth/meetings.space.created',
'https://www.googleapis.com/auth/meetings.space.settings']}, 'https://www.googleapis.com/auth/meetings.space.settings']},
{'name': 'Meet API - Read Meeting Spaces metadata readonly', {'name': 'Meet API - Read Meeting Spaces metadata',
'api': MEET_READONLY, 'api': MEET_READONLY,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/meetings.space.readonly'}, 'scope': 'https://www.googleapis.com/auth/meetings.space.readonly'},
{'name': 'OAuth2 API', {'name': 'OAuth2 API',
'api': OAUTH2, 'api': OAUTH2,
'subscopes': [],
'scope': USERINFO_PROFILE_SCOPE}, 'scope': USERINFO_PROFILE_SCOPE},
{'name': 'People API', {'name': 'People API',
'api': PEOPLE, 'api': PEOPLE,
@@ -717,12 +732,15 @@ _SVCACCT_SCOPES = [
'scope': PEOPLE_SCOPE}, 'scope': PEOPLE_SCOPE},
{'name': 'People Directory API - read only', {'name': 'People Directory API - read only',
'api': PEOPLE_DIRECTORY, 'api': PEOPLE_DIRECTORY,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/directory.readonly'}, 'scope': 'https://www.googleapis.com/auth/directory.readonly'},
{'name': 'People API - Other Contacts - read only', {'name': 'People API - Other Contacts - read only',
'api': PEOPLE_OTHERCONTACTS, 'api': PEOPLE_OTHERCONTACTS,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/contacts.other.readonly'}, 'scope': 'https://www.googleapis.com/auth/contacts.other.readonly'},
{'name': 'Search Console API - read only', {'name': 'Search Console API - read only',
'api': SEARCHCONSOLE, 'api': SEARCHCONSOLE,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': 'https://www.googleapis.com/auth/webmasters.readonly'}, 'scope': 'https://www.googleapis.com/auth/webmasters.readonly'},
{'name': 'Sheets API', {'name': 'Sheets API',
@@ -731,14 +749,17 @@ _SVCACCT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/spreadsheets'}, 'scope': 'https://www.googleapis.com/auth/spreadsheets'},
{'name': 'Site Verification API', {'name': 'Site Verification API',
'api': SITEVERIFICATION, 'api': SITEVERIFICATION,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': 'https://www.googleapis.com/auth/siteverification'}, 'scope': 'https://www.googleapis.com/auth/siteverification'},
{'name': 'Tag Manager API - Accounts, Containers, Workspaces, Tags - read only', {'name': 'Tag Manager API - Accounts, Containers, Workspaces, Tags - read only',
'api': TAGMANAGER, 'api': TAGMANAGER,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': 'https://www.googleapis.com/auth/tagmanager.readonly'}, 'scope': 'https://www.googleapis.com/auth/tagmanager.readonly'},
{'name': 'Tag Manager API - Users', {'name': 'Tag Manager API - Users',
'api': TAGMANAGER_USERS, 'api': TAGMANAGER_USERS,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': 'https://www.googleapis.com/auth/tagmanager.manage.users'}, 'scope': 'https://www.googleapis.com/auth/tagmanager.manage.users'},
{'name': 'Tasks API', {'name': 'Tasks API',
@@ -747,6 +768,7 @@ _SVCACCT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/tasks'}, 'scope': 'https://www.googleapis.com/auth/tasks'},
{'name': 'Youtube API - read only', {'name': 'Youtube API - read only',
'api': YOUTUBE, 'api': YOUTUBE,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': 'https://www.googleapis.com/auth/youtube.readonly'}, 'scope': 'https://www.googleapis.com/auth/youtube.readonly'},
] ]
@@ -754,25 +776,30 @@ _SVCACCT_SCOPES = [
_SVCACCT_SPECIAL_SCOPES = [ _SVCACCT_SPECIAL_SCOPES = [
{'name': 'Drive API - write todrive data - has access to all Drive', {'name': 'Drive API - write todrive data - has access to all Drive',
'api': DRIVETD, 'api': DRIVETD,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': DRIVE_SCOPE}, 'scope': DRIVE_SCOPE},
{'name': 'Gmail API - Full Access - read only', {'name': 'Gmail API - Full Access - read only',
'api': GMAIL, 'api': GMAIL,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': 'https://www.googleapis.com/auth/gmail.readonly'}, 'scope': 'https://www.googleapis.com/auth/gmail.readonly'},
{'name': 'Gmail API - Send Messages - including todrive', {'name': 'Gmail API - Send Messages - including todrive',
'api': GMAIL, 'api': GMAIL,
'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': GMAIL_SEND_SCOPE}, 'scope': GMAIL_SEND_SCOPE},
{'name': 'Sheets API - write todrive data - has access to all Sheets', {'name': 'Sheets API - write todrive data - has access to all Sheets',
'api': SHEETSTD, 'api': SHEETSTD,
'offByDefault': True, 'offByDefault': True,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/spreadsheets'}, 'scope': 'https://www.googleapis.com/auth/spreadsheets'},
] ]
_USER_SVCACCT_ONLY_SCOPES = [ _USER_SVCACCT_ONLY_SCOPES = [
{'name': 'Groups Migration API', {'name': 'Groups Migration API',
'api': GROUPSMIGRATION, 'api': GROUPSMIGRATION,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/apps.groups.migration'}, 'scope': 'https://www.googleapis.com/auth/apps.groups.migration'},
] ]
@@ -812,7 +839,7 @@ def getClientScopesURLs(commanddataClientAccess, todriveClientAccess):
def getSvcAcctScopeAPI(uscope): def getSvcAcctScopeAPI(uscope):
for scope in _SVCACCT_SCOPES: for scope in _SVCACCT_SCOPES:
if uscope == scope['scope'] or (uscope.endswith('.readonly') and 'readonly' in scope.get('subscopes', [])): if uscope == scope['scope'] or (uscope.endswith('.readonly') and 'readonly' in scope['subscopes']):
return scope['api'] return scope['api']
return None return None
@@ -840,7 +867,7 @@ def findAPIforScope(scopesList):
if cscope['scope'] == scope: if cscope['scope'] == scope:
requiredAPIs.append(cscope['name']) requiredAPIs.append(cscope['name'])
return True return True
if 'readonly' in cscope.get('subscopes', []) and cscope['scope']+'.readonly' == scope: if cscope['subscopes'] == READONLY and cscope['scope']+'.readonly' == scope:
requiredAPIs.append(cscope['name']+' (supports readonly)') requiredAPIs.append(cscope['name']+' (supports readonly)')
return True return True
return False return False

View File

@@ -171,12 +171,12 @@ EMAIL_BATCH_SIZE = 'email_batch_size'
ENABLE_DASA = 'enable_dasa' ENABLE_DASA = 'enable_dasa'
# Enable Cloud Session Reauthentication by borrowing a RAPT token from gcloud command # Enable Cloud Session Reauthentication by borrowing a RAPT token from gcloud command
ENABLE_GCLOUD_REAUTH = 'enable_gcloud_reauth' ENABLE_GCLOUD_REAUTH = 'enable_gcloud_reauth'
# Value for enforceExpansiveAccess for commands that delete or update drive file ACLs/permissions.
ENFORCE_EXPANSIVE_ACCESS = 'enforce_expansive_access'
# When retrieving lists of calendar events from API, how many should be retrieved in each chunk # When retrieving lists of calendar events from API, how many should be retrieved in each chunk
EVENT_MAX_RESULTS = 'event_max_results' EVENT_MAX_RESULTS = 'event_max_results'
# Path to extra_args.txt # Path to extra_args.txt
EXTRA_ARGS = 'extra_args' EXTRA_ARGS = 'extra_args'
# Google Cloud Project Organization ID
GCP_ORG_ID = 'gcp_org_id'
# Gmail CSE certificates directory # Gmail CSE certificates directory
GMAIL_CSE_INCERT_DIR = 'gmail_cse_incert_dir' GMAIL_CSE_INCERT_DIR = 'gmail_cse_incert_dir'
# Gmail CSE KACL wrapped key files # Gmail CSE KACL wrapped key files
@@ -331,7 +331,7 @@ CSV_INPUT_ROW_FILTER_ITEMS = {CSV_INPUT_ROW_FILTER, CSV_INPUT_ROW_FILTER_MODE,
CSV_OUTPUT_ROW_FILTER_ITEMS = {CSV_OUTPUT_HEADER_FILTER, CSV_OUTPUT_HEADER_DROP_FILTER, CSV_OUTPUT_ROW_FILTER_ITEMS = {CSV_OUTPUT_HEADER_FILTER, CSV_OUTPUT_HEADER_DROP_FILTER,
CSV_OUTPUT_HEADER_FORCE, CSV_OUTPUT_HEADER_ORDER, CSV_OUTPUT_HEADER_FORCE, CSV_OUTPUT_HEADER_ORDER,
CSV_OUTPUT_HEADER_REQUIRED, # CSV_OUTPUT_HEADER_REQUIRED,
CSV_OUTPUT_ROW_FILTER, CSV_OUTPUT_ROW_FILTER_MODE, CSV_OUTPUT_ROW_FILTER, CSV_OUTPUT_ROW_FILTER_MODE,
CSV_OUTPUT_ROW_DROP_FILTER, CSV_OUTPUT_ROW_DROP_FILTER_MODE, CSV_OUTPUT_ROW_DROP_FILTER, CSV_OUTPUT_ROW_DROP_FILTER_MODE,
CSV_OUTPUT_ROW_LIMIT} CSV_OUTPUT_ROW_LIMIT}
@@ -376,7 +376,7 @@ Defaults = {
CSV_OUTPUT_HEADER_DROP_FILTER: '', CSV_OUTPUT_HEADER_DROP_FILTER: '',
CSV_OUTPUT_HEADER_FORCE: '', CSV_OUTPUT_HEADER_FORCE: '',
CSV_OUTPUT_HEADER_ORDER: '', CSV_OUTPUT_HEADER_ORDER: '',
CSV_OUTPUT_HEADER_REQUIRED: '', # CSV_OUTPUT_HEADER_REQUIRED: '',
CSV_OUTPUT_LINE_TERMINATOR: 'lf', CSV_OUTPUT_LINE_TERMINATOR: 'lf',
CSV_OUTPUT_QUOTE_CHAR: '\'"\'', CSV_OUTPUT_QUOTE_CHAR: '\'"\'',
CSV_OUTPUT_ROW_FILTER: '', CSV_OUTPUT_ROW_FILTER: '',
@@ -396,13 +396,13 @@ Defaults = {
DEVICE_MAX_RESULTS: '200', DEVICE_MAX_RESULTS: '200',
DOMAIN: '', DOMAIN: '',
DRIVE_DIR: '', DRIVE_DIR: '',
ENFORCE_EXPANSIVE_ACCESS: TRUE,
DRIVE_MAX_RESULTS: '1000', DRIVE_MAX_RESULTS: '1000',
EMAIL_BATCH_SIZE: '50', EMAIL_BATCH_SIZE: '50',
ENABLE_DASA: FALSE, ENABLE_DASA: FALSE,
ENABLE_GCLOUD_REAUTH: FALSE, ENABLE_GCLOUD_REAUTH: FALSE,
EVENT_MAX_RESULTS: '250', EVENT_MAX_RESULTS: '250',
EXTRA_ARGS: '', EXTRA_ARGS: '',
GCP_ORG_ID: '',
GMAIL_CSE_INCERT_DIR: '', GMAIL_CSE_INCERT_DIR: '',
GMAIL_CSE_INKEY_DIR: '', GMAIL_CSE_INKEY_DIR: '',
INPUT_DIR: '.', INPUT_DIR: '.',
@@ -550,7 +550,7 @@ VAR_INFO = {
CSV_OUTPUT_HEADER_DROP_FILTER: {VAR_TYPE: TYPE_HEADERFILTER}, CSV_OUTPUT_HEADER_DROP_FILTER: {VAR_TYPE: TYPE_HEADERFILTER},
CSV_OUTPUT_HEADER_FORCE: {VAR_TYPE: TYPE_HEADERFORCEREQUIRED}, CSV_OUTPUT_HEADER_FORCE: {VAR_TYPE: TYPE_HEADERFORCEREQUIRED},
CSV_OUTPUT_HEADER_ORDER: {VAR_TYPE: TYPE_HEADERORDER}, CSV_OUTPUT_HEADER_ORDER: {VAR_TYPE: TYPE_HEADERORDER},
CSV_OUTPUT_HEADER_REQUIRED: {VAR_TYPE: TYPE_HEADERFORCEREQUIRED}, # CSV_OUTPUT_HEADER_REQUIRED: {VAR_TYPE: TYPE_HEADERFORCEREQUIRED},
CSV_OUTPUT_LINE_TERMINATOR: {VAR_TYPE: TYPE_CHOICE, VAR_CHOICES: {'cr': '\r', 'lf': '\n', 'crlf': '\r\n'}}, CSV_OUTPUT_LINE_TERMINATOR: {VAR_TYPE: TYPE_CHOICE, VAR_CHOICES: {'cr': '\r', 'lf': '\n', 'crlf': '\r\n'}},
CSV_OUTPUT_QUOTE_CHAR: {VAR_TYPE: TYPE_CHARACTER}, CSV_OUTPUT_QUOTE_CHAR: {VAR_TYPE: TYPE_CHARACTER},
CSV_OUTPUT_ROW_FILTER: {VAR_TYPE: TYPE_ROWFILTER}, CSV_OUTPUT_ROW_FILTER: {VAR_TYPE: TYPE_ROWFILTER},
@@ -570,13 +570,13 @@ VAR_INFO = {
DEVICE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 200)}, DEVICE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 200)},
DOMAIN: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'GA_DOMAIN', VAR_LIMITS: (0, None)}, DOMAIN: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'GA_DOMAIN', VAR_LIMITS: (0, None)},
DRIVE_DIR: {VAR_TYPE: TYPE_DIRECTORY, VAR_ENVVAR: 'GAMDRIVEDIR'}, DRIVE_DIR: {VAR_TYPE: TYPE_DIRECTORY, VAR_ENVVAR: 'GAMDRIVEDIR'},
ENFORCE_EXPANSIVE_ACCESS: {VAR_TYPE: TYPE_BOOLEAN},
DRIVE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 1000)}, DRIVE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 1000)},
EMAIL_BATCH_SIZE: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 100)}, EMAIL_BATCH_SIZE: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 100)},
ENABLE_DASA: {VAR_TYPE: TYPE_BOOLEAN, VAR_SIGFILE: 'enabledasa.txt', VAR_SFFT: (FALSE, TRUE)}, ENABLE_DASA: {VAR_TYPE: TYPE_BOOLEAN, VAR_SIGFILE: 'enabledasa.txt', VAR_SFFT: (FALSE, TRUE)},
ENABLE_GCLOUD_REAUTH: {VAR_TYPE: TYPE_BOOLEAN}, ENABLE_GCLOUD_REAUTH: {VAR_TYPE: TYPE_BOOLEAN},
EVENT_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 2500)}, EVENT_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 2500)},
EXTRA_ARGS: {VAR_TYPE: TYPE_FILE, VAR_SIGFILE: FN_EXTRA_ARGS_TXT, VAR_SFFT: ('', FN_EXTRA_ARGS_TXT), VAR_ACCESS: os.R_OK}, EXTRA_ARGS: {VAR_TYPE: TYPE_FILE, VAR_SIGFILE: FN_EXTRA_ARGS_TXT, VAR_SFFT: ('', FN_EXTRA_ARGS_TXT), VAR_ACCESS: os.R_OK},
GCP_ORG_ID: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
GMAIL_CSE_INCERT_DIR: {VAR_TYPE: TYPE_DIRECTORY}, GMAIL_CSE_INCERT_DIR: {VAR_TYPE: TYPE_DIRECTORY},
GMAIL_CSE_INKEY_DIR: {VAR_TYPE: TYPE_DIRECTORY}, GMAIL_CSE_INKEY_DIR: {VAR_TYPE: TYPE_DIRECTORY},
INPUT_DIR: {VAR_TYPE: TYPE_DIRECTORY}, INPUT_DIR: {VAR_TYPE: TYPE_DIRECTORY},

View File

@@ -830,7 +830,6 @@ class GamCLArgs():
ARG_CSEKEYPAIRS = 'csekeypairs' ARG_CSEKEYPAIRS = 'csekeypairs'
ARG_CURRENTPROJECTID = 'currentprojectid' ARG_CURRENTPROJECTID = 'currentprojectid'
ARG_CUSTOMER = 'customer' ARG_CUSTOMER = 'customer'
ARG_CUSTOMERID = 'customerid'
ARG_DATASTUDIOASSET = 'datastudioasset' ARG_DATASTUDIOASSET = 'datastudioasset'
ARG_DATASTUDIOASSETS = 'datastudioassets' ARG_DATASTUDIOASSETS = 'datastudioassets'
ARG_DATASTUDIOPERMISSION = 'datastudiopermission' ARG_DATASTUDIOPERMISSION = 'datastudiopermission'
@@ -914,7 +913,6 @@ class GamCLArgs():
ARG_FORWARDINGADDRESS = 'forwardingaddress' ARG_FORWARDINGADDRESS = 'forwardingaddress'
ARG_FORWARDINGADDRESSES = 'forwardingaddresses' ARG_FORWARDINGADDRESSES = 'forwardingaddresses'
ARG_GCPFOLDER = 'gcpfolder' ARG_GCPFOLDER = 'gcpfolder'
ARG_GCPORGID = 'gcporgid'
ARG_GCPSERVICEACCOUNT = 'gcpserviceaccount' ARG_GCPSERVICEACCOUNT = 'gcpserviceaccount'
ARG_GMAIL = 'gmail' ARG_GMAIL = 'gmail'
ARG_GMAILPROFILE = 'gmailprofile' ARG_GMAILPROFILE = 'gmailprofile'

View File

@@ -242,7 +242,6 @@ class GamEntity():
FORWARDING_ADDRESS = 'fwda' FORWARDING_ADDRESS = 'fwda'
GCP_FOLDER = 'gcpf' GCP_FOLDER = 'gcpf'
GCP_FOLDER_NAME = 'gcpn' GCP_FOLDER_NAME = 'gcpn'
GCP_ORG_ID = 'gcpo'
GMAIL_PROFILE = 'gmpr' GMAIL_PROFILE = 'gmpr'
GROUP = 'grou' GROUP = 'grou'
GROUP_ALIAS = 'gali' GROUP_ALIAS = 'gali'
@@ -614,7 +613,6 @@ class GamEntity():
FORWARDING_ADDRESS: ['Forwarding Addresses', 'Forwarding Address'], FORWARDING_ADDRESS: ['Forwarding Addresses', 'Forwarding Address'],
GCP_FOLDER: ['GCP Folders', 'GCP Folder'], GCP_FOLDER: ['GCP Folders', 'GCP Folder'],
GCP_FOLDER_NAME: ['GCP Folder Names', 'GCP Folder Name'], GCP_FOLDER_NAME: ['GCP Folder Names', 'GCP Folder Name'],
GCP_ORG_ID: ['GCP Organization ID', 'GCP Organization ID'],
GMAIL_PROFILE: ['Gmail Profile', 'Gmail Profile'], GMAIL_PROFILE: ['Gmail Profile', 'Gmail Profile'],
GROUP: ['Groups', 'Group'], GROUP: ['Groups', 'Group'],
GROUP_ALIAS: ['Group Aliases', 'Group Alias'], GROUP_ALIAS: ['Group Aliases', 'Group Alias'],

View File

@@ -257,10 +257,10 @@ DRIVE3_UPDATE_ACL_THROW_REASONS = [BAD_REQUEST, INVALID_OWNERSHIP_TRANSFER, CANN
CANNOT_UPDATE_PERMISSION, CANNOT_UPDATE_PERMISSION,
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION, CANNOT_MODIFY_INHERITED_PERMISSION, CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION, CANNOT_MODIFY_INHERITED_PERMISSION,
FIELD_NOT_WRITABLE, PERMISSION_NOT_FOUND] FIELD_NOT_WRITABLE, PERMISSION_NOT_FOUND]
DRIVE3_DELETE_ACL_THROW_REASONS = [BAD_REQUEST, NOT_FOUND, PERMISSION_NOT_FOUND, CANNOT_REMOVE_OWNER, DRIVE3_DELETE_ACL_THROW_REASONS = [BAD_REQUEST, CANNOT_REMOVE_OWNER,
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION, CANNOT_MODIFY_INHERITED_PERMISSION, CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION, CANNOT_MODIFY_INHERITED_PERMISSION,
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED, INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED,
CANNOT_DELETE_PERMISSION, FILE_NEVER_WRITABLE] NOT_FOUND, PERMISSION_NOT_FOUND, CANNOT_DELETE_PERMISSION]
DRIVE3_MODIFY_LABEL_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, NOT_FOUND, FORBIDDEN, INTERNAL_ERROR, DRIVE3_MODIFY_LABEL_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, NOT_FOUND, FORBIDDEN, INTERNAL_ERROR,
FILE_NEVER_WRITABLE, APPLY_LABEL_FORBIDDEN, FILE_NEVER_WRITABLE, APPLY_LABEL_FORBIDDEN,
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, INSUFFICIENT_FILE_PERMISSIONS, INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, INSUFFICIENT_FILE_PERMISSIONS,

View File

@@ -129,8 +129,6 @@ GAM_CFG_SECTION_NAME = 'gcsn'
GAM_PATH = 'gpth' GAM_PATH = 'gpth'
# Python source, PyInstaller or StaticX? # Python source, PyInstaller or StaticX?
GAM_TYPE = 'gtyp' GAM_TYPE = 'gtyp'
# Shared Service Account HTTP Object
HTTP_OBJECT = 'http'
# Length of last Got message # Length of last Got message
LAST_GOT_MSG_LEN = 'lgml' LAST_GOT_MSG_LEN = 'lgml'
# License SKUs # License SKUs
@@ -252,7 +250,7 @@ Globals = {
CSV_OUTPUT_HEADER_FILTER: [], CSV_OUTPUT_HEADER_FILTER: [],
CSV_OUTPUT_HEADER_FORCE: [], CSV_OUTPUT_HEADER_FORCE: [],
CSV_OUTPUT_HEADER_ORDER: [], CSV_OUTPUT_HEADER_ORDER: [],
CSV_OUTPUT_HEADER_REQUIRED: [], # CSV_OUTPUT_HEADER_REQUIRED: [],
CSV_OUTPUT_NO_ESCAPE_CHAR: None, CSV_OUTPUT_NO_ESCAPE_CHAR: None,
CSV_OUTPUT_QUOTE_CHAR: None, CSV_OUTPUT_QUOTE_CHAR: None,
CSV_OUTPUT_ROW_DROP_FILTER: [], CSV_OUTPUT_ROW_DROP_FILTER: [],
@@ -284,7 +282,6 @@ Globals = {
GAM_CFG_SECTION_NAME: '', GAM_CFG_SECTION_NAME: '',
GAM_PATH: '.', GAM_PATH: '.',
GAM_TYPE: '', GAM_TYPE: '',
HTTP_OBJECT: None,
LAST_GOT_MSG_LEN: 0, LAST_GOT_MSG_LEN: 0,
LICENSE_SKUS: [], LICENSE_SKUS: [],
MAKE_BUILDING_ID_NAME_MAP: True, MAKE_BUILDING_ID_NAME_MAP: True,

View File

@@ -534,7 +534,6 @@ UNKNOWN_API_OR_VERSION = 'Unknown Google API or version: ({0}), contact {1}'
UNRECOVERABLE_ERROR = 'Unrecoverable error' UNRECOVERABLE_ERROR = 'Unrecoverable error'
UPDATE_ATTENDEE_CHANGES = 'Update attendee changes' UPDATE_ATTENDEE_CHANGES = 'Update attendee changes'
UPDATE_GAM_TO_64BIT = "You're running a 32-bit version of GAM on a 64-bit version of Windows, upgrade to a windows-x86_64 version of GAM" UPDATE_GAM_TO_64BIT = "You're running a 32-bit version of GAM on a 64-bit version of Windows, upgrade to a windows-x86_64 version of GAM"
UPDATE_PRIMARY_EMAIL_PREVIEW = 'updateprimaryemail preview: {0}'
UPDATE_USER_PASSWORD_CHANGE_NOTIFY_MESSAGE = 'The account password for #givenname# #familyname#, #user# has been changed to: #password#\n' UPDATE_USER_PASSWORD_CHANGE_NOTIFY_MESSAGE = 'The account password for #givenname# #familyname#, #user# has been changed to: #password#\n'
UPDATE_USER_PASSWORD_CHANGE_NOTIFY_SUBJECT = 'Account #user# password has been changed' UPDATE_USER_PASSWORD_CHANGE_NOTIFY_SUBJECT = 'Account #user# password has been changed'
UPLOAD_CSV_FILE_INTERNAL_ERROR = 'Google reported "{0}" but the file was probably uploaded, check that it has {1} rows' UPLOAD_CSV_FILE_INTERNAL_ERROR = 'Google reported "{0}" but the file was probably uploaded, check that it has {1} rows'

View File

@@ -94,7 +94,7 @@ _SKUS = {
'1010430001': { '1010430001': {
'product': '101043', 'aliases': ['gwas', 'plusstorage'], 'displayName': 'Google Workspace Additional Storage'}, 'product': '101043', 'aliases': ['gwas', 'plusstorage'], 'displayName': 'Google Workspace Additional Storage'},
'1010470001': { '1010470001': {
'product': '101047', 'aliases': ['geminient', 'duetai'], 'displayName': 'Gemini Enterprise - Legacy'}, 'product': '101047', 'aliases': ['geminient', 'duetai'], 'displayName': 'Gemini Enterprise'},
'1010470002': { '1010470002': {
'product': '101047', 'aliases': ['gwlabs', 'workspacelabs'], 'displayName': 'Google Workspace Labs'}, 'product': '101047', 'aliases': ['gwlabs', 'workspacelabs'], 'displayName': 'Google Workspace Labs'},
'1010470003': { '1010470003': {
@@ -109,8 +109,6 @@ _SKUS = {
'product': '101047', 'aliases': ['aimeetingsandmessaging'], 'displayName': 'AI Meetings and Messaging'}, 'product': '101047', 'aliases': ['aimeetingsandmessaging'], 'displayName': 'AI Meetings and Messaging'},
'1010470008': { '1010470008': {
'product': '101047', 'aliases': ['geminiultra'], 'displayName': 'Google AI Ultra for Business'}, 'product': '101047', 'aliases': ['geminiultra'], 'displayName': 'Google AI Ultra for Business'},
'1010470009': {
'product': '101047', 'aliases': ['aiexpandedaccess'], 'displayName': 'AI Expanded Access'},
'1010490001': { '1010490001': {
'product': '101049', 'aliases': ['eeu'], 'displayName': 'Endpoint Education Upgrade'}, 'product': '101049', 'aliases': ['eeu'], 'displayName': 'Endpoint Education Upgrade'},
'1010500001': { '1010500001': {

View File

@@ -6,7 +6,7 @@
\deftab720 \deftab720
\pard\pardeftab720\sl276\slmult1\sa200\qc\partightenfactor0 \pard\pardeftab720\sl276\slmult1\sa200\qc\partightenfactor0
\f0\fs22 \cf0 Copyright 2026 Jay Lee\ \f0\fs22 \cf0 Copyright 2025 Jay Lee\
\pard\pardeftab720\sa200\qc\partightenfactor0 \pard\pardeftab720\sa200\qc\partightenfactor0
\f1\b \cf0 Licensed under the Apache License, Version 2.0 (the "License");\ \f1\b \cf0 Licensed under the Apache License, Version 2.0 (the "License");\

View File

@@ -1,115 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|ARM">
<Configuration>PGInstrument</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|ARM64">
<Configuration>PGInstrument</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|Win32">
<Configuration>PGInstrument</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|x64">
<Configuration>PGInstrument</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|ARM">
<Configuration>PGUpdate</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|ARM64">
<Configuration>PGUpdate</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|Win32">
<Configuration>PGUpdate</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|x64">
<Configuration>PGUpdate</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{447F05A8-F581-4CAC-A466-5AC7936E207E}</ProjectGuid>
<RootNamespace>_hashlib</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="python.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup>
<TargetExt>$(PyStdlibPydExt)</TargetExt>
</PropertyGroup>
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="pyproject.props" />
<Import Project="openssl.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
</PropertyGroup>
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies>ws2_32.lib;crypt32.lib;advapi32.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\Modules\_hashopenssl.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\python_nt.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="pythoncore.vcxproj">
<Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -15,14 +15,12 @@
<_DLLSuffix Condition="$(Platform) == 'ARM64'">$(_DLLSuffix)-arm64</_DLLSuffix> <_DLLSuffix Condition="$(Platform) == 'ARM64'">$(_DLLSuffix)-arm64</_DLLSuffix>
<_DLLSuffix Condition="$(Platform) == 'x64'">$(_DLLSuffix)-x64</_DLLSuffix> <_DLLSuffix Condition="$(Platform) == 'x64'">$(_DLLSuffix)-x64</_DLLSuffix>
</PropertyGroup> </PropertyGroup>
<!-- GAM Static Build: Disable missing DLL/PDB copy
<ItemGroup> <ItemGroup>
<_SSLDLL Include="$(opensslOutDir)\libcrypto$(_DLLSuffix).dll" /> <_SSLDLL Include="$(opensslOutDir)\libcrypto$(_DLLSuffix).dll" />
<_SSLDLL Include="$(opensslOutDir)\libcrypto$(_DLLSuffix).pdb" /> <_SSLDLL Include="$(opensslOutDir)\libcrypto$(_DLLSuffix).pdb" />
<_SSLDLL Include="$(opensslOutDir)\libssl$(_DLLSuffix).dll" /> <_SSLDLL Include="$(opensslOutDir)\libssl$(_DLLSuffix).dll" />
<_SSLDLL Include="$(opensslOutDir)\libssl$(_DLLSuffix).pdb" /> <_SSLDLL Include="$(opensslOutDir)\libssl$(_DLLSuffix).pdb" />
</ItemGroup> </ItemGroup>
-->
<Target Name="_CopySSLDLL" Inputs="@(_SSLDLL)" Outputs="@(_SSLDLL->'$(OutDir)%(Filename)%(Extension)')" AfterTargets="Build"> <Target Name="_CopySSLDLL" Inputs="@(_SSLDLL)" Outputs="@(_SSLDLL->'$(OutDir)%(Filename)%(Extension)')" AfterTargets="Build">
<Copy SourceFiles="@(_SSLDLL)" DestinationFolder="$(OutDir)" /> <Copy SourceFiles="@(_SSLDLL)" DestinationFolder="$(OutDir)" />
</Target> </Target>

View File

@@ -1,147 +1,128 @@
// Node.js script to launch Simply Sign Desktop app and log a user in // Node.js script that implements an Appium client which will launch
// using native Windows keystrokes and screenshot-desktop for reliable CI imaging. // Simply Sign Desktop app and log a user in. Once logged in it should
// be possible to use tools like signtool.exe to sign Windows EXE/MSI files
// with the Certum certificate.
import { execSync, spawn } from 'child_process'; import { Key, remote } from 'webdriverio';
import { exec } from 'child_process';
import { TOTP } from 'totp-generator'; import { TOTP } from 'totp-generator';
import path from 'path';
import fs from 'fs'; async function screenshot(driver, filename) {
// uncomment to save .png screenshots
await driver.saveScreenshot(filename);
return
}
function sleep(ms) { function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms)); return new Promise(resolve => setTimeout(resolve, ms));
} }
// Native PowerShell Keystroke Sender async function executeCommand(command) {
function sendKeys(keys) {
const script = `$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('${keys}')`;
execSync(`powershell -Command "${script}"`);
}
// Native PowerShell Desktop Clear
function minimizeAllWindows() {
console.log('Minimizing all rogue background windows...');
const script = `$shell = New-Object -ComObject "Shell.Application"; $shell.MinimizeAll()`;
try { try {
execSync(`powershell -Command "${script}"`); let { stdout, stderr } = await exec(command);
} catch (err) { return stdout;
console.log('Minimize command failed silently.'); } catch (error) {
console.error(`Error executing command: ${command}`);
console.error(`Error details: ${error}`);
throw error;
} }
} }
async function takeScreenshot(filename) {
const workspace = process.env.GITHUB_WORKSPACE || process.cwd();
const fullPath = path.join(workspace, filename);
const psScript = `
Add-Type -AssemblyName System.Windows.Forms;
Add-Type -AssemblyName System.Drawing;
$Screen = [System.Windows.Forms.SystemInformation]::VirtualScreen;
if ($Screen.Width -eq 0 -or $Screen.Height -eq 0) {
Write-Error "Screen dimensions are 0x0. Desktop not fully initialized.";
exit 1;
}
$bitmap = New-Object System.Drawing.Bitmap $Screen.Width, $Screen.Height;
$graphic = [System.Drawing.Graphics]::FromImage($bitmap);
$graphic.CopyFromScreen($Screen.Left, $Screen.Top, 0, 0, $bitmap.Size);
$bitmap.Save('${fullPath}');
`;
try {
execSync(`powershell -Command "${psScript}"`);
console.log(`Saved screenshot: ${fullPath}`);
} catch (err) {
console.error(`Failed to save screenshot ${fullPath}:`, err.message);
}
}
// Fire and forget application launcher
function launchSSD() {
const child = spawn('C:\\Program Files\\Certum\\SimplySign Desktop\\SimplySignDesktop.exe', [], {
detached: true,
stdio: 'ignore'
});
child.unref();
}
async function runSSD() { async function runSSD() {
await takeScreenshot('001.png'); const opts = {
minimizeAllWindows(); port: 4723,
await sleep(2000); logLevel: "silent",
await takeScreenshot('002.png'); capabilities: {
sendKeys('{ESC}'); platformName: "Windows",
await sleep(2000); "appium:app": "C:\\Program Files\\Certum\\SimplySign Desktop\\SimplySignDesktop.exe",
await takeScreenshot('003.png'); "appium:automationName": "Windows",
//sendKeys('{ESC}'); },
//await sleep(2000); };
//await takeScreenshot('004.png');
//sendKeys('{ESC}');
//await sleep(2000);
//await takeScreenshot('005.png');
//sendKeys('%{F4}');
//await sleep(2000);
//await takeScreenshot('006.png');
//sendKeys('%{F4}');
//await sleep(2000);
//await takeScreenshot('007.png');
// Re-execute SSD to open login dialog let driver;
launchSSD();
await sleep(3000);
await takeScreenshot('008.png');
launchSSD();
await sleep(3000);
await takeScreenshot('009.png');
// 2. Login Flow
console.log('Typing credentials...');
// Type Email
sendKeys('jay0lee@gmail.com');
await sleep(500);
await takeScreenshot('010.png');
// Tab to next field
sendKeys('{TAB}');
await sleep(500);
// Generate and type TOTP
console.log(`Our secret is ${process.env.TOTP_SECRET.length} characters.`);
const { otp } = await TOTP.generate(process.env.TOTP_SECRET, {algorithm: 'SHA-256'});
console.log(`Our token is ${otp.length} characters.`);
sendKeys(otp);
await sleep(500);
await takeScreenshot('011.png');
// Submit
sendKeys('{ENTER}');
console.log('Login sequence complete.');
// Screenshot cascade to monitor the window closing
await takeScreenshot('012.png');
await sleep(500);
await takeScreenshot('013.png');
await sleep(500);
await takeScreenshot('014.png');
await sleep(500);
console.log('Exiting script, leaving SimplySign running in background.');
// Verification block to list all PNGs in the workspace
console.log('\n--- Screenshot Verification ---');
const workspace = process.env.GITHUB_WORKSPACE || process.cwd();
try { try {
const files = fs.readdirSync(workspace); driver = await remote(opts);
const pngFiles = files.filter(f => f.endsWith('.png'));
console.log(`Target Directory: ${workspace}`); // Github Actions Win ARM64 is stuck on a OOB screen that steals focus
console.log(`Found ${pngFiles.length} .png files:`); // These enter / escapes should dismiss it.
pngFiles.forEach(f => console.log(` - ${f}`)); const runner_arch = process.env.RUNNER_ARCH;
} catch (err) { if ( runner_arch === "ARM64" ) {
console.error(`Error reading directory ${workspace}:`, err.message); console.log('Running on ARM64...');
await sleep(3000); // Pause execution for 3 seconds
await screenshot(driver, 'oob1.png');
await driver.sendKeys([Key.Enter]);
await sleep(3000); // Pause execution for 3 seconds
await screenshot(driver, 'oob2.png');
await driver.sendKeys([Key.Enter]);
await sleep(3000); // Pause execution for 3 seconds
await screenshot(driver, 'oob3.png');
await driver.sendKeys([Key.Escape]);
await screenshot(driver, 'oob6.png');
} else {
console.log('NOT running on ARM64');
} }
console.log('-------------------------------\n');
// Execute SSD again to open login dialog
exec('"C:\\Program Files\\Certum\\SimplySign Desktop\\SimplySignDesktop.exe"', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
});
await sleep(3000);
// Login
const windows = await driver.getWindowHandles();
const login_window = windows[0]
await driver.switchWindow(login_window);
await screenshot(driver, 'login01.png');
const id_value = 'jay0lee@gmail.com';
const id_arr = [...id_value];
await driver.sendKeys(id_arr);
await screenshot(driver, 'login02.png');
await driver.sendKeys([Key.Tab]);
console.log('Our secret is ' + process.env.TOTP_SECRET.length + ' characters.');
// We wait until the last possible second to generate
// our TOTP to ensure it's still valid.
const { otp } = await TOTP.generate(process.env.TOTP_SECRET, {algorithm: 'SHA-256'});
console.log('Our token is ' + otp.length + ' characters.');
const otp_arr = [...otp];
await driver.sendKeys(otp_arr);
await screenshot(driver, 'login03.png');
await driver.sendKeys([Key.Enter]);
// TODO: it's expected that on successful login the window
// will close and these screenshots will error out. Figure
// out how to handle that gracefully.
await screenshot(driver, 'login04.png');
await sleep(500);
await screenshot(driver, 'login05.png');
await sleep(500);
await screenshot(driver, 'login06.png');
await sleep(500);
await screenshot(driver, 'login07.png');
await sleep(500);
await screenshot(driver, 'login08.png');
await sleep(500);
await screenshot(driver, 'login09.png');
await sleep(500);
await screenshot(driver, 'login10.png');
await sleep(500);
await screenshot(driver, 'login11.png');
await sleep(500);
await screenshot(driver, 'login12.png');
} catch (error) {
console.error(error);
//console.error("Error during Appium run:");
}
// INTENTIONAL Keep driver open so tray icon for Certum doesn't close
// finally {
// if (driver) {
// await driver.deleteSession(); // Close the Appium session
// }
//}
} }
runSSD(); runSSD();

View File

@@ -22,13 +22,13 @@ gam oauth create
## Display Business Profile Accounts ## Display Business Profile Accounts
``` ```
gam <UserTyoeEntity> show businessprofileaccounts gam <UserItem> show businessprofileaccounts
[type locationgroup|organization|personal|usergroup] [type locationgroup|organization|personal|usergroup]
``` ```
Gam displays the information as an indented list of keys and values. Gam displays the information as an indented list of keys and values.
``` ```
gam <UserTyoeEntity> print businessprofileaccounts [todrive <ToDriveAttribute>*] gam <UserItem> print businessprofileaccounts [todrive <ToDriveAttribute>*]
[type locationgroup|organization|personal|usergroup] [type locationgroup|organization|personal|usergroup]
``` ```
Gam displays the information as columns of fields. Gam displays the information as columns of fields.

View File

@@ -14,9 +14,8 @@
There are seven values in `gam.cfg` that can be used to filter the output from `gam print` commands. There are seven values in `gam.cfg` that can be used to filter the output from `gam print` commands.
* `csv_output_header_filter` - A list of `<RegularExpressions>` used to select specific column headers to include * `csv_output_header_filter` - A list of `<RegularExpressions>` used to select specific column headers to include
* `csv_output_header_drop_filter` - A list of `<RegularExpressions>` used to select specific column headers to exclude * `csv_output_header_drop_filter` - A list of `<RegularExpressions>` used to select specific column headers to exclude
* `csv_output_header_force` - A list of `<Strings>` used to specify the exact column headers to include * `csv_output_header_force` - A list of <Strings> used to specify the exact column headers to include
* `csv_output_header_order` - A list of `<Strings>` used to specify the column header order; any headers in the file but not in the list will appear after the header* `csv_output_header_required` - A list of `<Strings>` used to specify column headers that are included even if the print command doesn't return them * `csv_output_header_order` - A list of <Strings> used to specify the column header order; any headers in the file but not in the list will appear after the headers in the list.
s in the list.
* `csv_output_row_filter` - A list or JSON dictionary used to include specific rows based on column values * `csv_output_row_filter` - A list or JSON dictionary used to include specific rows based on column values
* `csv_output_row_drop_filter` - A list or JSON dictionary used to exclude specific rows based on column values * `csv_output_row_drop_filter` - A list or JSON dictionary used to exclude specific rows based on column values
* `csv_output_row_limit` - A limit on the number of rows written * `csv_output_row_limit` - A limit on the number of rows written

View File

@@ -99,25 +99,14 @@ Typically, you will enclose the entire list in double quotes and quote each item
## Manage printers ## Manage printers
When creating a printer you must specify: `displayname`, `ou`, `uri` and `makeandmodel` or `driverless`. When creating a printer you must specify: `displayname`, `ou`, `uri` and `makeandmodel` or `driverless`.
``` ```
gam create printer <PrinterAttribute>+ [nodetails|returnidonly] gam create printer <PrinterAttribute>+ [nodetails]
gam update printer <PrinterID> <PrinterAttribute>+ [nodetails|returnidonly] gam update printer <PrinterID> <PrinterAttribute>+ [nodetails]
gam delete printer gam delete printer
<PrinterIDList>| <PrinterIDList>|
<FileSelector>| <FileSelector>|
<CSVFileSelector> <CSVFileSelector>
``` ```
By default, when a printer is created/updated, GAM outputs details of the printer. By default, when a printer is created/updated, GAM outputs details of the printer; the `nodetails` option suppresses this output.
* `nodetails` - Suppress the datails output.
* `returnidonly` - Display just the printer ID of the created printer as output
To retrieve the printer ID with `returnidonly`:
```
Linux/MacOS
printerId=$(gam create printer ... returnidonly)
Windows PowerShell
$printerId = & gam create printer ... returnidonly
```
The printer ID will only be valid when the return code of the command is 0; program accordingly.
## Display printers ## Display printers
Display information about a single printer. Display information about a single printer.

View File

@@ -1,11 +1,10 @@
# Cloud Identity Groups # Cloud Identity Groups
- [API documentation](#api-documentation) - [API documentation](#api-documentation)
- [Query documentation](#query-documentation) - [Query documentation](#query-documentation)
- [Python Regular Expressions](Python-Regular-Expressions) Match function and Search function - [Python Regular Expressions](Python-Regular-Expressions) Match function
- [Notes](#Notes) - [Notes](#Notes)
- [Definitions](#definitions) - [Definitions](#definitions)
- [Manage groups](#manage-groups) - [Manage groups](#manage-groups)
- [Update a group's primary email address](#update-a-groups-primary-email-address)
- [Display information about individual groups](#display-information-about-individual-groups) - [Display information about individual groups](#display-information-about-individual-groups)
- [Display information about multiple groups](#display-information-about-multiple-groups) - [Display information about multiple groups](#display-information-about-multiple-groups)
- [Display group counts](#display-group-counts) - [Display group counts](#display-group-counts)
@@ -240,7 +239,6 @@ gam create cigroup <EmailAddress>
[security|makesecuritygroup] [locked] [security|makesecuritygroup] [locked]
[dynamic <QueryDynamicGroup>] [dynamic <QueryDynamicGroup>]
gam update cigroup <GroupEntity> [copyfrom <GroupItem>] <GroupAttribute> gam update cigroup <GroupEntity> [copyfrom <GroupItem>] <GroupAttribute>
[updateprimaryemail <RESearchPattern> <RESubstitution> [preview]]
[security|makesecuritygroup| [security|makesecuritygroup|
dynamicsecurity|makedynamicsecuritygroup| dynamicsecurity|makedynamicsecuritygroup|
lockedsecurity|makelockedsecuritygroup] lockedsecurity|makelockedsecuritygroup]
@@ -261,22 +259,6 @@ You can update a group to restrict its membership with the `memberrestrictions <
The `makeowner` option makes the administrator in `oauth2.txt` the initial owner of the group. The `makeowner` option makes the administrator in `oauth2.txt` the initial owner of the group.
## Update a group's primary email address
You can simply update a group's primary email address with the `email` option.
```
gam update cigroup groupold@domain.com email groupnew@domain.com
```
The `updateprimaryemail <RESearchPattern> <RESubstitution> [preview]` option allows modification several group's
current primary email address. For example, to change the domain of a set of groups from the current domain.com to newdomain.com,
make a CSV file Groups.csv with a column `email` that contains the group email addresses that are to be changed.
You can list all groups with: `gam redirect csv ./Groups.csv print cigroups`
```
gam update cigroup csvfile Groups.csv:email updateprimaryemail "^(.+)@domain.com$" "\1@newdomain.com"
```
The `preview` option allows verification of the primary email address changes before commiting the changes.
If the group's current primary email address does not match the <REMatchPattern> then no modification is made.
## Display information about individual groups ## Display information about individual groups
This command displays information as an indented list of keys and values. This command displays information as an indented list of keys and values.
``` ```

View File

@@ -12,13 +12,13 @@
## Notes ## Notes
To use these commands you must update your client access authentication. To use these commands you must update your client access authentication.
You'll enter 23 or 23r to turn on the Cloud Identity Policy scope; then continue You'll enter 20r to turn on the Cloud Identity Policy scope; then continue
with authentication. with authentication.
``` ```
gam oauth delete gam oauth delete
gam oauth create gam oauth create
... ...
[R] 23) Cloud Identity - Policy (supports readonly) [R] 20) Cloud Identity - Policy (supports readonly)
``` ```
You must enable access to policies in the GCP cloud console. You must enable access to policies in the GCP cloud console.
@@ -58,7 +58,7 @@ See: https://cloud.google.com/identity/docs/concepts/supported-policy-api-settin
Display selected policies. Display selected policies.
``` ```
gam info policies <CIPolicyEntity> gam info policies <CIPolicyEntity>
[nowarnings] [noappnames] [noidmappimg] [nowarnings] [noappnames]
[formatjson] [formatjson]
``` ```
@@ -67,22 +67,18 @@ Select policies::
* `settings/<String>` - A policy setting type, `settings/workspace_marketplace.apps_allowlist` * `settings/<String>` - A policy setting type, `settings/workspace_marketplace.apps_allowlist`
* `<String>` - A policy setting type, `workspace_marketplace.apps_allowlist` * `<String>` - A policy setting type, `workspace_marketplace.apps_allowlist`
By default, policy warnings are displayed, use the `nowarnings` option to suppress their display. By default, policy warnings are displayed, use the 'nowarnings` option to suppress their display.
By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist` By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist`
to get the application name for the application ID. Use option `noappnames` to suppress these calls. to get the application name for the application ID. Use option `noappnames` to suppress these calls.
By default, additional API calls are made to add the `policyQuery/groupEmail` and `policyQuery/orgUnitPath` fields
that are mapped from the `policyQuery/group` and `policyQuery/orgUnit` fields. Use option `noidmapping'
to suppress these calls and not add the additional fields.
By default, Gam displays the information as an indented list of keys and values. By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format. * `formatjson` - Display the fields in JSON format.
Display all or filtered policies. Display all or filtered policies.
``` ```
gam show policies gam show policies
[filter <String>] [nowarnings] [noappnames] [noidmappimg] [filter <String>] [nowarnings] [noappnames]
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>] [group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
[formatjson] [formatjson]
``` ```
@@ -96,16 +92,12 @@ By default, policy warnings are displayed, use the `nowarnings` option to suppre
By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist` By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist`
to get the application name for the application ID. Use option `noappnames` to suppress these calls. to get the application name for the application ID. Use option `noappnames` to suppress these calls.
By default, additional API calls are made to add the `policyQuery/groupEmail` and `policyQuery/orgUnitPath` fields
that are mapped from the `policyQuery/group` and `policyQuery/orgUnit` fields. Use option `noidmapping'
to suppress these calls and not add the additional fields.
By default, Gam displays the information as an indented list of keys and values. By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format. * `formatjson` - Display the fields in JSON format.
``` ```
gam print policies [todrive <ToDriveAttribute>*] gam print policies [todrive <ToDriveAttribute>*]
[filter <String>] [nowarnings] [noappnames] [noidmappimg] [filter <String>] [nowarnings] [noappnames]
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>] [group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
[formatjson [quotechar <Character>]] [formatjson [quotechar <Character>]]
``` ```
@@ -116,10 +108,6 @@ By default, all policies are displayed:
By default, policy warnings are displayed, use the `nowarnings` option to suppress their display. By default, policy warnings are displayed, use the `nowarnings` option to suppress their display.
By default, additional API calls are made to add the `policyQuery/groupEmail` and `policyQuery/orgUnitPath` fields
that are mapped from the `policyQuery/group` and `policyQuery/orgUnit` fields. Use option `noidmapping'
to suppress these calls and not add the additional fields.
By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist` By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist`
to get the application name for the application ID. Use option `noappnames` to suppress these calls. to get the application name for the application ID. Use option `noappnames` to suppress these calls.
@@ -138,11 +126,6 @@ Print all service status policies.
gam redirect csv ./ServiceStatusPolicies.csv print policies filter "setting.type.matches('.*service_status')" gam redirect csv ./ServiceStatusPolicies.csv print policies filter "setting.type.matches('.*service_status')"
``` ```
Print Drive external sharing policies.
```
gam redirect csv ./DriveExternalSharingPolicies.csv print policies filter "setting.type.matches('settings/drive_and_docs.external_sharing')"
```
Print all polices that apply directly to the OU "/Staff". Print all polices that apply directly to the OU "/Staff".
``` ```
gam redirect csv ./StaffPolicies.csv print policies ou "^/Staff$" gam redirect csv ./StaffPolicies.csv print policies ou "^/Staff$"

View File

@@ -319,8 +319,6 @@ Data fields identified in a `csvkmd` argument.
(select <ProjectIDList> | <FileSelector> | <CSVFileSelector>) (select <ProjectIDList> | <FileSelector> | <CSVFileSelector>)
<PrinterIDEntity> ::= <PrinterIDEntity> ::=
<PrinterIDList> | <FileSelector> | <CSVFileSelector> <PrinterIDList> | <FileSelector> | <CSVFileSelector>
<QueryDriveFile> :: = <String> See: https://developers.google.com/workspace/drive/api/guides/search-files
<QuerySharedDrive> ::= <String> See: https://developers.google.com/workspace/drive/api/guides/search-shareddrives
<RecipientEntity> ::= <RecipientEntity> ::=
<EmailAddressEntity> | (select <UserTypeEntity>) <EmailAddressEntity> | (select <UserTypeEntity>)
<ResourceEntity> ::= <ResourceEntity> ::=
@@ -331,22 +329,22 @@ Data fields identified in a `csvkmd` argument.
<SerialNumberList> | <FileSelector> | <CSVFileSelector> <SerialNumberList> | <FileSelector> | <CSVFileSelector>
<SharedDriveIDEntity> ::= <SharedDriveIDEntity> ::=
<DriveFileItem> | <DriveFileItem> |
(shareddriveid <DriveFileItem>) | (shareddriveid:<DriveFileItem>) (teamdriveid <DriveFileItem>) | (teamdriveid:<DriveFileItem>)
<SharedDriveNameEntity> ::= <SharedDriveNameEntity> ::=
(shareddrive <SharedDriveName>) | (shareddrive:<SharedDriveName>) (teamdrive <SharedDriveName>) | (teamdrive:<SharedDriveName>)
<SharedDriveEntity> ::= <SharedDriveEntity> ::=
<SharedDriveIDEntity> | <SharedDriveIDEntity> |
<SharedDriveNameEntity> <SharedDriveNameEntity>
<SharedDriveAdminQueryEntity> ::= <SharedDriveAdminQueryEntity> ::=
(shareddriveadminquery <QuerySharedDrive>) | (shareddriveadminquery:<QuerySharedDrive>) (teamdriveadminquery <QueryTeamDrive>) | (teamdriveadminquery:<QueryTeamDrive>)
<SharedDriveEntityAdmin> ::= <SharedDriveEntityAdmin> ::=
<SharedDriveIDEntity> | <SharedDriveIDEntity> |
<SharedDriveNameEntity>| <SharedDriveNameEntity>|
<SharedDriveAdminQueryEntity> <SharedDriveAdminQueryEntity>
<SharedDriveFileNameEntity> ::= <SharedDriveFileNameEntity> ::=
(shareddrivefilename <DriveFileName>) | (shareddrivefilename:<DriveFileName>) (teamdrivefilename <DriveFileName>) | (teamdrivefilename:<DriveFileName>)
<SharedDriveFileQueryEntity> ::= <SharedDriveFileQueryEntity> ::=
(shareddrivequery <QueryDriveFile>) | (shareddrivequery:<QueryDriveFile>) (teamdrivequery <QueryDriveFile>) | (teamdrivequery:<QueryDriveFile>)
<SharedDriveFileQueryShortcut> ::= <SharedDriveFileQueryShortcut> ::=
all_files | all_folders | all_google_files | all_non_google_files | all_items all_files | all_folders | all_google_files | all_non_google_files | all_items
<SiteACLScopeEntity> ::= <SiteACLScopeEntity> ::=

View File

@@ -114,9 +114,9 @@ ous_and_children_na_ns
(anydrivefilename <DriveFileName>)|(anydrivefilename:<DriveFileName>) (anydrivefilename <DriveFileName>)|(anydrivefilename:<DriveFileName>)
<SharedDriveID> ::= <String> <SharedDriveID> ::= <String>
<SharedDriveName> ::= <String> <SharedDriveName> ::= <String>
<SharedDriveIDEntity> ::= (shareddriveid <DriveFileItem>) | (shareddriveid:<DriveFileItem>) <SharedDriveIDEntity> ::= (teamdriveid <DriveFileItem>) | (teamdriveid:<DriveFileItem>)
<SharedDriveNameEntity> ::= (shareddrive <SharedDriveName>) | (shareddrive:<SharedDriveName>) <SharedDriveNameEntity> ::= (teamdrive <SharedDriveName>) | (teamdrive:<SharedDriveName>)
<SharedDriveFileNameEntity> ::= (shareddrivefilename <DriveFileName>) | (shareddrivefilename:<DriveFileName>) <SharedDriveFileNameEntity> ::= (teamdrivefilename <DriveFileName>) | (teamdrivefilename:<DriveFileName>)
<SharedDriveEntity> ::= <SharedDriveEntity> ::=
<SharedDriveIDEntity> | <SharedDriveIDEntity> |
<SharedDriveNameEntity> <SharedDriveNameEntity>
@@ -327,7 +327,7 @@ Use these options to select users for GAM commands.
* `ou_arch` - Archived users * `ou_arch` - Archived users
* `ou_ns` - Non-suspended users * `ou_ns` - Non-suspended users
* `ou_susp` - Suspended users * `ou_susp` - Suspended users
* `ou_na_ns` - Non-archived and non-suspended users * `ou_na_ns` - Non-archived and nn-suspended users
## Users in the Organization Unit `<OrgUnitItem>` and all of its sub Organization Units ## Users in the Organization Unit `<OrgUnitItem>` and all of its sub Organization Units
* `ou_and_children|ou_and_children_na|ou_and_children_arch|ou_and_children_ns|ou_and_children_susp|ou_and_children_na_ns <OrgUnitItem>` * `ou_and_children|ou_and_children_na|ou_and_children_arch|ou_and_children_ns|ou_and_children_susp|ou_and_children_na_ns <OrgUnitItem>`
@@ -336,7 +336,7 @@ Use these options to select users for GAM commands.
* `ou_and_children_arch` - Archived users * `ou_and_children_arch` - Archived users
* `ou_and_children_ns` - Non-suspended users * `ou_and_children_ns` - Non-suspended users
* `ou_and_children_susp` - Suspended users * `ou_and_children_susp` - Suspended users
* `ou_and_children_na_ns` - Non-archived and non-suspended users * `ou_and_children_na_ns` - Non-archived and nn-suspended users
## Users directly in the Organization Units `<OrgUnitList>` ## Users directly in the Organization Units `<OrgUnitList>`
* `ous|ous_na|ous_arch|ous_ns|ous_susp|ous_na_ns <OrgUnitList>` - Users directly in the Organization Units `<OrgUnitList>` * `ous|ous_na|ous_arch|ous_ns|ous_susp|ous_na_ns <OrgUnitList>` - Users directly in the Organization Units `<OrgUnitList>`
@@ -345,7 +345,7 @@ Use these options to select users for GAM commands.
* `ous_arch` - Archived users * `ous_arch` - Archived users
* `ous_ns` - Non-suspended users * `ous_ns` - Non-suspended users
* `ous_susp` - Suspended users * `ous_susp` - Suspended users
* `ous_na_ns` - Non-archived and non-suspended users * `ous_na_ns` - Non-archived and nn-suspended users
`<OrgUnitList>` may require special quoting based on whether the OUs contain spaces, commas or single quotes. `<OrgUnitList>` may require special quoting based on whether the OUs contain spaces, commas or single quotes.

View File

@@ -3,7 +3,6 @@
- [Notes](#Notes) - [Notes](#Notes)
- [API documentation](#api-documentation) - [API documentation](#api-documentation)
- [Grant Service Account Rights to Manage CAA](#grant-service-account-rights-to-manage-caa) - [Grant Service Account Rights to Manage CAA](#grant-service-account-rights-to-manage-caa)
- [Get Google Cloud organization ID for your workspace](#Get Google Cloud organization ID for your workspace)
- [Definitions](#definitions) - [Definitions](#definitions)
- [Parameters for Basic Levels](#parameters-for-basic-levels) - [Parameters for Basic Levels](#parameters-for-basic-levels)
- [Create an Access Level](#create-an-access-level) - [Create an Access Level](#create-an-access-level)
@@ -37,15 +36,6 @@ In order for GAM to manage CAA access levels, you need to grant your service acc
10. Click `Save`. It may take 15 minutes or more for the role permissions to propagate. 10. Click `Save`. It may take 15 minutes or more for the role permissions to propagate.
11. Confirm the role is in place by re-running `gam print caalevels` 11. Confirm the role is in place by re-running `gam print caalevels`
## Get Google Cloud organization ID for your workspace
This ID is used by the caalevel commands; to eliminate additional API calls,
you can get the value and store it in the `gam.cfg/gcp_org_id` variable.
```
$ gam info gcporgid
organizations/906207637890
$ gam config gcp_org_id organizations/906207637890 save
```
## Definitions ## Definitions
``` ```
<JSONData> ::= (json [charset <Charset>] <String>) | (json file <FileName> [charset <Charset>]) | <JSONData> ::= (json [charset <Charset>] <String>) | (json file <FileName> [charset <Charset>]) |

View File

@@ -4,8 +4,6 @@
- [Update customer](#update-customer) - [Update customer](#update-customer)
- [Display customer](#display-customer) - [Display customer](#display-customer)
- [Display instance](#display-instance) - [Display instance](#display-instance)
- [Display Customer ID](#display-customer-id)
- [Display GCP organization ID](#display-gcp-organization-id)
## API documentation ## API documentation
* [Directory API - Customers](https://developers.google.com/admin-sdk/directory/reference/rest/v1/customers) * [Directory API - Customers](https://developers.google.com/admin-sdk/directory/reference/rest/v1/customers)
@@ -47,19 +45,3 @@ gam info instance [formatjson]
``` ```
By default, Gam displays the information as an indented list of keys and values. By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format. * `formatjson` - Display the fields in JSON format.
## Display Customer ID
You can get and set the `gam.cfg/customer_id` value with these commands:
```
$ gam info customerid
C78abc9de
$ gam config customer_id C78abc9de save
```
## Display GCP organization ID
You can get and set the `gam.cfg/gcp_org_id` value with these commands:
```
$ gam info gcporgid
organizations/906207637890
$ gam config gcp_org_id organizations/906207637890 save
```

View File

@@ -25,41 +25,41 @@ start a new terminal session and reissue the command from above.
## Executable, Manual ## Executable, Manual
* Executable Archive, Manual, Linux/Google Cloud Shell * Executable Archive, Manual, Linux/Google Cloud Shell
- `gam-7.wx.yz-linux-x86_64-glibc2.35.tar.xz` - `gam-7.wx.yz-linux-x86_64-glibc2.36.tar.xz`
- `gam-7.wx.yz-linux-x86_64-glibc2.39.tar.xz` - `gam-7.wx.yz-linux-x86_64-glibc2.39.tar.xz`
- `gam-7.wx.yz-linux-x86_64-legacy.tar.xz` - `gam-7.wx.yz-linux-x86_64-legacy.tar.xz`
- Download the archive, extract the contents into some directory. - Download the archive, extract the contents into some directory.
- Start a terminal session. - Start a terminal session.
* Executable Archive, Manual, Raspberry Pi/ChromeOS ARM devices * Executable Archive, Manual, Raspberry Pi/ChromeOS ARM devices
- `gam-7.wx.yz-linux-arm64-glibc2.35.tar.xz` - `gam-7.wx.yz-linux-arm64-glibc2.36.tar.xz`
- `gam-7.wx.yz-linux-arm64-glibc2.39.tar.xz` - `gam-7.wx.yz-linux-arm64-glibc2.39.tar.xz`
- `gam-7.wx.yz-linux-arm64-legacy.tar.xz` - `gam-7.wx.yz-linux-arm64-legacy.tar.xz`
- Download the archive, extract the contents into some directory. - Download the archive, extract the contents into some directory.
- Start a terminal session. - Start a terminal session.
* Executable Archive, Manual, Mac OS versions Sonoma, Sequoia - M1/M2 * Executable Archive, Manual, Mac OS versions Sonoma, Sequoia - M1/M2
- `gam-7.wx.yz-macos14.8-arm64.tar.xz` - `gam-7.wx.yz-macos14.7-arm64.tar.xz`
- Download the archive, extract the contents into some directory. - Download the archive, extract the contents into some directory.
- Start a terminal session. - Start a terminal session.
* Executable Archive, Manual, Mac OS versions Sequoia - M2/M3 * Executable Archive, Manual, Mac OS versions Sequoia - M2/M3
- `gam-7.wx.yz-macos15.7-arm64.tar.xz` - `gam-7.wx.yz-macos15.6-arm64.tar.xz`
- Download the archive, extract the contents into some directory.
- Start a terminal session.
* Executable Archive, Manual, Mac OS, versions Sequoia, Tahoe - Intel
- `gam-7.wx.yz-macos15.7-x86_64.tar.xz`
- Download the archive, extract the contents into some directory. - Download the archive, extract the contents into some directory.
- Start a terminal session. - Start a terminal session.
* Executable Archive, Manual, Mac OS versions Tahoe - M2/M3/M4 * Executable Archive, Manual, Mac OS versions Tahoe - M2/M3/M4
- `gam-7.wx.yz-macos26.3-arm64.tar.xz` - `gam-7.wx.yz-macos26.0-arm64.tar.xz`
- Download the archive, extract the contents into some directory. - Download the archive, extract the contents into some directory.
- Start a terminal session. - Start a terminal session.
* Executable Archive, Manual, Mac OS versions Tahoe - Intel * Executable Archive, Manual, Mac OS, versions Ventura, Sonoma - Intel
- `gam-7.wx.yz-macos26.3-x86_64.tar.xz` - `gam-7.wx.yz-macos13.7-x86_64.tar.xz`
- Download the archive, extract the contents into some directory.
- Start a terminal session.
* Executable Archive, Manual, Mac OS, versions Sequoia, Tahoe - Intel
- `gam-7.wx.yz-macos15.6-x86_64.tar.xz`
- Download the archive, extract the contents into some directory. - Download the archive, extract the contents into some directory.
- Start a terminal session. - Start a terminal session.
@@ -69,7 +69,7 @@ start a new terminal session and reissue the command from above.
- Start a Command Prompt/PowerShell session. - Start a Command Prompt/PowerShell session.
* Executable Installer, Manual, Windows 64 bit * Executable Installer, Manual, Windows 64 bit
- `gam-7.wx.yz-windows-x86_64.exe` - `gam-7.wx.yz-windows-x86_64.msi`
- Download the installer and run it. - Download the installer and run it.
- Start a Command Prompt/PowerShell session. - Start a Command Prompt/PowerShell session.
@@ -79,7 +79,7 @@ start a new terminal session and reissue the command from above.
- Start a Command Prompt/PowerShell session. - Start a Command Prompt/PowerShell session.
* Executable Installer, Manual, Windows 11 ARM * Executable Installer, Manual, Windows 11 ARM
- `gam-7.wx.yz-windows-arm64.exe` - `gam-7.wx.yz-windows-arm64.msi`
- Download the installer and run it. - Download the installer and run it.
- Start a Command Prompt/PowerShell session. - Start a Command Prompt/PowerShell session.

View File

@@ -49,8 +49,7 @@
<DriveFolderID> ::= <String> <DriveFolderID> ::= <String>
<DriveFolderIDList> ::= "<DriveFolderID>(,<DriveFolderID>)*" <DriveFolderIDList> ::= "<DriveFolderID>(,<DriveFolderID>)*"
<DriveFolderName> ::= <String> <DriveFolderName> ::= <String>
<QueryDriveFile> :: = <String> See: https://developers.google.com/workspace/drive/api/guides/search-files <QueryDriveFile> :: = <String> See: https://developers.google.com/drive/api/v3/search-files
<QuerySharedDrive> ::= <String> See: https://developers.google.com/workspace/drive/api/guides/search-shareddrives
<DriveFileQueryEntity> ::= <DriveFileQueryEntity> ::=
(query <QueryDriveFile>) | (query:<QueryDriveFile>) (query <QueryDriveFile>) | (query:<QueryDriveFile>)
<DriveFileQueryShortcut> ::= <DriveFileQueryShortcut> ::=
@@ -91,15 +90,15 @@
<SharedDriveID> ::= <String> <SharedDriveID> ::= <String>
<SharedDriveName> ::= <String> <SharedDriveName> ::= <String>
<SharedDriveIDEntity> ::= (shareddriveid <SharedDriveID>) | (shareddriveid:<SharedDriveID>) <SharedDriveIDEntity> ::= (teamdriveid <SharedDriveID>) | (teamdriveid:<SharedDriveID>)
<SharedDriveNameEntity> ::= (shareddrive <SharedDriveName>) | (shareddrive:<SharedDriveName>) <SharedDriveNameEntity> ::= (teamdrive <SharedDriveName>) | (teamdrive:<SharedDriveName>)
<SharedDriveFileNameEntity> ::= (shareddrivefilename <DriveFileName>) | (shareddrivefilename:<DriveFileName>) <SharedDriveFileNameEntity> ::= (teamdrivefilename <DriveFileName>) | (teamdrivefilename:<DriveFileName>)
<SharedDriveEntity> ::= <SharedDriveEntity> ::=
<SharedDriveIDEntity> | <SharedDriveIDEntity> |
<SharedDriveNameEntity> <SharedDriveNameEntity>
<SharedDriveAdminQueryEntity> ::= <SharedDriveAdminQueryEntity> ::=
(shareddriveadminquery <QuerySharedDrive>) | (shareddriveadminquery:<QuerySharedDrive>) (teamdriveadminquery <QueryTeamDrive>) | (teamdriveadminquery:<QueryTeamDrive>)
<SharedDriveFileQueryEntity> ::= <SharedDriveFileQueryEntity> ::=
(query <QueryDriveFile>) | (query:<QueryDriveFile>) (query <QueryDriveFile>) | (query:<QueryDriveFile>)
<SharedDriveFileQueryShortcut> ::= <SharedDriveFileQueryShortcut> ::=
@@ -336,13 +335,13 @@ Select a Shared Drive file by giving its unique ID.
``` ```
<SharedDriveIDEntity> ::= <SharedDriveIDEntity> ::=
<DriveFileItem> | <DriveFileItem> |
(shareddriveid <DriveFileItem>) | (shareddriveid:<DriveFileItem>) (teamdriveid <DriveFileItem>) | (teamdriveid:<DriveFileItem>)
``` ```
### Examples ### Examples
``` ```
gam user testuser show fileinfo 1234ABCD gam user testuser show fileinfo 1234ABCD
gam user testuser show fileinfo id 1234ABCD gam user testuser show fileinfo id 1234ABCD
gam user testuser show fileinfo shareddriveid 1234ABCD gam user testuser show fileinfo teamdriveid 1234ABCD
``` ```
## Select Shared Drive file by name ## Select Shared Drive file by name
If you have the name, a search must be performed to find the ID that matches the name. If you have the name, a search must be performed to find the ID that matches the name.
@@ -351,16 +350,16 @@ You must specify the Shared Drive, either by ID or name, and the name of the fil
Remember, searching for a file by name may return several file IDs if you have multiple files with the same name. Remember, searching for a file by name may return several file IDs if you have multiple files with the same name.
``` ```
<SharedDriveIDEntity> ::= <SharedDriveIDEntity> ::=
(shareddriveid <DriveFileItem>) | (shareddriveid:<DriveFileItem>) (teamdriveid <DriveFileItem>) | (teamdriveid:<DriveFileItem>)
<SharedDriveNameEntity> ::= <SharedDriveNameEntity> ::=
(shareddrive <SharedDriveName>) | (shareddrive:<SharedDriveName>) (teamdrive <SharedDriveName>) | (teamdrive:<SharedDriveName>)
<SharedDriveFileNameEntity> ::= <SharedDriveFileNameEntity> ::=
(shareddrivefilename <DriveFileName>) | (shareddrivefilename:<DriveFileName>) (teamdrivefilename <DriveFileName>) | (teamdrivefilename:<DriveFileName>)
``` ```
### Examples ### Examples
``` ```
gam user testuser show fileinfo shareddriveid 1234ABCD shareddrivefilename "Test File" gam user testuser show fileinfo teamdriveid 1234ABCD teamdrivefilename "Test File"
gam user testuser show fileinfo shareddrive "Shared Drive 1" shareddrivefilename "Test File" gam user testuser show fileinfo teamdrive "Shared Drive 1" teamdrivefilename "Test File"
``` ```
## Select Shared Drive file by query ## Select Shared Drive file by query
You can use a query to find a file ID. You perform the query on all Shared Drives or a specific Shared Drive. You can use a query to find a file ID. You perform the query on all Shared Drives or a specific Shared Drive.
@@ -368,7 +367,7 @@ You can use a query to find a file ID. You perform the query on all Shared Drive
See: [Drive Query](https://developers.google.com/drive/api/v3/search-files) See: [Drive Query](https://developers.google.com/drive/api/v3/search-files)
``` ```
<SharedDriveFileQueryEntity> ::= <SharedDriveFileQueryEntity> ::=
(shareddrivequery <QueryDriveFile>) | (shareddrivequery:<QueryDriveFile>) (teamdrivequery <QueryDriveFile>) | (teamdrivequery:<QueryDriveFile>)
<SharedDriveFileQueryShortcut> ::= <SharedDriveFileQueryShortcut> ::=
all_files | all_folders | all_google_files | all_non_google_files | all_items all_files | all_folders | all_google_files | all_non_google_files | all_items
``` ```
@@ -381,32 +380,32 @@ Keyword to query mappings for `<DriveFileQueryShortcut>`:
### Examples ### Examples
``` ```
gam user testuser show fileinfo shareddrivequery "name='Test File'" gam user testuser show fileinfo teamdrivequery "name='Test File'"
gam user testuser show fileinfo shareddriveid 1234ABCD shareddrivequery "name='Test File'" gam user testuser show fileinfo teamdriveid 1234ABCD teamdrivequery "name='Test File'"
gam user testuser show fileinfo shareddrive shareddrive "Shared Drive 1" shareddrivequery "name='Test File'" gam user testuser show fileinfo teamdrive teamdrive "Shared Drive 1" teamdrivequery "name='Test File'"
gam user testuser show fileinfo shareddriveid 1234ABCD all_non_google_files gam user testuser show fileinfo teamdriveid 1234ABCD all_non_google_files
``` ```
## Select root folder of a Shared Drive by ID ## Select root folder of a Shared Drive by ID
The root folder of a Shared Drive is a folder, you select it by giving its unique ID. The root folder of a Shared Drive is a folder, you select it by giving its unique ID.
``` ```
<SharedDriveIDEntity> ::= <SharedDriveIDEntity> ::=
<DriveFileItem> | <DriveFileItem> |
(shareddriveid <DriveFileItem>) | (shareddriveid:<DriveFileItem>) (teamdriveid <DriveFileItem>) | (teamdriveid:<DriveFileItem>)
``` ```
### Examples ### Examples
``` ```
gam user testuser show fileinfo 1234ABCD gam user testuser show fileinfo 1234ABCD
gam user testuser show fileinfo shareddriveid 1234ABCD gam user testuser show fileinfo teamdriveid 1234ABCD
``` ```
## Select root folder of a Shared Drive by name ## Select root folder of a Shared Drive by name
If you have a Shared Drive name, a search must be performed to find the ID that matches the name. If you have a Shared Drive name, a search must be performed to find the ID that matches the name.
``` ```
<SharedDriveNameEntity> ::= <SharedDriveNameEntity> ::=
(shareddrive <SharedDriveName>) | (shareddrive:<SharedDriveName>) (teamdrive <SharedDriveName>) | (teamdrive:<SharedDriveName>)
``` ```
### Examples ### Examples
``` ```
gam user testuser show fileinfo shareddrive "Shared Drive 1" gam user testuser show fileinfo teamdrive "Shared Drive 1"
``` ```

View File

@@ -27,13 +27,13 @@
(anydrivefilename <DriveFileName>) | (anydrivefilename:<DriveFileName>) (anydrivefilename <DriveFileName>) | (anydrivefilename:<DriveFileName>)
<SharedDriveIDEntity> ::= <SharedDriveIDEntity> ::=
<DriveFileItem> | <DriveFileItem> |
(shareddriveid <DriveFileItem>) | (shareddriveid:<DriveFileItem>) (teamdriveid <DriveFileItem>) | (teamdriveid:<DriveFileItem>)
<SharedDriveName> ::= <String> <SharedDriveName> ::= <String>
<SharedDriveNameEntity> ::= <SharedDriveNameEntity> ::=
(shareddrive <SharedDriveName>) | (shareddrive:<SharedDriveName>) (teamdrive <SharedDriveName>) | (teamdrive:<SharedDriveName>)
<SharedDriveEntity> ::= <SharedDriveEntity> ::=
<SharedDriveIDEntity> | <SharedDriveIDEntity> |
<SharedDriveNameEntity> <SharedDriveNameEntity>
<SharedDriveFileNameEntity> ::= <SharedDriveFileNameEntity> ::=
(shareddrivefilename <DriveFileName>) | (shareddrivefilename:<DriveFileName>) (teamdrivefilename <DriveFileName>) | (teamdrivefilename:<DriveFileName>)
``` ```

View File

@@ -10,383 +10,6 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation
### 7.39.08
Fixed bug in `gam oauth create` that caused a trap when `0) Business Account Management API` was selected.
Upgraded to Python 3.14.4 on macOS and Windows; Linux is still 3.14.3.
### 7.39.07
Upgraded to OpenSSL 3.6.2.
### 7.39.06
Fixed bug in `gam version checkrc`.
### 7.39.05
Added optional argument `preview` to `updateprimaryemail <RegularExpression> <EmailReplacement> [preview]`
for the following commands that causes GAM to preview, but not perform, primary email address changes.
This allows verification of the primary email address changes before commiting the changes.
```
gam update group <GroupEntity>
gam update cigroup <GroupEntity>
gam <UserTypeEntity> update user
```
### 7.39.04
Added `updateprimaryemail <RegularExpression> <EmailReplacement>` option to
`gam update group <GroupEntity>` and `gam update cigroup <GroupEntity>` to allow modifying
the group's current primary email address.
For example, to change the domain of a set of groups from the current domain.com to newdomain.com:
```
gam update group csvfile Groups.csv:email updateprimaryemail "^(.+)@domain.com$" "\1@newdomain.com"
```
### 7.39.03
Added the following options to `gam <UserTypeEntity> create chatspace` that can be used to capture
space details when creating chat spaces in bulk.
```
csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]] (addcsvdata <FieldName> <String>)*
```
See: https://github.com/GAM-team/GAM/wiki/Users-Chat#bulk-build-chat-spaces
### 7.39.02
Fixed progress messages for `gam <UserTypeEntity> print filelist` when permissions were being
displayed/matched for Shared Drives.
### 7.39.01
Updated `gam <UserTypeEntity> transfer drive <UserItem>` to handle the following error:
```
ERROR: 403: cannotDeletePermission - The authenticated user cannot delete the permission.
```
### 7.39.00
Deleted variable `enforce_expansive_access` from `gam.cfg` and removed option `enforceexpansiveaccess`
from the following commands as expansive access is now always enforced by Google on My Drives.
```
gam <UserTypeEntity> delete permissions
gam <UserTypeEntity> delete drivefileacl
gam <UserTypeEntity> update drivefileacl
gam <UserTypeEntity> copy drivefile
gam <UserTypeEntity> move drivefile
gam <UserTypeEntity> transfer ownership
gam <UserTypeEntity> claim ownership
```
### 7.38.02
Added license SKU `1010470009` for `AI Expanded Access`; abbreviation `aiexpandedaccess`.
Renamed license SKU `1010470001` from `Gemini Enterprise` to `Gemini Enterprise - Legacy`.
### 7.38.01
Added `root` as a synonym for '/' in command line arguments that specify an OU.
This is to avoid issues where a stand-alone `/` on the command line may be mis-interpreted
by the command line interpreter as a reference to the file system root.
### 7.38.00
Added variable `gcp_org_id` to `gam.cfg` that is used by the following commands;
by setting the value, additional API calls are eliminated.
```
gam create project
gam create gcpfolder
gam create|update|delete caalevel
gam print|show caalevels
gam print|show tokens gcpdetails
```
You can get and set the `gam.cfg/gcp_org_id` value with these commands:
```
$ gam info gcporgid
organizations/906207637890
$ gam config gcp_org_id organizations/906207637890 save
```
You can get and set the `gam.cfg/customer_id` value with these commands:
```
$ gam info customerid
C78abc9de
$ gam config customer_id C78abc9de save
```
Added the following options to `gam report <ActivityApplicationName>`.
```
applicationinfofilter <String>
networkinfofilter <String>
statusfilter <String>
includesensitivedata
```
### 7.37.00
Added new client access scopes used by `gam print tokens`.
```
[*] 52) Resource Manager API - Organizations readonly
[*] 53) Resource Manager API - Projects readonly
```
Added option `gcpdetails` to `gam print tokens` that uses these scopes to get additional project information.
### 7.36.03
Added command to send email replies that causes Gmail to recognize the message
in conversation mode for the user sending the reply and the user receiving the reply;
GAM supplies the necessary headers and options.
```
gam <UserTypeEntity> sendreply
(((query <QueryGmail> [querytime<String> <Date>]*) [or|and])+) | (ids <MessageIDEntity>)
[replyto <EmailAddress>]
[subject <String>] [<MessageContent>] [html [<Boolean>]]
(attach <FileName> [charset <CharSet>])*
(embedimage <FileName> <String>)*
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
gam user user@domain.com sendreply query "rfc822MsgId:<CAAMmEdqj43...1OsQ@mail.gmail.com>" textmessage "Thanks for the information"
gam user user@domain.com sendreply ids 19cfc3506c02c22b textmessage "Thanks for the information"
```
* See: https://github.com/GAM-team/GAM/wiki/Send-Email#conversation-mode
### 7.36.02
Added option `threadid <String>` to `gam [<UserTypeEntity>] sendemail` that causes Gmail to recognize the message
in conversation mode in for the user sending the message.
* See: https://github.com/GAM-team/GAM/wiki/Send-Email#conversation-mode
### 7.36.01
Fixed bug in `gam info|print|show policies` where the `policyQuery/query` field was not displayed.
Added option `noidmapping` to `gam info|print|show policies` to suppress adding the `policyQuery/groupEmail` and
`policyQuery/orgUnitPath` name fields that are mapped from the `policyQuery/group` and `policyQuery/orgInit` id fields.
### 7.36.00
Added options `filtermultiattrtype` and filtermultiattrcustom` to `gam info user` and
`gam print users` that support filtering `<UserMultiAttribute>` display based on `type` or `customType`.
```
<UserMultiAttributeFilterName> ::=
address|addresses|
externalid|externalids|
im|ims|
keyword|keywords|
location|locations|
orgainzation|organizations|
otheremail|otheremails|
phone|phones|
relation|relations|
website|websites
```
* `filtermultiattrtype <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `type` is `<String>`
* `filtermultiattrcustom <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `customType` is `<String>`
```
gam info user user@domain.com quick filtermultiattrtype organizations work filtermultiattrcustom phones private
```
### 7.35.03
Updated `gam <UserTypeEntity> print filelist|filecounts` to handle options `showsize` and `showsizeunits` as independent options.
* `showsize` - Display a column `Size` with a byte count
* `showsizeunits` - Display a column `SizeUnits` with a formatted size with units
If you select both options, you can sort multiple rows using the `Size` column.
### 7.35.02
Added option `showsizeunits` to `gam gam <UserTypeEntity> print filelist|filecounts` as an alternative to option `showsize`.
* `showsize` - 31549200951 - This is a byte count
* `showsizeunits` - 31.55 GB - This is as shown in the Admin console
### 7.35.01
The following commands have been updated to not verify the existence of `gam.cfg` credentials files
as the WARNING messages about the missing files can be confusing to new users setting up GAM.
```
gam checkconn
gam oauth|oauth2
gam version
```
### 7.35.00
Windows `gam-7.wx.yz-x86_64.msi` has been replaced with `gam-7.wx.yz-x86_64.exe`.
Windows `gam-7.wx.yz-arm64.msi` has been replaced with `gam-7.wx.yz-arm64.exe`.
Updated cacerts.pem to avoid to following error in `gam checkconn`.
```
Checking raw.githubusercontent.com (185.199.110.133) (2)... ERROR
Certificate verification failed. If you are behind a firewall / proxy server that does TLS / SSL inspection you may need to point GAM at your certificate authority file by setting cacerts_pem = /path/to/your/certauth.pem in gam.cfg.
```
If you have customized cacerts.pem, update your version with the `Operating CA: Let's Encrypt` values from the GAM default version.
### 7.34.13
Fixed bug in `gam info policies <CIPolicyNameEntity> ... formatjson` where extraneous line
`Show Info 1 Policy` was displayed.
### 7.34.12
Fixed build errors that prevented Windows zip files from being created.
Added option `returnidonly` to `gam create|update printer` that causes GAM to return just the ID
of the printer.
### 7.34.11
Updated gam-install.sh script for macOS/Linux to properly config GAM when the answer to the following question is No.
```
Can you run a full browser on this machine? (usually Y for macOS, N for Linux if you SSH into this machine)
```
### 7.34.10
Fixed bug where `formatjson quotechar <Character>` on the command line did not override `redirect csv <FileName> multiprocess quotechar <Character>`.
### 7.34.09
Updated `gam <UserTypeEntity> update photo` to delete the user's existing photo
before performing the update as the API update will succeed but not replace a user's existing self-set photo.
### 7.34.08
Rebuild to avoid the following error:
```
requests/__init__.py:113: RequestsDependencyWarning: urllib3 (2.6.3) or chardet (6.0.0.post1)/charset_normalizer (3.4.4) doesn't match a supported version!
```
### 7.34.07
Added the following command to create a guest user.
* See: https://support.google.com/a/answer/16558545
```
gam create guestuser <EmailAddress>
```
Added the following items to `<UserFieldName>`:
* `guestaccountinfo` - Additional guest-related metadata fields
* `isguestuser` - Indicates if the inserted user is a guest
### 7.34.06
Added option `copyfolderpermissions [<Boolean>]` to `gam <UserTypeEntity> copy|move drivefile`.
When `copyfolderpermissions false` is specified, no folder permissions are copied; this simplifies
disabling all folder permission copying.
When not specified or `copyfolderpermissions [true]` is specified, folder permissions are copied based on the following options:
```
copymergewithparentfolderpermissions [<Boolean>]
copymergedtopfolderpermissions [<Boolean>]
copytopfolderpermissions [<Boolean>]
copytopfolderiheritedpermissions [<Boolean>]
copytopfoldernoniheritedpermissions never|always|syncallfolders|syncupdatedfolders
copymergedsubfolderpermissions [<Boolean>]
copysubfolderpermissions [<Boolean>]
copysubfolderinheritedpermissions [<Boolean>]
copysubfoldernoniheritedpermissions never|always|syncallfolders|syncupdatedfolders
```
### 7.34.05
Updated `gam report <ActivityApplictionName>` to perform a reverse chronological sort
on all rows across multiple users and/or event names; this is consistent with the behavior
in the Admin console. Use option `notimesort` to suppress this sort.
### 7.34.04
Updated `gam <UserTypeEntity> create drivefileacl <DriveFileEntity> user <UserItem> role owner` to better
handle the case where the current owner of a file is suspended. Previously, the command was displayed as an error
even though the ownership was changed.
```
gam user currentowner@domain.com add drivefileacl <DriveFileID> user newowner@domain.com role owner
User: currentowner@domain.com, Add 1 Drive File/Folder ACL
User: currentowner@domain.com, Drive File/Folder ID: <DriveFileID>, Permission ID: newowner@domain.com, Add Failed: Sorry, the items were successfully shared but emails could not be sent to newowner@domain.com.
```
Now the command is displayed as a success with a note indicating that the ownership change email was not sent.
```
gam user currentowner@domain.com add drivefileacl <DriveFileID> user newowner@domain.com role owner
User: currentowner@domain.com, Add 1 Drive File/Folder ACL
User: currentowner@domain.com, Drive File/Folder ID: <DriveFileID>, Permission ID: newowner@domain.com, Added: Sorry, the items were successfully shared but emails could not be sent to newowner@domain.com.
New Owner
id: 10834698115409747890
type: user
emailAddress: newowner@domain.com
domain: domain.com
role: owner
permissionDetails:
role: writer
type: file
inherited: True
inheritedFrom: Unknown
role: owner
type: file
inherited: False
deleted: False
pendingOwner: False
```
### 7.34.03
Updated to Python 3.14.3
Updated Cryptography to 46.0.5
Updated `gam course <CourseID> create student|teacher <EmailAddress>` error message when
`<EmailAddress>` is not in a trusted domain to remove suggestion about creating an invitation.
### 7.34.02
Updated GAM to prevent errors like the following:
```
ERROR: Unable to find the server at oauth2.googleapis.com
ERROR: Unable to find the server at gmail.googleapis.com
```
If you experience any unexpected errors, post a message to:
* The GAM Discussion Forum (google-apps-manager@googlegroups.com)
* The GAM Public Chat Room (https://chat.google.com/app/chat/AAAA4BULhWo)
### 7.34.01
Updated `gam create|update adminrole` to handle the following errors:
```
ERROR: 400: invalid - Invalid Role privileges
ERROR: 400: required - Required parameter: [resource.privileges[n].service_id]
```
### 7.34.00
Added variable `csv_output_header_required` to `gam.cfg` that is a comma separated list of `<Strings>`
that are required to be in the list of column headers in the CSV file written by a gam print command.
This will typically be used to specify headers that are required in subsequent commands that process
the CSV file even if the API didn't return any data for those columns.
Updated the following commands to not require the `Directory API - Domains` scope
unless the `internal` or `external` options are used to request the member category.
```
gam info|print groups
gam print|show group-members
gam info|print cigroups
gam print|show cigroup-members
gam <UserTypeEntity> print|show filesharecounts
```
### 7.33.03 ### 7.33.03
Fixed bug in `gam [<UserTypeEntity>] sendemail ... from <EmailAddress> replyto <EmailAddress>` Fixed bug in `gam [<UserTypeEntity>] sendemail ... from <EmailAddress> replyto <EmailAddress>`

View File

@@ -1,13 +1,12 @@
# Groups # Groups
- [API documentation](#api-documentation) - [API documentation](#api-documentation)
- [Query documentation](#query-documentation) - [Query documentation](#query-documentation)
- [Python Regular Expressions](Python-Regular-Expressions) Match function and Search function - [Python Regular Expressions](Python-Regular-Expressions) Match function
- [Definitions](#definitions) - [Definitions](#definitions)
- [GUI API Group settings mapping](#gui-api-group-settings-mapping) - [GUI API Group settings mapping](#gui-api-group-settings-mapping)
- [GUI API Group access type settings mapping](#gui-api-group-access-type-settings-mapping) - [GUI API Group access type settings mapping](#gui-api-group-access-type-settings-mapping)
- [whoCanViewMembership and whoCanDiscoverGroup interactions](#whocanviewmembership-and-whocandiscovergroup-interactions) - [whoCanViewMembership and whoCanDiscoverGroup interactions](#whocanviewmembership-and-whocandiscovergroup-interactions)
- [Manage groups](#manage-groups) - [Manage groups](#manage-groups)
- [Update a group's primary email address](#update-a-groups-primary-email-address)
- [Update a group's settings with JSON data](#update-a-groups-settings-with-json-data) - [Update a group's settings with JSON data](#update-a-groups-settings-with-json-data)
- [Display information about specific groups](#display-information-about-specific-groups) - [Display information about specific groups](#display-information-about-specific-groups)
- [Display information about selected groups](#display-information-about-selected-groups) - [Display information about selected groups](#display-information-about-selected-groups)
@@ -349,7 +348,6 @@ gam create group <EmailAddress>
[copyfrom <GroupItem>] <GroupAttribute>* [copyfrom <GroupItem>] <GroupAttribute>*
[verifynotinvitable] [verifynotinvitable]
gam update group|groups <GroupEntity> [email <EmailAddress>] gam update group|groups <GroupEntity> [email <EmailAddress>]
[updateprimaryemail <RESearchPattern> <RESubstitution> [preview]]
[copyfrom <GroupItem>] <GroupAttribute>* [copyfrom <GroupItem>] <GroupAttribute>*
[makesecuritygroup|security] [makesecuritygroup|security]
[admincreated <Boolean>] [admincreated <Boolean>]
@@ -365,22 +363,6 @@ You can update a group to a security group with the `makesecuritygroup` option.
When deleting and `noactionifalias` is specified, no action is performed if `<GroupEntity>` specifies an alias rather than a primary email address. When deleting and `noactionifalias` is specified, no action is performed if `<GroupEntity>` specifies an alias rather than a primary email address.
## Update a group's primary email address
You can simply update a group's primary email address with the `email` option.
```
gam update group groupold@domain.com email groupnew@domain.com
```
The `updateprimaryemail <RESearchPattern> <RESubstitution> [preview]` option allows modification several group's
current primary email address. For example, to change the domain of a set of groups from the current domain.com to newdomain.com,
make a CSV file Groups.csv with a column `email` that contains the group email addresses that are to be changed.
You can list all groups with: `gam redirect csv ./Groups.csv print groups`
```
gam update group csvfile Groups.csv:email updateprimaryemail "^(.+)@domain.com$" "\1@newdomain.com"
```
The `preview` option allows verification of the primary email address changes before commiting the changes.
If the group's current primary email address does not match the <REMatchPattern> then no modification is made.
## Update a group's settings with JSON data ## Update a group's settings with JSON data
You can save group settings in JSON format which can simplify updating multiple settings. Suppose you have You can save group settings in JSON format which can simplify updating multiple settings. Suppose you have
a set of test groups that you will use to experiment with the new group settings coming in May 2019. You a set of test groups that you will use to experiment with the new group settings coming in May 2019. You

View File

@@ -9,30 +9,30 @@ and all necessary authentications.
## Linux and MacOS and Google Cloud Shell ## Linux and MacOS and Google Cloud Shell
In these examples, your Google Super admin is shown as gamteam@domain.com; replace with the In these examples, your Google Super admin is shown as admin@domain.com; replace with the
actual email adddress. actual email adddress.
In these examples, the user home folder is shown as /Users/gamteam; adjust according to your In these examples, the user home folder is shown as /Users/admin; adjust according to your
specific situation; e.g., /home/administrator. specific situation; e.g., /home/administrator.
This example assumes that GAM7 has been installed in /Users/gamteam/bin/gam7. This example assumes that GAM7 has been installed in /Users/admin/bin/gam7.
If you've installed GAM7 in another directory, substitute that value in the directions. If you've installed GAM7 in another directory, substitute that value in the directions.
### Set a configuration directory ### Set a configuration directory
The default GAM configuration directory is /Users/gamteam/.gam; for more flexibility you The default GAM configuration directory is /Users/admin/.gam; for more flexibility you
probably want to select a non-hidden location. This example assumes that the GAM probably want to select a non-hidden location. This example assumes that the GAM
configuration directory will be /Users/gamteam/GAMConfig; If you've chosen another directory, configuration directory will be /Users/admin/GAMConfig; If you've chosen another directory,
substitute that value in the directions. substitute that value in the directions.
Make the directory: Make the directory:
``` ```
gamteam@server:/Users/gamteam$ mkdir -p /Users/gamteam/GAMConfig admin@server:/Users/admin$ mkdir -p /Users/admin/GAMConfig
``` ```
Add the following line: Add the following line:
``` ```
export GAMCFGDIR="/Users/gamteam/GAMConfig" export GAMCFGDIR="/Users/admin/GAMConfig"
``` ```
to one of these files based on your shell: to one of these files based on your shell:
``` ```
@@ -44,34 +44,34 @@ to one of these files based on your shell:
Issue the following command replacing `<Filename>` with the name of the file you edited: Issue the following command replacing `<Filename>` with the name of the file you edited:
``` ```
gamteam@server:/Users/gamteam$ source <Filename> admin@server:/Users/admin$ source <Filename>
``` ```
You need to make sure the GAM configuration directory actually exists. Test that like this: You need to make sure the GAM configuration directory actually exists. Test that like this:
``` ```
gamteam@server:/Users/gamteam$ ls -l $GAMCFGDIR admin@server:/Users/admin$ ls -l $GAMCFGDIR
``` ```
### Set a working directory ### Set a working directory
You should establish a GAM working directory; you will store your GAM related You should establish a GAM working directory; you will store your GAM related
data in this folder and execute GAM commands from this folder. You should not use data in this folder and execute GAM commands from this folder. You should not use
/Users/gamteam/bin/gam7 or /Users/gamteam/GAMConfig for this purpose. /Users/admin/bin/gam7 or /Users/admin/GAMConfig for this purpose.
This example assumes that the GAM working directory will be /Users/gamteam/GAMWork; If you've chosen This example assumes that the GAM working directory will be /Users/admin/GAMWork; If you've chosen
another directory, substitute that value in the directions. another directory, substitute that value in the directions.
Make the directory: Make the directory:
``` ```
gamteam@server:/Users/gamteam$ mkdir -p /Users/gamteam/GAMWork admin@server:/Users/admin$ mkdir -p /Users/admin/GAMWork
``` ```
### Set an alias ### Set an alias
You should set an alias to point to /Users/gamteam/bin/gam7/gam so you can operate from the /Users/gamteam/GAMWork directory. You should set an alias to point to /Users/admin/bin/gam7/gam so you can operate from the /Users/admin/GAMWork directory.
Aliases aren't available in scripts, so you may want to set a symlink instead, see below. Aliases aren't available in scripts, so you may want to set a symlink instead, see below.
Add the following line: Add the following line:
``` ```
alias gam="/Users/gamteam/bin/gam7/gam" alias gam="/Users/admin/bin/gam7/gam"
``` ```
to one of these files based on your shell: to one of these files based on your shell:
``` ```
@@ -84,48 +84,48 @@ to one of these files based on your shell:
Issue the following command replacing `<Filename>` with the name of the file you edited: Issue the following command replacing `<Filename>` with the name of the file you edited:
``` ```
gamteam@server:/Users/gamteam$ source <Filename> admin@server:/Users/admin$ source <Filename>
``` ```
### Set a symlink ### Set a symlink
Set a symlink in `/usr/local/bin` (or some other location on $PATH) to point to GAM. Set a symlink in `/usr/local/bin` (or some other location on $PATH) to point to GAM.
``` ```
gamteam@server:/Users/gamteam$ ln -s "/Users/gamteam/bin/gam7/gam" /usr/local/bin/gam admin@server:/Users/admin$ ln -s "/Users/admin/bin/gam7/gam" /usr/local/bin/gam
``` ```
### Initialize GAM7; this should be the first GAM7 command executed. ### Initialize GAM7; this should be the first GAM7 command executed.
``` ```
gamteam@server:/Users/gamteam$ gam config drive_dir /Users/gamteam/GAMWork verify admin@server:/Users/admin$ gam config drive_dir /Users/admin/GAMWork verify
Created: /Users/gamteam/GAMConfig Created: /Users/admin/GAMConfig
Created: /Users/gamteam/GAMConfig/gamcache Created: /Users/admin/GAMConfig/gamcache
Config File: /Users/gamteam/GAMConfig/gam.cfg, Initialized Config File: /Users/admin/GAMConfig/gam.cfg, Initialized
Section: DEFAULT Section: DEFAULT
... ...
cache_dir = /Users/gamteam/GAMConfig/gamcache cache_dir = /Users/admin/GAMConfig/gamcache
... ...
config_dir = /Users/gamteam/GAMConfig config_dir = /Users/admin/GAMConfig
... ...
drive_dir = /Users/gamteam/GAMWork drive_dir = /Users/admin/GAMWork
... ...
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
### Verify initialization, this was a successful installation. ### Verify initialization, this was a successful installation.
``` ```
gamteam@server:/Users/gamteam$ ls -l $GAMCFGDIR admin@server:/Users/admin$ ls -l $GAMCFGDIR
total 48 total 48
-rw-r-----+ 1 admin staff 1069 Mar 3 09:23 gam.cfg -rw-r-----+ 1 admin staff 1069 Mar 3 09:23 gam.cfg
drwxr-x---+ 2 admin staff 68 Mar 3 09:23 gamcache drwxr-x---+ 2 admin staff 68 Mar 3 09:23 gamcache
-rw-rw-rw-+ 1 admin staff 0 Mar 3 09:23 oauth2.txt.lock -rw-rw-rw-+ 1 admin staff 0 Mar 3 09:23 oauth2.txt.lock
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
### Create your project with local browser ### Create your project with local browser
``` ```
gamteam@server:/Users/gamteam$ gam create project admin@server:/Users/admin$ gam create project
WARNING: Config File: /Users/gamteam/GAMConfig/gam.cfg, Item: client_secrets_json, Value: /Users/gamteam/GAMConfig/client_secrets.json, Not Found WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Item: client_secrets_json, Value: /Users/admin/GAMConfig/client_secrets.json, Not Found
WARNING: Config File: /Users/gamteam/GAMConfig/gam.cfg, Item: oauth2service_json, Value: /Users/gamteam/GAMConfig/oauth2service.json, Not Found WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Item: oauth2service_json, Value: /Users/admin/GAMConfig/oauth2service.json, Not Found
Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) gamteam@domain.com Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) admin@domain.com
Your browser has been opened to visit: Your browser has been opened to visit:
@@ -167,7 +167,7 @@ Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-p
Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Extracting public certificate Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Extracting public certificate
Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Done generating private key and public certificate Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Done generating private key and public certificate
Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Service Account Key: SVCACCTKEY, Uploaded Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Service Account Key: SVCACCTKEY, Uploaded
Service Account OAuth2 File: /Users/gamteam/GAMConfig/oauth2service.json, Service Account Key: SVCACCTKEY, Updated Service Account OAuth2 File: /Users/admin/GAMConfig/oauth2service.json, Service Account Key: SVCACCTKEY, Updated
Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Has rights to rotate own private key Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Has rights to rotate own private key
Please go to: Please go to:
@@ -185,16 +185,16 @@ Enter your Client Secret: CLIENTSECRET
6. Go back to your browser and click OK to close the "OAuth client" popup if it's still open. 6. Go back to your browser and click OK to close the "OAuth client" popup if it's still open.
That's it! Your GAM Project is created and ready to use. That's it! Your GAM Project is created and ready to use.
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
### Create your project without local browser (Google Cloud Shell for instance) ### Create your project without local browser (Google Cloud Shell for instance)
``` ```
gamteam@server:/Users/gamteam$ gam config no_browser true save admin@server:/Users/admin$ gam config no_browser true save
gamteam@server:/Users/gamteam$ gam create project admin@server:/Users/admin$ gam create project
WARNING: Config File: /Users/gamteam/GAMConfig/gam.cfg, Item: client_secrets_json, Value: /Users/gamteam/GAMConfig/client_secrets.json, Not Found WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Item: client_secrets_json, Value: /Users/admin/GAMConfig/client_secrets.json, Not Found
WARNING: Config File: /Users/gamteam/GAMConfig/gam.cfg, Item: oauth2service_json, Value: /Users/gamteam/GAMConfig/oauth2service.json, Not Found WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Item: oauth2service_json, Value: /Users/admin/GAMConfig/oauth2service.json, Not Found
Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) gamteam@domain.com Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) admin@domain.com
Go to the following link in a browser on other computer: Go to the following link in a browser on other computer:
@@ -235,7 +235,7 @@ Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-p
Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Extracting public certificate Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Extracting public certificate
Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Done generating private key and public certificate Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Done generating private key and public certificate
Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Service Account Key: SVCACCTKEY, Uploaded Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Service Account Key: SVCACCTKEY, Uploaded
Service Account OAuth2 File: /Users/gamteam/GAMConfig/oauth2service.json, Service Account Key: SVCACCTKEY, Updated Service Account OAuth2 File: /Users/admin/GAMConfig/oauth2service.json, Service Account Key: SVCACCTKEY, Updated
Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Has rights to rotate own private key Project: gam-project-abc-def-ghi, Service Account: gam-project-abc-def-ghi@gam-project-abc-def-ghi.iam.gserviceaccount.com, Has rights to rotate own private key
Please go to: Please go to:
@@ -253,7 +253,7 @@ Enter your Client Secret: CLIENTSECRET
6. Go back to your browser and click OK to close the "OAuth client" popup if it's still open. 6. Go back to your browser and click OK to close the "OAuth client" popup if it's still open.
That's it! Your GAM Project is created and ready to use. That's it! Your GAM Project is created and ready to use.
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
### Enable GAM7 client access ### Enable GAM7 client access
@@ -261,7 +261,7 @@ You select a list of scopes, GAM uses a browser to get final authorization from
writes the credentials into the file oauth2.txt. writes the credentials into the file oauth2.txt.
``` ```
gamteam@server:/Users/gamteam$ gam oauth create admin@server:/Users/admin$ gam oauth create
[*] 0) Calendar API (supports readonly) [*] 0) Calendar API (supports readonly)
[*] 1) Chrome Browser Cloud Management API (supports readonly) [*] 1) Chrome Browser Cloud Management API (supports readonly)
@@ -328,7 +328,7 @@ Continue to authorization by entering a 'c'
Please enter 0-50[a|r] or s|u|e|c: c Please enter 0-50[a|r] or s|u|e|c: c
Enter your Google Workspace admin email address? gamteam@domain.com Enter your Google Workspace admin email address? admin@domain.com
Go to the following link in a browser on this computer or on another computer: Go to the following link in a browser on this computer or on another computer:
@@ -340,16 +340,16 @@ click the Allow button, paste "Unable to connect" URL from other computer (only
Enter verification code or paste "Unable to connect" URL from other computer (only URL data up to &scope required): Enter verification code or paste "Unable to connect" URL from other computer (only URL data up to &scope required):
The authentication flow has completed. The authentication flow has completed.
Client OAuth2 File: /Users/gamteam/GAMConfig/oauth2.txt, Created Client OAuth2 File: /Users/admin/GAMConfig/oauth2.txt, Created
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
If clicking on the link in the instructions does not work (i.e. you get a 404 or 400 error message, instead of something about 'unable to connect') the URL in the link is too long. Most likely, you have selected all scopes. Try again with fewer scopes until it works. (there is no harm in repeatedly trying) If clicking on the link in the instructions does not work (i.e. you get a 404 or 400 error message, instead of something about 'unable to connect') the URL in the link is too long. Most likely, you have selected all scopes. Try again with fewer scopes until it works. (there is no harm in repeatedly trying)
### Enable GAM7 service account access. ### Enable GAM7 service account access.
``` ```
gamteam@server:/Users/gamteam$ gam user gamteam@domain.com update serviceaccount admin@server:/Users/admin$ gam user admin@domain.com update serviceaccount
[*] 0) AlertCenter API [*] 0) AlertCenter API
[*] 1) Analytics API - read only [*] 1) Analytics API - read only
[*] 2) Analytics Admin API - read only [*] 2) Analytics Admin API - read only
@@ -413,7 +413,7 @@ Service Account Private Key Authentication
Authentication PASS Authentication PASS
Service Account Private Key age; Google recommends rotating keys on a routine basis Service Account Private Key age; Google recommends rotating keys on a routine basis
Service Account Private Key age: 1 day WARN Service Account Private Key age: 1 day WARN
Domain-wide Delegation authentication:, User: gamteam@domain.com, Scopes: 38 Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 38
https://mail.google.com/ FAIL (1/38) https://mail.google.com/ FAIL (1/38)
https://sites.google.com/feeds FAIL (2/38) https://sites.google.com/feeds FAIL (2/38)
https://www.googleapis.com/auth/analytics.readonly FAIL (3/38) https://www.googleapis.com/auth/analytics.readonly FAIL (3/38)
@@ -464,7 +464,7 @@ Click AUTHORIZE
When the box closes you're done When the box closes you're done
After authorizing it may take some time for this test to pass so wait a few moments and then try this command again. After authorizing it may take some time for this test to pass so wait a few moments and then try this command again.
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
The link shown in the error message should take you directly to the authorization screen. The link shown in the error message should take you directly to the authorization screen.
If not, make sure that you are logged in as a domain admin, then re-enter the link. If not, make sure that you are logged in as a domain admin, then re-enter the link.
@@ -474,14 +474,14 @@ If not, make sure that you are logged in as a domain admin, then re-enter the li
Wait a moment and then perform the following command; it it still fails, wait a bit longer, it can sometimes take serveral minutes Wait a moment and then perform the following command; it it still fails, wait a bit longer, it can sometimes take serveral minutes
for the authorization to complete. for the authorization to complete.
``` ```
gamteam@server:/Users/gamteam$ gam user gamteam@domain.com check serviceaccount admin@server:/Users/admin$ gam user admin@domain.com check serviceaccount
System time status System time status
Your system time differs from admin.googleapis.com by less than 1 second PASS Your system time differs from admin.googleapis.com by less than 1 second PASS
Service Account Private Key Authentication Service Account Private Key Authentication
Authentication PASS Authentication PASS
Service Account Private Key age; Google recommends rotating keys on a routine basis Service Account Private Key age; Google recommends rotating keys on a routine basis
Service Account Private Key age: 1 day WARN Service Account Private Key age: 1 day WARN
Domain-wide Delegation authentication:, User: gamteam@domain.com, Scopes: 38 Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 38
https://mail.google.com/ PASS (1/38) https://mail.google.com/ PASS (1/38)
https://sites.google.com/feeds PASS (2/38) https://sites.google.com/feeds PASS (2/38)
https://www.googleapis.com/auth/analytics.readonly PASS (3/38) https://www.googleapis.com/auth/analytics.readonly PASS (3/38)
@@ -524,14 +524,14 @@ All scopes PASSED!
Service Account Client name: SVCACCTID is fully authorized. Service Account Client name: SVCACCTID is fully authorized.
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
### Update gam.cfg with some basic values ### Update gam.cfg with some basic values
* `customer_id` - Having this data keeps Gam from having to make extra API calls * `customer_id` - Having this data keeps Gam from having to make extra API calls
* `domain` - This allows you to omit the domain portion of email addresses * `domain` - This allows you to omit the domain portion of email addresses
* `timezone local` - Gam will convert all UTC times to your local timezone * `timezone local` - Gam will convert all UTC times to your local timezone
``` ```
gamteam@server:/Users/gamteam$ gam info domain admin@server:/Users/admin$ gam info domain
Customer ID: C01234567 Customer ID: C01234567
Primary Domain: domain.com Primary Domain: domain.com
Customer Creation Time: 2007-06-06T15:47:55.444Z Customer Creation Time: 2007-06-06T15:47:55.444Z
@@ -539,8 +539,8 @@ Primary Domain Verified: True
Default Language: en Default Language: en
... ...
gamteam@server:/Users/gamteam$ gam config customer_id C01234567 domain domain.com timezone local save verify admin@server:/Users/admin$ gam config customer_id C01234567 domain domain.com timezone local save verify
Config File: /Users/gamteam/GAMConfig/gam.cfg, Saved Config File: /Users/admin/GAMConfig/gam.cfg, Saved
Section: DEFAULT Section: DEFAULT
... ...
customer_id = C01234567 customer_id = C01234567
@@ -550,12 +550,12 @@ Section: DEFAULT
timezone = local timezone = local
... ...
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
## Windows ## Windows
In these examples, your Google Super admin is shown as gamteam@domain.com; replace with the In these examples, your Google Super admin is shown as admin@domain.com; replace with the
actual email adddress. actual email adddress.
This example assumes that GAM7 has been installed in C:\GAM7; if you've installed This example assumes that GAM7 has been installed in C:\GAM7; if you've installed
@@ -645,7 +645,7 @@ C:\>gam create project
WARNING: Config File: C:\GAMConfig\gam.cfg, Item: client_secrets_json, Value: C:\GAMConfig\client_secrets.json, Not Found WARNING: Config File: C:\GAMConfig\gam.cfg, Item: client_secrets_json, Value: C:\GAMConfig\client_secrets.json, Not Found
WARNING: Config File: C:\GAMConfig\gam.cfg, Item: oauth2service_json, Value: C:\GAMConfig\oauth2service.json, Not Found WARNING: Config File: C:\GAMConfig\gam.cfg, Item: oauth2service_json, Value: C:\GAMConfig\oauth2service.json, Not Found
Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) gamteam@domain.com Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) admin@domain.com
Your browser has been opened to visit: Your browser has been opened to visit:
@@ -714,7 +714,7 @@ C:\>gam create project
WARNING: Config File: C:\GAMConfig\gam.cfg, Item: client_secrets_json, Value: C:\GAMConfig\client_secrets.json, Not Found WARNING: Config File: C:\GAMConfig\gam.cfg, Item: client_secrets_json, Value: C:\GAMConfig\client_secrets.json, Not Found
WARNING: Config File: C:\GAMConfig\gam.cfg, Item: oauth2service_json, Value: C:\GAMConfig\oauth2service.json, Not Found WARNING: Config File: C:\GAMConfig\gam.cfg, Item: oauth2service_json, Value: C:\GAMConfig\oauth2service.json, Not Found
Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) gamteam@domain.com Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) admin@domain.com
Go to the following link in a browser on other computer: Go to the following link in a browser on other computer:
@@ -848,7 +848,7 @@ Continue to authorization by entering a 'c'
Please enter 0-50[a|r] or s|u|e|c: c Please enter 0-50[a|r] or s|u|e|c: c
Enter your Google Workspace admin email address? gamteam@domain.com Enter your Google Workspace admin email address? admin@domain.com
Go to the following link in a browser on this computer or on another computer: Go to the following link in a browser on this computer or on another computer:
@@ -866,7 +866,7 @@ C:\>
``` ```
### Enable GAM7 service account access. ### Enable GAM7 service account access.
``` ```
C:\>gam user gamteam@domain.com update serviceaccount C:\>gam user admin@domain.com update serviceaccount
[*] 0) AlertCenter API [*] 0) AlertCenter API
[*] 1) Analytics API - read only [*] 1) Analytics API - read only
[*] 2) Analytics Admin API - read only [*] 2) Analytics Admin API - read only
@@ -930,7 +930,7 @@ Service Account Private Key Authentication
Authentication PASS Authentication PASS
Service Account Private Key age; Google recommends rotating keys on a routine basis Service Account Private Key age; Google recommends rotating keys on a routine basis
Service Account Private Key age: 1 day WARN Service Account Private Key age: 1 day WARN
Domain-wide Delegation authentication:, User: gamteam@domain.com, Scopes: 38 Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 38
https://mail.google.com/ FAIL (1/38) https://mail.google.com/ FAIL (1/38)
https://sites.google.com/feeds FAIL (2/38) https://sites.google.com/feeds FAIL (2/38)
https://www.googleapis.com/auth/analytics.readonly FAIL (3/38) https://www.googleapis.com/auth/analytics.readonly FAIL (3/38)
@@ -991,14 +991,14 @@ If not, make sure that you are logged in as a domain admin, then re-enter the li
Wait a moment and then perform the following command; it it still fails, wait a bit longer, it can sometimes take serveral minutes Wait a moment and then perform the following command; it it still fails, wait a bit longer, it can sometimes take serveral minutes
for the authorization to complete. for the authorization to complete.
``` ```
C:\>gam user gamteam@domain.com check serviceaccount C:\>gam user admin@domain.com check serviceaccount
System time status System time status
Your system time differs from admin.googleapis.com by less than 1 second PASS Your system time differs from admin.googleapis.com by less than 1 second PASS
Service Account Private Key Authentication Service Account Private Key Authentication
Authentication PASS Authentication PASS
Service Account Private Key age; Google recommends rotating keys on a routine basis Service Account Private Key age; Google recommends rotating keys on a routine basis
Service Account Private Key age: 1 day WARN Service Account Private Key age: 1 day WARN
Domain-wide Delegation authentication:, User: gamteam@domain.com, Scopes: 38 Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 38
https://mail.google.com/ PASS (1/38) https://mail.google.com/ PASS (1/38)
https://sites.google.com/feeds PASS (2/38) https://sites.google.com/feeds PASS (2/38)
https://www.googleapis.com/auth/analytics.readonly PASS (3/38) https://www.googleapis.com/auth/analytics.readonly PASS (3/38)

View File

@@ -129,7 +129,7 @@ See: [Downloads-Installs-GAM7](Downloads-Installs-GAM7)
### Update to latest version, use current path `C:\GAMADV-XTD3`. ### Update to latest version, use current path `C:\GAMADV-XTD3`.
You don't have to update path or scripts. You don't have to update path or scripts.
* Executable Installer, Manual, Windows 64 bit * Executable Installer, Manual, Windows 64 bit
- `gam-7.wx.yz-windows-x86_64.exe` - `gam-7.wx.yz-windows-x86_64.msi`
- Download the installer and run it. When prompted for the Destination Foler, enter `C:\GAMADV-XTD3`. - Download the installer and run it. When prompted for the Destination Foler, enter `C:\GAMADV-XTD3`.
* Executable Archive, Manual, Windows 64 bit * Executable Archive, Manual, Windows 64 bit
- `gam-7.wx.yz-windows-x86_64.zip` - `gam-7.wx.yz-windows-x86_64.zip`
@@ -139,7 +139,7 @@ Your update is complete.
### Update to latest version, use new path `C:\GAM7`. ### Update to latest version, use new path `C:\GAM7`.
* Executable Installer, Manual, Windows 64 bit * Executable Installer, Manual, Windows 64 bit
- `gam-7.wx.yz-windows-x86_64.exe` - `gam-7.wx.yz-windows-x86_64.msi`
- Download the installer and run it. - Download the installer and run it.
- Start a Command Prompt/PowerShell session. - Start a Command Prompt/PowerShell session.
* Executable Archive, Manual, Windows 64 bit * Executable Archive, Manual, Windows 64 bit

View File

@@ -10,30 +10,30 @@ and all necessary authentications.
## Linux and MacOS and Google Cloud Shell ## Linux and MacOS and Google Cloud Shell
In these examples, your Google Super admin is shown as gamteam@domain.com; replace with the In these examples, your Google Super admin is shown as admin@domain.com; replace with the
actual email adddress. actual email adddress.
In these examples, the user home folder is shown as /Users/gamteam; adjust according to your In these examples, the user home folder is shown as /Users/admin; adjust according to your
specific situation; e.g., /home/administrator. specific situation; e.g., /home/administrator.
This example assumes that GAM7 has been installed in /Users/gamteam/bin/gam7. This example assumes that GAM7 has been installed in /Users/admin/bin/gam7.
If you've installed GAM7 in another directory, substitute that value in the directions. If you've installed GAM7 in another directory, substitute that value in the directions.
### Set a configuration directory ### Set a configuration directory
The default GAM configuration directory is /Users/gamteam/.gam; for more flexibility you The default GAM configuration directory is /Users/admin/.gam; for more flexibility you
probably want to select a non-hidden location. This example assumes that the GAM probably want to select a non-hidden location. This example assumes that the GAM
configuration directory will be /Users/gamteam/GAMConfig; If you've chosen another directory, configuration directory will be /Users/admin/GAMConfig; If you've chosen another directory,
substitute that value in the directions. substitute that value in the directions.
Make the directory: Make the directory:
``` ```
gamteam@server:/Users/gamteam$ mkdir -p /Users/gamteam/GAMConfig admin@server:/Users/admin$ mkdir -p /Users/admin/GAMConfig
``` ```
Add the following line: Add the following line:
``` ```
export GAMCFGDIR="/Users/gamteam/GAMConfig" export GAMCFGDIR="/Users/admin/GAMConfig"
``` ```
to one of these files based on your shell: to one of these files based on your shell:
``` ```
@@ -45,34 +45,34 @@ to one of these files based on your shell:
Issue the following command replacing `<Filename>` with the name of the file you edited: Issue the following command replacing `<Filename>` with the name of the file you edited:
``` ```
gamteam@server:/Users/gamteam$ source <Filename> admin@server:/Users/admin$ source <Filename>
``` ```
You need to make sure the GAM configuration directory actually exists. Test that like this: You need to make sure the GAM configuration directory actually exists. Test that like this:
``` ```
gamteam@server:/Users/gamteam$ ls -l $GAMCFGDIR admin@server:/Users/admin$ ls -l $GAMCFGDIR
``` ```
### Set a working directory ### Set a working directory
You should establish a GAM working directory; you will store your GAM related You should establish a GAM working directory; you will store your GAM related
data in this folder and execute GAM commands from this folder. You should not use data in this folder and execute GAM commands from this folder. You should not use
/Users/gamteam/bin/gam7 or /Users/gamteam/GAMConfig for this purpose. /Users/admin/bin/gam7 or /Users/admin/GAMConfig for this purpose.
This example assumes that the GAM working directory will be /Users/gamteam/GAMWork; If you've chosen This example assumes that the GAM working directory will be /Users/admin/GAMWork; If you've chosen
another directory, substitute that value in the directions. another directory, substitute that value in the directions.
Make the directory: Make the directory:
``` ```
gamteam@server:/Users/gamteam$ mkdir -p /Users/gamteam/GAMWork admin@server:/Users/admin$ mkdir -p /Users/admin/GAMWork
``` ```
### Set an alias ### Set an alias
You should set an alias to point to /Users/gamteam/bin/gam7/gam so you can operate from the /Users/gamteam/GAMWork directory. You should set an alias to point to /Users/admin/bin/gam7/gam so you can operate from the /Users/admin/GAMWork directory.
Aliases aren't available in scripts, so you may want to set a symlink instead, see below. Aliases aren't available in scripts, so you may want to set a symlink instead, see below.
Add the following line: Add the following line:
``` ```
alias gam="/Users/gamteam/bin/gam7/gam" alias gam="/Users/admin/bin/gam7/gam"
``` ```
to one of these files based on your shell: to one of these files based on your shell:
``` ```
@@ -85,62 +85,62 @@ to one of these files based on your shell:
If you already have an alias for legacy GAM but are no longer going to run it, delete these lines: If you already have an alias for legacy GAM but are no longer going to run it, delete these lines:
``` ```
function gam() { "/Users/gamteam/bin/gam/gam" "$@" ; }" function gam() { "/Users/admin/bin/gam/gam" "$@" ; }"
alias gam="/Users/gamteam/bin/gam/gam" alias gam="/Users/admin/bin/gam/gam"
``` ```
If you already have an alias for legacy GAM and want to run it and GAM7, give your old alias a different name: If you already have an alias for legacy GAM and want to run it and GAM7, give your old alias a different name:
``` ```
function gamstd() { "/Users/gamteam/bin/gam/gam" "$@" ; }" function gamstd() { "/Users/admin/bin/gam/gam" "$@" ; }"
alias gamstd="/Users/gamteam/bin/gam/gam" alias gamstd="/Users/admin/bin/gam/gam"
``` ```
Issue the following command replacing `<Filename>` with the name of the file you edited: Issue the following command replacing `<Filename>` with the name of the file you edited:
``` ```
gamteam@server:/Users/gamteam$ source <Filename> admin@server:/Users/admin$ source <Filename>
``` ```
### Set a symlink ### Set a symlink
Set a symlink in `/usr/local/bin` (or some other location on $PATH) to point to GAM. Set a symlink in `/usr/local/bin` (or some other location on $PATH) to point to GAM.
``` ```
gamteam@server:/Users/gamteam$ ln -s "/Users/gamteam/bin/gam7/gam" /usr/local/bin/gam admin@server:/Users/admin$ ln -s "/Users/admin/bin/gam7/gam" /usr/local/bin/gam
``` ```
Set environment variable OLDGAMPATH to point to the existing Gam directory; /Users/gamteam/bin/gam will be used in this example. Set environment variable OLDGAMPATH to point to the existing Gam directory; /Users/admin/bin/gam will be used in this example.
If your existing Gam is in another directory, substitute that value in the directions. If your existing Gam is in another directory, substitute that value in the directions.
``` ```
gamteam@server:/Users/gamteam$ export OLDGAMPATH=/Users/gamteam/bin/gam admin@server:/Users/admin$ export OLDGAMPATH=/Users/admin/bin/gam
``` ```
Verify that OLDGAMPATH points to the correct location. Verify that OLDGAMPATH points to the correct location.
``` ```
gamteam@server:/Users/gamteam$ ls -l $OLDGAMPATH/*.json admin@server:/Users/admin$ ls -l $OLDGAMPATH/*.json
-rw-r-----@ 1 admin staff 553 Feb 26 10:39 /Users/gamteam/bin/gam/client_secrets.json -rw-r-----@ 1 admin staff 553 Feb 26 10:39 /Users/admin/bin/gam/client_secrets.json
-rw-r-----@ 1 admin staff 2377 Feb 26 10:39 /Users/gamteam/bin/gam/oauth2service.json -rw-r-----@ 1 admin staff 2377 Feb 26 10:39 /Users/admin/bin/gam/oauth2service.json
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
### Initialize GAM7; this should be the first GAM7 command executed. ### Initialize GAM7; this should be the first GAM7 command executed.
``` ```
gamteam@server:/Users/gamteam$ gam config drive_dir /Users/gamteam/GAMWork verify admin@server:/Users/admin$ gam config drive_dir /Users/admin/GAMWork verify
Created: /Users/gamteam/GAMConfig Created: /Users/admin/GAMConfig
Created: /Users/gamteam/GAMConfig/gamcache Created: /Users/admin/GAMConfig/gamcache
Copied: /Users/gamteam/bin/gam/oauth2service.json, To: /Users/gamteam/GAMConfig/oauth2service.json Copied: /Users/admin/bin/gam/oauth2service.json, To: /Users/admin/GAMConfig/oauth2service.json
Copied: /Users/gamteam/bin/gam/oauth2.txt, To: /Users/gamteam/GAMConfig/oauth2.txt Copied: /Users/admin/bin/gam/oauth2.txt, To: /Users/admin/GAMConfig/oauth2.txt
Copied: /Users/gamteam/bin/gam/client_secrets.json, To: /Users/gamteam/GAMConfig/client_secrets.json Copied: /Users/admin/bin/gam/client_secrets.json, To: /Users/admin/GAMConfig/client_secrets.json
Config File: /Users/gamteam/GAMConfig/gam.cfg, Initialized Config File: /Users/admin/GAMConfig/gam.cfg, Initialized
Section: DEFAULT Section: DEFAULT
... ...
cache_dir = /Users/gamteam/GAMConfig/gamcache cache_dir = /Users/admin/GAMConfig/gamcache
... ...
config_dir = /Users/gamteam/GAMConfig config_dir = /Users/admin/GAMConfig
... ...
drive_dir = /Users/gamteam/GAMWork drive_dir = /Users/admin/GAMWork
... ...
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
### Verify initialization, this was a successful installation. ### Verify initialization, this was a successful installation.
``` ```
gamteam@server:/Users/gamteam$ ls -l $GAMCFGDIR admin@server:/Users/admin$ ls -l $GAMCFGDIR
total 48 total 48
-rw-r-----+ 1 admin staff 553 Mar 3 09:23 client_secrets.json -rw-r-----+ 1 admin staff 553 Mar 3 09:23 client_secrets.json
-rw-r-----+ 1 admin staff 1069 Mar 3 09:23 gam.cfg -rw-r-----+ 1 admin staff 1069 Mar 3 09:23 gam.cfg
@@ -149,21 +149,21 @@ drwxr-x---+ 2 admin staff 68 Mar 3 09:23 gamcache
-rw-r-----+ 1 admin staff 5104 Mar 3 09:23 oauth2.txt -rw-r-----+ 1 admin staff 5104 Mar 3 09:23 oauth2.txt
-rw-rw-rw-+ 1 admin staff 0 Mar 3 09:23 oauth2.txt.lock -rw-rw-rw-+ 1 admin staff 0 Mar 3 09:23 oauth2.txt.lock
-rw-r-----+ 1 admin staff 2377 Mar 3 09:23 oauth2service.json -rw-r-----+ 1 admin staff 2377 Mar 3 09:23 oauth2service.json
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
If the verification looks like this, then you'll have to copy client_secrets.json and oauth2service.json manually. If the verification looks like this, then you'll have to copy client_secrets.json and oauth2service.json manually.
``` ```
gamteam@server:/Users/gamteam$ ls -l $GAMCFGDIR admin@server:/Users/admin$ ls -l $GAMCFGDIR
total 40 total 40
-rw-r-----+ 1 admin admin 1427 Nov 1 11:38 gam.cfg -rw-r-----+ 1 admin admin 1427 Nov 1 11:38 gam.cfg
drwxr-x---+ 16 admin admin 544 Nov 2 07:25 gamcache drwxr-x---+ 16 admin admin 544 Nov 2 07:25 gamcache
-rw-r--r--+ 1 admin admin 10 Nov 2 15:31 lastupdatecheck.txt -rw-r--r--+ 1 admin admin 10 Nov 2 15:31 lastupdatecheck.txt
-rw-rw-rw-+ 1 admin admin 0 Sep 19 17:28 oauth2.txt.lock -rw-rw-rw-+ 1 admin admin 0 Sep 19 17:28 oauth2.txt.lock
gamteam@server:/Users/gamteam$ cp -p $OLDGAMPATH/client_secrets.json $GAMCFGDIR/ admin@server:/Users/admin$ cp -p $OLDGAMPATH/client_secrets.json $GAMCFGDIR/
gamteam@server:/Users/gamteam$ cp -p $OLDGAMPATH/oauth2service.json $GAMCFGDIR/ admin@server:/Users/admin$ cp -p $OLDGAMPATH/oauth2service.json $GAMCFGDIR/
gamteam@server:/Users/gamteam$ cp -p $OLDGAMPATH/oauth2.txt $GAMCFGDIR/ admin@server:/Users/admin$ cp -p $OLDGAMPATH/oauth2.txt $GAMCFGDIR/
gamteam@server:/Users/gamteam$ ls -l $GAMCFGDIR admin@server:/Users/admin$ ls -l $GAMCFGDIR
total 40 total 40
-rw-r-----+ 1 admin staff 553 Mar 3 09:23 client_secrets.json -rw-r-----+ 1 admin staff 553 Mar 3 09:23 client_secrets.json
-rw-r-----+ 1 admin staff 1069 Mar 3 09:23 gam.cfg -rw-r-----+ 1 admin staff 1069 Mar 3 09:23 gam.cfg
@@ -175,9 +175,9 @@ drwxr-x---+ 2 admin staff 68 Mar 3 09:23 gamcache
``` ```
### Update your project with local browser to include the additional APIs that GAM7 uses. ### Update your project with local browser to include the additional APIs that GAM7 uses.
``` ```
gamteam@server:/Users/gamteam$ gam update project admin@server:/Users/admin$ gam update project
Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) gam-project-abc-123-xyz? gamteam@domain.com Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) gam-project-abc-123-xyz? admin@domain.com
Your browser has been opened to visit: Your browser has been opened to visit:
@@ -205,14 +205,14 @@ Enable 3 APIs
API: groupsmigration.googleapis.com, Enabled (2/3) API: groupsmigration.googleapis.com, Enabled (2/3)
API: sheets.googleapis.com, Enabled (3/3) API: sheets.googleapis.com, Enabled (3/3)
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
### Update your project without local browser (Google Cloud Shell for instance) to include the additional APIs that GAM7 uses ### Update your project without local browser (Google Cloud Shell for instance) to include the additional APIs that GAM7 uses
``` ```
gamteam@server:/Users/gamteam$ gam config no_browser true save admin@server:/Users/admin$ gam config no_browser true save
gamteam@server:/Users/gamteam$ gam update project admin@server:/Users/admin$ gam update project
Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) gam-project-abc-123-xyz? gamteam@domain.com Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) gam-project-abc-123-xyz? admin@domain.com
Go to the following link in a browser on other computer: Go to the following link in a browser on other computer:
@@ -239,7 +239,7 @@ Enable 3 APIs
API: groupsmigration.googleapis.com, Enabled (2/3) API: groupsmigration.googleapis.com, Enabled (2/3)
API: sheets.googleapis.com, Enabled (3/3) API: sheets.googleapis.com, Enabled (3/3)
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
### Enable GAM7 client access ### Enable GAM7 client access
@@ -249,16 +249,17 @@ You select a list of scopes, GAM uses a browser to get final authorization from
writes the credentials into the file oauth2.txt. writes the credentials into the file oauth2.txt.
``` ```
gamteam@server:/Users/gamteam$ rm -f /Users/gamteam/GAMConfig/oauth2.txt admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt
gamteam@server:/Users/gamteam$ gam version admin@server:/Users/admin$ gam version
GAM 7.39.08 - https://github.com/GAM-team/GAM - pyinstaller WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
GAM 7.33.03 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.4 64-bit final Python 3.14.2 64-bit final
macOS Tahoe 26.4 arm64 macOS Tahoe 26.2 x86_64
Path: /Users/gamteam/bin/gam7 Path: /Users/admin/bin/gam7
Config File: /Users/gamteam/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
gamteam@server:/Users/gamteam$ gam oauth create admin@server:/Users/admin$ gam oauth create
[*] 0) Calendar API (supports readonly) [*] 0) Calendar API (supports readonly)
[*] 1) Chrome Browser Cloud Management API (supports readonly) [*] 1) Chrome Browser Cloud Management API (supports readonly)
@@ -325,7 +326,7 @@ Continue to authorization by entering a 'c'
Please enter 0-50[a|r] or s|u|e|c: c Please enter 0-50[a|r] or s|u|e|c: c
Enter your Google Workspace admin email address? gamteam@domain.com Enter your Google Workspace admin email address? admin@domain.com
Go to the following link in a browser on this computer or on another computer: Go to the following link in a browser on this computer or on another computer:
@@ -337,13 +338,13 @@ click the Allow button, paste "Unable to connect" URL from other computer (only
Enter verification code or paste "Unable to connect" URL from other computer (only URL data up to &scope required): Enter verification code or paste "Unable to connect" URL from other computer (only URL data up to &scope required):
The authentication flow has completed. The authentication flow has completed.
Client OAuth2 File: /Users/gamteam/GAMConfig/oauth2.txt, Created Client OAuth2 File: /Users/admin/GAMConfig/oauth2.txt, Created
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
### Enable GAM7 service account access. ### Enable GAM7 service account access.
``` ```
gamteam@server:/Users/gamteam$ gam user gamteam@domain.com update serviceaccount admin@server:/Users/admin$ gam user admin@domain.com update serviceaccount
[*] 0) AlertCenter API [*] 0) AlertCenter API
[*] 1) Analytics API - read only [*] 1) Analytics API - read only
[*] 2) Analytics Admin API - read only [*] 2) Analytics Admin API - read only
@@ -407,7 +408,7 @@ Service Account Private Key Authentication
Authentication PASS Authentication PASS
Service Account Private Key age; Google recommends rotating keys on a routine basis Service Account Private Key age; Google recommends rotating keys on a routine basis
Service Account Private Key age: 1 day WARN Service Account Private Key age: 1 day WARN
Domain-wide Delegation authentication:, User: gamteam@domain.com, Scopes: 38 Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 38
https://mail.google.com/ PASS (1/38) https://mail.google.com/ PASS (1/38)
https://sites.google.com/feeds FAIL (2/38) https://sites.google.com/feeds FAIL (2/38)
https://www.googleapis.com/auth/analytics.readonly FAIL (3/38) https://www.googleapis.com/auth/analytics.readonly FAIL (3/38)
@@ -458,7 +459,7 @@ Click AUTHORIZE
When the box closes you're done When the box closes you're done
After authorizing it may take some time for this test to pass so wait a few moments and then try this command again. After authorizing it may take some time for this test to pass so wait a few moments and then try this command again.
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
The link shown in the error message should take you directly to the authorization screen. The link shown in the error message should take you directly to the authorization screen.
If not, make sure that you are logged in as a domain admin, then re-enter the link. If not, make sure that you are logged in as a domain admin, then re-enter the link.
@@ -468,7 +469,7 @@ If not, make sure that you are logged in as a domain admin, then re-enter the li
Wait a moment and then perform the following command; it it still fails, wait a bit longer, it can sometimes take serveral minutes Wait a moment and then perform the following command; it it still fails, wait a bit longer, it can sometimes take serveral minutes
for the authorization to complete. for the authorization to complete.
``` ```
gamteam@server:/Users/gamteam$ gam user gamteam@domain.com check serviceaccount admin@server:/Users/admin$ gam user admin@domain.com check serviceaccount
System time status System time status
Your system time differs from admin.googleapis.com by less than 1 second PASS Your system time differs from admin.googleapis.com by less than 1 second PASS
@@ -476,7 +477,7 @@ Service Account Private Key Authentication
Authentication PASS Authentication PASS
Service Account Private Key age; Google recommends rotating keys on a routine basis Service Account Private Key age; Google recommends rotating keys on a routine basis
Service Account Private Key age: 1 day WARN Service Account Private Key age: 1 day WARN
Domain-wide Delegation authentication:, User: gamteam@domain.com, Scopes: 38 Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 38
https://mail.google.com/ PASS (1/38) https://mail.google.com/ PASS (1/38)
https://sites.google.com/feeds PASS (2/38) https://sites.google.com/feeds PASS (2/38)
https://www.googleapis.com/auth/analytics.readonly PASS (3/38) https://www.googleapis.com/auth/analytics.readonly PASS (3/38)
@@ -518,14 +519,14 @@ Domain-wide Delegation authentication:, User: gamteam@domain.com, Scopes: 38
All scopes PASSED! All scopes PASSED!
Service Account Client name: SVCACCTID is fully authorized. Service Account Client name: SVCACCTID is fully authorized.
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
### Update gam.cfg with some basic values ### Update gam.cfg with some basic values
* `customer_id` - Having this data keeps Gam from having to make extra API calls * `customer_id` - Having this data keeps Gam from having to make extra API calls
* `domain` - This allows you to omit the domain portion of email addresses * `domain` - This allows you to omit the domain portion of email addresses
* `timezone local` - Gam will convert all UTC times to your local timezone * `timezone local` - Gam will convert all UTC times to your local timezone
``` ```
gamteam@server:/Users/gamteam$ gam info domain admin@server:/Users/admin$ gam info domain
Customer ID: C01234567 Customer ID: C01234567
Primary Domain: domain.com Primary Domain: domain.com
Customer Creation Time: 2007-06-06T15:47:55.444Z Customer Creation Time: 2007-06-06T15:47:55.444Z
@@ -533,8 +534,8 @@ Primary Domain Verified: True
Default Language: en Default Language: en
... ...
gamteam@server:/Users/gamteam$ gam config customer_id C01234567 domain domain.com timezone local save verify admin@server:/Users/admin$ gam config customer_id C01234567 domain domain.com timezone local save verify
Config File: /Users/gamteam/GAMConfig/gam.cfg, Saved Config File: /Users/admin/GAMConfig/gam.cfg, Saved
Section: DEFAULT Section: DEFAULT
activity_max_results = 100 activity_max_results = 100
admin_email = '' admin_email = ''
@@ -545,18 +546,18 @@ Section: DEFAULT
bail_on_internal_error_tries = 2 bail_on_internal_error_tries = 2
batch_size = 50 batch_size = 50
cacerts_pem = '' cacerts_pem = ''
cache_dir = /Users/gamteam/GAMConfig/gamcache cache_dir = /Users/admin/GAMConfig/gamcache
cache_discovery_only = true cache_discovery_only = true
channel_customer_id = '' channel_customer_id = ''
charset = utf-8 charset = utf-8
chat_max_results = 100 chat_max_results = 100
classroom_max_results = 0 classroom_max_results = 0
client_secrets_json = client_secrets.json ; /Users/gamteam/GAMConfig/client_secrets.json client_secrets_json = client_secrets.json ; /Users/admin/GAMConfig/client_secrets.json
clock_skew_in_seconds = 10 clock_skew_in_seconds = 10
cmdlog = '' cmdlog = ''
cmdlog_max_backups = 5 cmdlog_max_backups = 5
cmdlog_max_kilo_bytes = 1000 cmdlog_max_kilo_bytes = 1000
config_dir = /Users/gamteam/GAMConfig config_dir = /Users/admin/GAMConfig
contact_max_results = 100 contact_max_results = 100
csv_input_column_delimiter = , csv_input_column_delimiter = ,
csv_input_no_escape_char = true csv_input_no_escape_char = true
@@ -573,7 +574,6 @@ Section: DEFAULT
csv_output_header_filter = '' csv_output_header_filter = ''
csv_output_header_force = '' csv_output_header_force = ''
csv_output_header_order = '' csv_output_header_order = ''
csv_output_header_required = ''
csv_output_line_terminator = lf csv_output_line_terminator = lf
csv_output_no_escape_char = false csv_output_no_escape_char = false
csv_output_quote_char = '"' csv_output_quote_char = '"'
@@ -593,7 +593,7 @@ Section: DEFAULT
developer_preview_apis = '' developer_preview_apis = ''
device_max_results = 200 device_max_results = 200
domain = domain.com domain = domain.com
drive_dir = /Users/gamteam/GAMWork drive_dir = /Users/admin/GAMWork
drive_max_results = 1000 drive_max_results = 1000
email_batch_size = 50 email_batch_size = 50
enable_dasa = false enable_dasa = false
@@ -621,8 +621,8 @@ Section: DEFAULT
no_verify_ssl = false no_verify_ssl = false
num_tbatch_threads = 2 num_tbatch_threads = 2
num_threads = 5 num_threads = 5
oauth2_txt = oauth2.txt ; /Users/gamteam/GAMConfig/oauth2.txt oauth2_txt = oauth2.txt ; /Users/admin/GAMConfig/oauth2.txt
oauth2service_json = oauth2service.json ; /Users/gamteam/GAMConfig/oauth2service.json oauth2service_json = oauth2service.json ; /Users/admin/GAMConfig/oauth2service.json
output_dateformat = '' output_dateformat = ''
output_timeformat = '' output_timeformat = ''
people_max_results = 100 people_max_results = 100
@@ -673,12 +673,12 @@ Section: DEFAULT
user_max_results = 500 user_max_results = 500
user_service_account_access_only = false user_service_account_access_only = false
gamteam@server:/Users/gamteam$ admin@server:/Users/admin$
``` ```
## Windows ## Windows
In these examples, your Google Super admin is shown as gamteam@domain.com; replace with the In these examples, your Google Super admin is shown as admin@domain.com; replace with the
actual email adddress. actual email adddress.
This example assumes that GAM7 has been installed in C:\GAM7; if you've installed This example assumes that GAM7 has been installed in C:\GAM7; if you've installed
@@ -797,7 +797,6 @@ Section: DEFAULT
csv_output_header_filter = '' csv_output_header_filter = ''
csv_output_header_force = '' csv_output_header_force = ''
csv_output_header_order = '' csv_output_header_order = ''
csv_output_header_required = ''
csv_output_line_terminator = lf csv_output_line_terminator = lf
csv_output_no_escape_char = false csv_output_no_escape_char = false
csv_output_quote_char = '"' csv_output_quote_char = '"'
@@ -964,7 +963,7 @@ C:\>dir %GAMCFGDIR%
``` ```
C:\>gam update project C:\>gam update project
Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) gam-project-abc-123-xyz? gamteam@domain.com Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) gam-project-abc-123-xyz? admin@domain.com
Your browser has been opened to visit: Your browser has been opened to visit:
@@ -996,7 +995,7 @@ C:\>
C:\>gam config no_browser true save C:\>gam config no_browser true save
C:\>gam update project C:\>gam update project
Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) gam-project-abc-123-xyz? gamteam@domain.com Enter your Google Workspace admin or GCP project manager email address authorized to manage project(s) gam-project-abc-123-xyz? admin@domain.com
Go to the following link in a browser on other computer: Go to the following link in a browser on other computer:
@@ -1034,9 +1033,10 @@ writes the credentials into the file oauth2.txt.
``` ```
C:\>del C:\GAMConfig\oauth2.txt C:\>del C:\GAMConfig\oauth2.txt
C:\>gam version C:\>gam version
GAM 7.39.08 - https://github.com/GAM-team/GAM - pythonsource WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
GAM 7.33.03 - https://github.com/GAM-team/GAM - pythonsource
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.4 64-bit final Python 3.14.2 64-bit final
Windows 11 10.0.26200 AMD64 Windows 11 10.0.26200 AMD64
Path: C:\GAM7 Path: C:\GAM7
Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
@@ -1108,7 +1108,7 @@ Continue to authorization by entering a 'c'
Please enter 0-50[a|r] or s|u|e|c: c Please enter 0-50[a|r] or s|u|e|c: c
Enter your Google Workspace admin email address? gamteam@domain.com Enter your Google Workspace admin email address? admin@domain.com
Go to the following link in a browser on this computer or on another computer: Go to the following link in a browser on this computer or on another computer:
@@ -1127,7 +1127,7 @@ C:\>
### Enable GAM7 service account access. ### Enable GAM7 service account access.
``` ```
C:\>gam user gamteam@domain.com update serviceaccount C:\>gam user admin@domain.com update serviceaccount
[*] 0) AlertCenter API [*] 0) AlertCenter API
[*] 1) Analytics API - read only [*] 1) Analytics API - read only
[*] 2) Analytics Admin API - read only [*] 2) Analytics Admin API - read only
@@ -1191,7 +1191,7 @@ Service Account Private Key Authentication
Authentication PASS Authentication PASS
Service Account Private Key age; Google recommends rotating keys on a routine basis Service Account Private Key age; Google recommends rotating keys on a routine basis
Service Account Private Key age: 1 day WARN Service Account Private Key age: 1 day WARN
Domain-wide Delegation authentication:, User: gamteam@domain.com, Scopes: 38 Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 38
https://mail.google.com/ PASS (1/38) https://mail.google.com/ PASS (1/38)
https://sites.google.com/feeds FAIL (2/38) https://sites.google.com/feeds FAIL (2/38)
https://www.googleapis.com/auth/analytics.readonly FAIL (3/38) https://www.googleapis.com/auth/analytics.readonly FAIL (3/38)
@@ -1252,14 +1252,14 @@ If not, make sure that you are logged in as a domain admin, then re-enter the li
Wait a moment and then perform the following command; it it still fails, wait a bit longer, it can sometimes take serveral minutes Wait a moment and then perform the following command; it it still fails, wait a bit longer, it can sometimes take serveral minutes
for the authorization to complete. for the authorization to complete.
``` ```
C:\>gam user gamteam@domain.com check serviceaccount C:\>gam user admin@domain.com check serviceaccount
System time status System time status
Your system time differs from admin.googleapis.com by less than 1 second PASS Your system time differs from admin.googleapis.com by less than 1 second PASS
Service Account Private Key Authentication Service Account Private Key Authentication
Authentication PASS Authentication PASS
Service Account Private Key age; Google recommends rotating keys on a routine basis Service Account Private Key age; Google recommends rotating keys on a routine basis
Service Account Private Key age: 1 day WARN Service Account Private Key age: 1 day WARN
Domain-wide Delegation authentication:, User: gamteam@domain.com, Scopes: 38 Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 38
https://mail.google.com/ PASS (1/38) https://mail.google.com/ PASS (1/38)
https://sites.google.com/feeds PASS (2/38) https://sites.google.com/feeds PASS (2/38)
https://www.googleapis.com/auth/analytics.readonly PASS (3/38) https://www.googleapis.com/auth/analytics.readonly PASS (3/38)
@@ -1357,7 +1357,6 @@ Section: DEFAULT
csv_output_header_filter = '' csv_output_header_filter = ''
csv_output_header_force = '' csv_output_header_force = ''
csv_output_header_order = '' csv_output_header_order = ''
csv_output_header_required = ''
csv_output_line_terminator = lf csv_output_line_terminator = lf
csv_output_no_escape_char = false csv_output_no_escape_char = false
csv_output_quote_char = '"' csv_output_quote_char = '"'

View File

@@ -41,7 +41,6 @@
| License Name | License SKU | Abbreviation | | License Name | License SKU | Abbreviation |
|--------------|-------------|---------------| |--------------|-------------|---------------|
| AI Expanded Access | 1010470009 | aiexpandedaccess |
| AI Meetings and Messaging | 1010470007 | aimeetingsandmessaging | | AI Meetings and Messaging | 1010470007 | aimeetingsandmessaging |
| AI Security | 1010470006 | aisecurity | | AI Security | 1010470006 | aisecurity |
| AppSheet Core | 1010380001 | appsheetcore | | AppSheet Core | 1010380001 | appsheetcore |
@@ -62,7 +61,7 @@
| G Suite Lite | Google-Apps-Lite | gsuitelite | | G Suite Lite | Google-Apps-Lite | gsuitelite |
| Gemini Business | 1010470003 | geminibiz | Gemini Business | 1010470003 | geminibiz
| Gemini Education Premium | 1010470005 | geminiedupremium | | Gemini Education Premium | 1010470005 | geminiedupremium |
| Gemini Enterprise - Legacy | 1010470001 | geminient | duetai | | Gemini Enterprise | 1010470001 | geminient | duetai |
| Google AI Pro for Education | 1010470004 | gaiproedu | | Google AI Pro for Education | 1010470004 | gaiproedu |
| Google AI Ultra for Business | 1010470008 | geminiultra | | Google AI Ultra for Business | 1010470008 | geminiultra |
| Google Apps Message Security | Google-Apps-For-Postini | postini | | Google Apps Message Security | Google-Apps-For-Postini | postini |
@@ -153,7 +152,6 @@
4tb | drive4tb | googledrivestorage4tb | Google-Drive-storage-4TB | 4tb | drive4tb | googledrivestorage4tb | Google-Drive-storage-4TB |
8tb | drive8tb | googledrivestorage8tb | Google-Drive-storage-8TB | 8tb | drive8tb | googledrivestorage8tb | Google-Drive-storage-8TB |
16tb | drive16tb | googledrivestorage16tb | Google-Drive-storage-16TB | 16tb | drive16tb | googledrivestorage16tb | Google-Drive-storage-16TB |
aiexpandedaccess | 1010470009 | AI Expanded Access |
aimeetingsandmessaging | 1010470007 | AI Meetings and Messaging | aimeetingsandmessaging | 1010470007 | AI Meetings and Messaging |
aisecurity | 1010470006 | AI Security | aisecurity | 1010470006 | AI Security |
appsheetcore | 1010380001 | AppSheet Core | appsheetcore | 1010380001 | AppSheet Core |
@@ -172,7 +170,7 @@
gaiproedu | geminiedu | 1010470004 | Google AI Pro for Education | gaiproedu | geminiedu | 1010470004 | Google AI Pro for Education |
geminibiz | 1010470003 | Gemini Business | geminibiz | 1010470003 | Gemini Business |
geminiedupremium| 1010470005 | Gemini Education Premium | geminiedupremium| 1010470005 | Gemini Education Premium |
geminient| duetai | 1010470001 | Gemini Enterprise - Legacy| geminient| duetai | 1010470001 | Gemini Enterprise |
geminiultra | 1010470008 | Google AI Ultra for Business | geminiultra | 1010470008 | Google AI Ultra for Business |
gsuitebasic | gafb | gafw | basic | Google-Apps-For-Business | gsuitebasic | gafb | gafw | basic | Google-Apps-For-Business |
gsuitebusiness | gau | gsb | unlimited | Google-Apps-Unlimited | gsuitebusiness | gau | gsb | unlimited | Google-Apps-Unlimited |

View File

@@ -56,7 +56,6 @@ The only `<VariableNames>` recognized in this `<Section>` are:
* `csv_output_header_drop_filter` * `csv_output_header_drop_filter`
* `csv_output_header_force` * `csv_output_header_force`
* `csv_output_header_order` * `csv_output_header_order`
* `csv_output_header_required`
* `csv_output_row_filter` * `csv_output_row_filter`
* `csv_output_row_filter_mode` * `csv_output_row_filter_mode`
* `csv_output_row_drop_filter` * `csv_output_row_drop_filter`

View File

@@ -1,7 +1,6 @@
# Organizational Units # Organizational Units
- [API documentation](#api-documentation) - [API documentation](#api-documentation)
- [Definitions](#definitions) - [Definitions](#definitions)
- [Special character issues](#special-character-issues)
- [Special quoting](#special-quoting) - [Special quoting](#special-quoting)
- [Manage organizational units](#manage-organizational-units) - [Manage organizational units](#manage-organizational-units)
- [Add users to an organizational unit](#add-users-to-an-organizational-unit) - [Add users to an organizational unit](#add-users-to-an-organizational-unit)
@@ -51,15 +50,6 @@ For `<UserTypeEntity>`, see: [Collections of Users](Collections-Of-Users)
For `<CrOSTypeEntity>`, see: [Collections of ChromeOS Devices](Collections-of-ChromeOS-Devices) For `<CrOSTypeEntity>`, see: [Collections of ChromeOS Devices](Collections-of-ChromeOS-Devices)
## Special character issues
If an organizational unit name contains a `#` or a `+`, these commands will not work due to a bug
that Google does not plan to fix.
```
gam update org|ou <OrgUnitPath>
gam delete org|ou <OrgUnitPath>
gam info org|ou <OrgUnitPath>
```
## Special quoting ## Special quoting
You specify a single organizational unit with `org <OrgUnitPath>` and a list of organizationsl units with `orgs <OrgUnitList>`. You specify a single organizational unit with `org <OrgUnitPath>` and a list of organizationsl units with `orgs <OrgUnitList>`.
As organizational unit paths can contain spaces, some care must be used when entering `<OrgUnitPath>` and `<OrgUnitList>`. As organizational unit paths can contain spaces, some care must be used when entering `<OrgUnitPath>` and `<OrgUnitList>`.

View File

@@ -14,17 +14,17 @@
## API documentation ## API documentation
* [Activity Data Sources](https://support.google.com/a/answer/11482175) * [Activity Data Sources](https://support.google.com/a/answer/11482175)
Changes starting 2025-10-29.
* [Reports API - Admin log event changes](https://support.google.com/a/answer/16601511)
Changes starting 2025-12-20 Changes starting 2025-12-20
* [Reports API - Admin log enhancements](https://workspaceupdates.googleblog.com/2025/12/google-workspace-audit-log-api.html) * [Reports API - Admin log enhancements](https://workspaceupdates.googleblog.com/2025/12/google-workspace-audit-log-api.html)
Changes starting 2026-02-17. These pages show event/parameter names; scroll down in the left column to: Reports.
* [Reports API - Admin log event changes](https://support.google.com/a/answer/16601511)
These pages show event/parameter names: * [Reports API - Activities](https://developers.google.com/admin-sdk/reports/v1/reference/activities)
* [Reports API - Admin Activities](https://developers.google.com/workspace/admin/reports/v1/appendix/activity/admin-event-names) * [Reports API - Customer Usage](https://developers.google.com/admin-sdk/reports/v1/reference/customerUsageReports)
* [Reports API - Activities](https://developers.google.com/workspace/admin/reports/v1/appendix/activity/access-transparency) * [Reports API - User Usage](https://developers.google.com/admin-sdk/reports/v1/reference/userUsageReport)
* [Reports API - Customer Usage](https://developers.google.com/workspace/admin/reports/v1/appendix/usage/customer)
* [Reports API - User Usage](https://developers.google.com/workspace/admin/reports/v1/appendix/usage/user)
## Definitions ## Definitions
``` ```
@@ -99,9 +99,6 @@ gam report <ActivityApplicationName> [todrive <ToDriveAttribute>*]
[event|events <EventNameList>] [ip <String>] [event|events <EventNameList>] [ip <String>]
[gmaileventtypes <NumberRangeList>] [gmaileventtypes <NumberRangeList>]
[groupidfilter <String>] [resourcedetailsfilter <String>] [groupidfilter <String>] [resourcedetailsfilter <String>]
[networkinfofilter <String>] [statusfilter <String>]
[applicationinfofilter <String>] [includesensitivedata]
[notimesort]
[maxactivities <Number>] [maxevents <Number>] [maxresults <Number>] [maxactivities <Number>] [maxevents <Number>] [maxresults <Number>]
[countsonly [bydate|summary] [eventrowfilter]] [countsonly [bydate|summary] [eventrowfilter]]
(addcsvdata <FieldName> <String>)* [shownoactivities] (addcsvdata <FieldName> <String>)* [shownoactivities]
@@ -156,15 +153,6 @@ Limit to those users that are a member of at least one of a list of groups.
Limit based on resource details. Limit based on resource details.
* `resourcedetailsfilter <String>` - See: https://developers.google.com/workspace/admin/reports/reference/rest/v1/activities/list#query-parameters * `resourcedetailsfilter <String>` - See: https://developers.google.com/workspace/admin/reports/reference/rest/v1/activities/list#query-parameters
Limit based on 'regionCode`.
* `networkinfofilter <String>` - Format: 'regionCode="IN"'
Limit based on `statusCode`.
* `statusfilter <String>` - Format: 'statusCode="200"'
Limit based on `oAuthClientId`.
* `applicationinfofilter <String>` - Format: 'oAuthClientId="clientId"'
You can use `config csv_output_row_filter` to filter the events if the API filter can't produce the results you want. You can use `config csv_output_row_filter` to filter the events if the API filter can't produce the results you want.
Limit to a list of specific events. Limit to a list of specific events.
@@ -188,9 +176,6 @@ show the most recent activity/event; this can be useful when reporting drive act
Add additional columns of data from the command line to the output. Add additional columns of data from the command line to the output.
* `addcsvdata <FieldName> <String>` * `addcsvdata <FieldName> <String>`
By default, a reverse chronological sort is performed on all rows across multiple users and/or event names;
this is consistent with the behavior in the Admin console. Use option `notimesort` to suppress this sort.
Display a row with a key value of `NoActivities` when there are no activities to report. Display a row with a key value of `NoActivities` when there are no activities to report.
* `shownoactivities` * `shownoactivities`

View File

@@ -44,7 +44,6 @@ Thanks to Duncan Isaksen-Loxton for a script to help manage multiple domains.
4tb | drive4tb | googledrivestorage4tb | Google-Drive-storage-4TB | 4tb | drive4tb | googledrivestorage4tb | Google-Drive-storage-4TB |
8tb | drive8tb | googledrivestorage8tb | Google-Drive-storage-8TB | 8tb | drive8tb | googledrivestorage8tb | Google-Drive-storage-8TB |
16tb | drive16tb | googledrivestorage16tb | Google-Drive-storage-16TB | 16tb | drive16tb | googledrivestorage16tb | Google-Drive-storage-16TB |
aiexpandedaccess | 1010470009 | AI Expanded Access |
aimeetingsandmessaging | 1010470007 | AI Meetings and Messaging | aimeetingsandmessaging | 1010470007 | AI Meetings and Messaging |
aisecurity | 1010470006 | AI Security | aisecurity | 1010470006 | AI Security |
appsheetcore | 1010380001 | AppSheet Core | appsheetcore | 1010380001 | AppSheet Core |
@@ -62,7 +61,7 @@ Thanks to Duncan Isaksen-Loxton for a script to help manage multiple domains.
geminibiz | 1010470003 | Gemini Business | geminibiz | 1010470003 | Gemini Business |
geminiedu | 1010470004 | Gemini Education | geminiedu | 1010470004 | Gemini Education |
geminiedupremium| 1010470005 | Gemini Education Premium | geminiedupremium| 1010470005 | Gemini Education Premium |
geminient| duetai | 1010470001 | Gemini Enterprise - Legacy | geminient| duetai | 1010470001 | Gemini Enterprise |
gsuitebasic | gafb | gafw | basic | Google-Apps-For-Business | gsuitebasic | gafb | gafw | basic | Google-Apps-For-Business |
gsuitebusiness | gau | gsb | unlimited | Google-Apps-Unlimited | gsuitebusiness | gau | gsb | unlimited | Google-Apps-Unlimited |
gsuitebusinessarchived | gsbau | businessarchived | 1010340002 | Google Workspace Business - Archived User | gsuitebusinessarchived | gsbau | businessarchived | 1010340002 | Google Workspace Business - Archived User |

View File

@@ -377,9 +377,6 @@ features "CameraSet"
features "'Laptop Cart'" features "'Laptop Cart'"
features "CameraSet,'Laptop Cart'" features "CameraSet,'Laptop Cart'"
``` ```
For quoting rules, see: [List Quoting Rules](Command-Line-Parsing)
## Manage buildings ## Manage buildings
When creating a building, at a minimum you must enter `address|addresslines` and `country|regioncode`. When creating a building, at a minimum you must enter `address|addresslines` and `country|regioncode`.

View File

@@ -13,7 +13,6 @@
- [Send an email to users](#send-an-email-to-users) - [Send an email to users](#send-an-email-to-users)
- [Simple `replace <Tag> <String>` processing](Tag-Replace) - [Simple `replace <Tag> <String>` processing](Tag-Replace)
- [Example](#example) - [Example](#example)
- [Conversation mode](#conversation-mode)
## Note ## Note
Thanks to @bousquf for the following enhancement. You want to send a message from an authorized group Thanks to @bousquf for the following enhancement. You want to send a message from an authorized group
@@ -215,14 +214,14 @@ Configure it at Admin Console > Apps > Google Workspace > Gmail > Routing > SMTP
gam sendemail [recipient|to] <RecipientEntity> gam sendemail [recipient|to] <RecipientEntity>
[from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>] [from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage] [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
[subject <String>] [<MessageContent>] [subject <String>]
[<MessageContent>]
(replace <Tag> <String>)* (replace <Tag> <String>)*
(replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)* (replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
[html [<Boolean>]] (attach <FileName> [charset <Charset>])* [html [<Boolean>]] (attach <FileName> [charset <Charset>])*
(embedimage <FileName> <String>)* (embedimage <FileName> <String>)*
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>] [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)* (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
[threadid <String>]
``` ```
By default, emails will be sent from the admin user named in oauth2.txt, override this with the `from <EmailAddress>` option. By default, emails will be sent from the admin user named in oauth2.txt, override this with the `from <EmailAddress>` option.
@@ -273,14 +272,14 @@ You can specify additional recipients, e.g., help desk personnel.
gam sendemail [recipient|to] <RecipientEntity> [from <EmailAddress>] gam sendemail [recipient|to] <RecipientEntity> [from <EmailAddress>]
[replyto <EmailAddress>] [replyto <EmailAddress>]
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage] [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
[subject <String>] [<MessageContent>] [subject <String>]
[<MessageContent>]
(replace <Tag> <String>)* (replace <Tag> <String>)*
(replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)* (replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
[html [<Boolean>]] (attach <FileName> [charset <Charset>])* [html [<Boolean>]] (attach <FileName> [charset <Charset>])*
(embedimage <FileName> <String>)* (embedimage <FileName> <String>)*
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>] [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)* (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
[threadid <String>]
``` ```
By default, emails will be sent from the admin user named in oauth2.txt, override this with the `from <EmailAddress>` option. By default, emails will be sent from the admin user named in oauth2.txt, override this with the `from <EmailAddress>` option.
@@ -354,14 +353,14 @@ gam csv Users.csv gam sendemail "~personal" subject "Your new #domain# account`
gam <UserTypeEntity> sendemail recipient|to <RecipientEntity> gam <UserTypeEntity> sendemail recipient|to <RecipientEntity>
[replyto <EmailAddress>] [replyto <EmailAddress>]
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage] [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
[subject <String>] [<MessageContent>] [subject <String>]
[<MessageContent>]
(replace <Tag> <String>)* (replace <Tag> <String>)*
(replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)* (replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
[html [<Boolean>]] (attach <FileName> [charset <Charset>])* [html [<Boolean>]] (attach <FileName> [charset <Charset>])*
(embedimage <FileName> <String>)* (embedimage <FileName> <String>)*
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>] [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)* (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
[threadid <String>]
``` ```
Emails will be sent from the users in `<UserTypeEntity>` to the recipients in `<RecipientEntity>`. Emails will be sent from the users in `<UserTypeEntity>` to the recipients in `<RecipientEntity>`.
@@ -396,14 +395,14 @@ Your command line will have: `embedimage file1.jpg image1 embedimage file2.jpg i
gam <UserTypeEntity> sendemail from <EmailAddress> gam <UserTypeEntity> sendemail from <EmailAddress>
[replyto <EmailAddress>] [replyto <EmailAddress>]
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage] [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
[subject <String>] [<MessageContent>] [subject <String>]
[<MessageContent>]
(replace <Tag> <String>)* (replace <Tag> <String>)*
(replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)* (replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
[html [<Boolean>]] (attach <FileName> [charset <Charset>])* [html [<Boolean>]] (attach <FileName> [charset <Charset>])*
(embedimage <FileName> <String>)* (embedimage <FileName> <String>)*
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>] [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)* (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
[threadid <String>]
``` ```
Emails will be sent to the users in `<UserTypeEntity>`. Emails will be sent to the users in `<UserTypeEntity>`.
@@ -452,42 +451,3 @@ $ gam csv UserEmail.csv gam user "~User" sendemail to "~To" subject "~Subject" t
User: user1@domain.com, Send Email to 1 Recipient User: user1@domain.com, Send Email to 1 Recipient
Recipient: user2@domain.com, Message: Test, Email Sent: 17677cdfbe1146f4 Recipient: user2@domain.com, Message: Test, Email Sent: 17677cdfbe1146f4
``` ```
## Conversation mode
To reply to an email and have Gmail recognize it in conversation mode for the original sender, you have to specify the
`References` and `In-Reply-to` headers with the `RFC822 Message ID` from the original message
and the `subject` from the original message.
```
gam user recipient@domain.com sendemail to sender@domain.com references "<CAAMabc...XYZQ@mail.gmail.com>" in-reply-to "<CAAMabc...XYZQ@mail.gmail.com>" subject "Re: Original subject" textmessage "Reply text"
```
If you want to have Gmail recognize the reply in conversation mode in the Sent folder of the original recipient,
you must include `threadid <String>`; you can get the 'threadId` with:
```
gam user recipient@domain.com show threads query "rfc822MsgId:<CAAMabc...XYZQ@mail.gmail.com>"
Getting all Messages that match query ((rfc822MsgId:<CAAMabc...XYZQ@mail.gmail.com>)) for recipient@domain.com
Got 1 Message that matched query ((rfc822MsgId:<CAAMabc...XYZQ@mail.gmail.com>)) for recipient@domain.com...
User: recipient@domain.com, Show 1 Thread
Thread: 19cfd414fe48430d
Message: 19cfd414fe48430d
...
gam user recipient@domain.com sendemail to sender@domain.com references "<CAAMabc...XYZQ@mail.gmail.com>" in-reply-to "<CAAMabc...XYZQ@mail.gmail.com>" subject "Re: Original subject" textmessage "Reply text" threadid 19cfd414fe48430d
```
As of version 7.36.03, GAM has a command to simplify this process.
```
gam <UserTypeEntity> sendreply
(((query <QueryGmail> [querytime<String> <Date>]*) [or|and])+) | (ids <MessageIDEntity>)
[replyto <EmailAddress>]
[subject <String>] [<MessageContent>] [html [<Boolean>]]
(attach <FileName> [charset <CharSet>])*
(embedimage <FileName> <String>)*
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
gam user recipient@domain.com sendreply query "rfc822MsgId:<CAAMabc...XYZQ@mail.gmail.com>" textmessage "Reply text"
```

View File

@@ -14,7 +14,6 @@
- [Change Shared Drive visibility](#change-shared-drive-visibility) - [Change Shared Drive visibility](#change-shared-drive-visibility)
- [Display Shared Drives](#display-shared-drives) - [Display Shared Drives](#display-shared-drives)
- [Display Shared Drive Counts](#display-shared-drive-counts) - [Display Shared Drive Counts](#display-shared-drive-counts)
- [Display Shared Drive Storage Info](#display-shared-drive-storage-info)
- [Display List of Shared Drives in an Organizational Unit](#display-list-of-shared-drives-in-an-organizational-unit) - [Display List of Shared Drives in an Organizational Unit](#display-list-of-shared-drives-in-an-organizational-unit)
- [Display Count of Shared Drives in an Organizational Unit](#display-count-of-shared-drives-in-an-organizational-unit) - [Display Count of Shared Drives in an Organizational Unit](#display-count-of-shared-drives-in-an-organizational-unit)
- [Display Shared Drive Organizers](#display-shared-drive-organizers) - [Display Shared Drive Organizers](#display-shared-drive-organizers)
@@ -172,7 +171,7 @@
withlink withlink
<DrivePermissionsFieldNameList> ::= "<DrivePermissionsFieldName>(,<DrivePermissionsFieldName>)*" <DrivePermissionsFieldNameList> ::= "<DrivePermissionsFieldName>(,<DrivePermissionsFieldName>)*"
<QuerySharedDrive> ::= <String> See: https://developers.google.com/workspace/drive/api/guides/search-shareddrives <QueryTeamDrive> ::= <String> See: https://developers.google.com/drive/api/v3/search-parameters
<SharedDriveACLRole> ::= <SharedDriveACLRole> ::=
manager|organizer|owner| manager|organizer|owner|
contentmanager|fileorganizer| contentmanager|fileorganizer|
@@ -184,8 +183,8 @@
<SharedDriveName> ::= <String> <SharedDriveName> ::= <String>
<SharedDriveEntity> ::= <SharedDriveEntity> ::=
<SharedDriveID>| <SharedDriveID>|
(shareddriveid <SharedDriveID>)|(shareddriveid:<SharedDriveID>)| (teamdriveid <SharedDriveID>)|(teamdriveid:<SharedDriveID>)|
(shareddrive <SharedDriveName>)|(shareddrive:<SharedDriveName>) (teamdrive <SharedDriveName>)|(teamdrive:<SharedDriveName>)
<SharedDriveFieldName> ::= <SharedDriveFieldName> ::=
backgroundimagefile| backgroundimagefile|
@@ -200,11 +199,11 @@
<SharedDriveFieldNameList> ::= "<SharedDriveFieldName>(,<SharedDriveFieldName>)*" <SharedDriveFieldNameList> ::= "<SharedDriveFieldName>(,<SharedDriveFieldName>)*"
<SharedDriveIDEntity> ::= <SharedDriveIDEntity> ::=
<DriveFileItem>|(shareddriveid <DriveFileItem>)|(shareddriveid:<DriveFileItem>) <DriveFileItem>|(teamdriveid <DriveFileItem>)|(teamdriveid:<DriveFileItem>)
<SharedDriveNameEntity> ::= <SharedDriveNameEntity> ::=
(shareddrive <SharedDriveName>)|(shareddrive:<SharedDriveName>) (teamdrive <SharedDriveName>)|(teamdrive:<SharedDriveName>)
<SharedDriveAdminQueryEntity> ::= <SharedDriveAdminQueryEntity> ::=
(shareddriveadminquery <QuerySharedDrive>)|(shareddriveadminquery:<QuerySharedDrive>) (teamdriveadminquery <QueryTeamDrive>)|(teamdriveadminquery:<QueryTeamDrive>)
<SharedDriveEntityAdmin> ::= <SharedDriveEntityAdmin> ::=
<SharedDriveIDEntity> | <SharedDriveIDEntity> |
@@ -328,11 +327,11 @@ When either of these options is chosen, no infomation about Shared Drive restric
To retrieve the Shared Drive ID with `returnidonly`: To retrieve the Shared Drive ID with `returnidonly`:
``` ```
Linux/MacOS Linux/MacOS
shareddriveId=$(gam create shareddrive ... returnidonly) teamDriveId=$(gam create shareddrive ... returnidonly)
Windows PowerShell Windows PowerShell
$shareddriveId = & gam create shareddrive ... returnidonly $teamDriveId = & gam create shareddrive ... returnidonly
Windows Command Prompt Windows Command Prompt
for /f "delims=" %a in ('gam create shareddrive ... returnidonly') do set shareddriveId=%a for /f "delims=" %a in ('gam create shareddrive ... returnidonly') do set teamDriveId=%a
``` ```
## Bulk Create Shared Drives ## Bulk Create Shared Drives
@@ -423,14 +422,14 @@ By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format. * `formatjson` - Display the fields in JSON format.
``` ```
gam [<UserTypeEntity>] show shareddrives gam [<UserTypeEntity>] show shareddrives
[adminaccess|asadmin] [shareddriveadminquery|query <QuerySharedDrive>] [adminaccess|asadmin] [teamdriveadminquery|query <QueryTeamDrive>]
[matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
[fields <SharedDriveFieldNameList>] [fields <SharedDriveFieldNameList>]
[showwebviewlink text|hyperlink] [showwebviewlink text|hyperlink]
[formatjson] [formatjson]
``` ```
By default, all Shared Drives are displayed; use the following options to select a subset of Shared Drives: By default, all Shared Drives are displayed; use the following options to select a subset of Shared Drives:
* `shareddriveadminquery|query <QuerySharedDrive>` - Use a query to select Shared Drives * `teamdriveadminquery|query <QueryTeamDrive>` - Use a query to select Shared Drives
* `matchname <REMatchPattern>` - Retrieve Shared Drives with names that match a pattern. * `matchname <REMatchPattern>` - Retrieve Shared Drives with names that match a pattern.
* `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected * `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected
@@ -442,14 +441,14 @@ By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format. * `formatjson` - Display the fields in JSON format.
``` ```
gam [<UserTypeEntity>] print shareddrives [todrive <ToDriveAttribute>*] gam [<UserTypeEntity>] print shareddrives [todrive <ToDriveAttribute>*]
[adminaccess|asadmin] [shareddriveadminquery|query <QuerySharedDrive>] [adminaccess|asadmin] [teamdriveadminquery|query <QueryTeamDrive>]
[matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
[fields <SharedDriveFieldNameList>] [fields <SharedDriveFieldNameList>]
[showwebviewlink text|hyperlink] [showwebviewlink text|hyperlink]
[formatjson [quotechar <Character>]] [formatjson [quotechar <Character>]]
``` ```
By default, all Shared Drives are displayed; use the following options to select a subset of Shared Drives: By default, all Shared Drives are displayed; use the following options to select a subset of Shared Drives:
* `shareddriveadminquery|query <QuerySharedDrive>` - Use a query to select Shared Drives * `teamdriveadminquery|query <QueryTeamDrive>` - Use a query to select Shared Drives
* `matchname <REMatchPattern>` - Retrieve Shared Drives with names that match a pattern. * `matchname <REMatchPattern>` - Retrieve Shared Drives with names that match a pattern.
* `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected * `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected
@@ -499,7 +498,7 @@ Options `shareddriveadminquery|query` and `shareddrives|teamdrives` are mutually
Options `shareddriveadminquery|query` and `orgunit|org|ou` require `adminaccess|asadmin`. Options `shareddriveadminquery|query` and `orgunit|org|ou` require `adminaccess|asadmin`.
By default, organizers for all Shared Drives are displayed; use the following options to select a subset of Shared Drives: By default, organizers for all Shared Drives are displayed; use the following options to select a subset of Shared Drives:
* `shareddriveadminquery|query <QuerySharedDrive>` - Use a query to select Shared Drives * `teamdriveadminquery|query <QueryTeamDrive>` - Use a query to select Shared Drives
* `shareddrives|teamdrives <SharedDriveIDList>` - Select the Shared Drive IDs specified in `<SharedDriveIDList>` * `shareddrives|teamdrives <SharedDriveIDList>` - Select the Shared Drive IDs specified in `<SharedDriveIDList>`
* `shareddrives|teamdrives select <FileSelector>|<CSVFileSelector>` - Select the Shared Drive IDs specified in `<FileSelector>|<CSVFileSelector>` * `shareddrives|teamdrives select <FileSelector>|<CSVFileSelector>` - Select the Shared Drive IDs specified in `<FileSelector>|<CSVFileSelector>`
* `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected * `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected
@@ -536,12 +535,12 @@ gam print shareddrives query "organizerCount = 0"
Display the number of Shared Drives. Display the number of Shared Drives.
``` ```
gam [<UserTypeEntity>] show|print shareddrives gam [<UserTypeEntity>] show|print shareddrives
[adminaccess|asadmin] [shareddriveadminquery|query <QuerySharedDrive>] [adminaccess|asadmin] [teamdriveadminquery|query <QueryTeamDrive>]
[matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
showitemcountonly showitemcountonly
``` ```
By default, all Shared Drives are counted; use the following options to select a subset of Shared Drives: By default, all Shared Drives are counted; use the following options to select a subset of Shared Drives:
* `shareddriveadminquery|query <QuerySharedDrive>` - Use a query to select Shared Drives * `teamdriveadminquery|query <QueryTeamDrive>` - Use a query to select Shared Drives
* `matchname <REMatchPattern>` - Retrieve Shared Drives with names that match a pattern. * `matchname <REMatchPattern>` - Retrieve Shared Drives with names that match a pattern.
* `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected * `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected
@@ -564,21 +563,6 @@ Windows Command Prompt
for /f "delims=" %a in ('gam print shareddrives showitemcountonly') do set count=%a for /f "delims=" %a in ('gam print shareddrives showitemcountonly') do set count=%a
``` ```
## Display Shared Drive Storage Info
Get a list of Shared Drives/organizers.
```
gam redirect csv ./SharedDriveOrganizers.csv print shareddriveorganizers includefileorganizers
```
Get SharedDrive Drive file count and storage info; use one of the following for size information:
* `showsize` - 31549200951 - This is a byte count; include `Size` in `csv_output_header_filter`
* `showsizeunits` - 31.55 GB - This is as shown in the Admin console; include `SizeUnits` in csv_output_header_filter
```
gam config csv_output_header_filter "id,name,Total,Size,SizeUnits,Item cap" csv_input_row_filter "organizers:regex:^.+$"
redirect csv ./SharedDriveStorageInfo.csv multiprocess redirect stderr - multiprocess
csv ./SharedDriveOrganizers.csv gam user "~organizers" print filecounts select shareddriveid "~id" showsize showsizeunits
```
## Display all Shared Drives with a specific organizer ## Display all Shared Drives with a specific organizer
Substitute actual email address for `organizer@domain.com`. Substitute actual email address for `organizer@domain.com`.
``` ```
@@ -774,7 +758,7 @@ gam config csv_output_header_drop_filter "User,createdTime,permission.photoLink,
## Display Shared Drive access for selected Shared Drives ## Display Shared Drive access for selected Shared Drives
``` ```
gam [<UserTypeEntity>] show shareddriveacls gam [<UserTypeEntity>] show shareddriveacls
[adminaccess|asadmin] [shareddriveadminquery|query <QuerySharedDrive>] [adminaccess|asadmin] [teamdriveadminquery|query <QueryTeamDrive>]
[matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
[user|group <EmailAddress> [checkgroups]] (role|roles <SharedDriveACLRoleList>)* [user|group <EmailAddress> [checkgroups]] (role|roles <SharedDriveACLRoleList>)*
<PermissionMatch>* [<PermissionMatchAction>] [pmselect] <PermissionMatch>* [<PermissionMatchAction>] [pmselect]
@@ -783,7 +767,7 @@ gam [<UserTypeEntity>] show shareddriveacls
[formatjson] [formatjson]
gam [<UserTypeEntity>] print shareddriveacls [todrive <ToDriveAttribute>*] gam [<UserTypeEntity>] print shareddriveacls [todrive <ToDriveAttribute>*]
[adminaccess|asadmin] [shareddriveadminquery|query <QuerySharedDrive>] [adminaccess|asadmin] [teamdriveadminquery|query <QueryTeamDrive>]
[matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
[user|group <EmailAddress> [checkgroups]] (role|roles <SharedDriveACLRoleList>)* [user|group <EmailAddress> [checkgroups]] (role|roles <SharedDriveACLRoleList>)*
<PermissionMatch>* [<PermissionMatchAction>] [pmselect] <PermissionMatch>* [<PermissionMatchAction>] [pmselect]
@@ -793,7 +777,7 @@ gam [<UserTypeEntity>] print shareddriveacls [todrive <ToDriveAttribute>*]
``` ```
By default, all Shared Drives are displayed; use the following options to select a subset of Shared Drives: By default, all Shared Drives are displayed; use the following options to select a subset of Shared Drives:
* `shareddriveadminquery|query <QuerySharedDrive>` - Use a query to select Shared Drives * `teamdriveadminquery|query <QueryTeamDrive>` - Use a query to select Shared Drives
* `matchname <REMatchPattern>` - Retrieve Shared Drives with names that match a pattern. * `matchname <REMatchPattern>` - Retrieve Shared Drives with names that match a pattern.
* `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected * `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected
* `<PermissionMatch>* [<PermissionMatchAction>] pmselect` - Use permission matching to select Shared Drives; all ACLs are displayed for the selected Shared Drives * `<PermissionMatch>* [<PermissionMatchAction>] pmselect` - Use permission matching to select Shared Drives; all ACLs are displayed for the selected Shared Drives
@@ -943,12 +927,12 @@ gam redirect stdout ./DeleteSharedDrives.txt multiprocess redirect stderr stdout
## Delete old empty Shared Drives ## Delete old empty Shared Drives
``` ```
# Get a list of Shared Drives organizers for Shared Drives created before one year ago; alter date<-1y as required. # Get a list of Shared Drives organizers for Shared Drives created before one year ago; alter date<-1y as required.
gam config csv_output_row_filter "createdTime:date<-1y" redirect csv ./ShareddriveOrganizers.csv print shareddriveorganizers domainlist mydomain.com includetypes user oneorganizer shownoorganizerdrives gam config csv_output_row_filter "createdTime:date<-1y" redirect csv ./TeamDriveOrganizers.csv print shareddriveorganizers domainlist mydomain.com includetypes user oneorganizer shownoorganizerdrives
# Inspect shareddriveOrganizers.csv, you'll have to deal with Shared Drives with no organizer/manager # Inspect shareddriveOrganizers.csv, you'll have to deal with Shared Drives with no organizer/manager
# Get old empty Shared Drives # Get old empty Shared Drives
gam config num_threads 10 csv_input_row_filter "organizers:regex:^.+$" csv_output_row_filter "Total:count=0" redirect csv ./OldEmptySharedDrives.csv multiprocess redirect stderr - multiprocess csv ./ShareddriveOrganizers.csv gam user "~organizers" print filecounts select shareddriveid "~id" showsize gam config num_threads 10 csv_input_row_filter "organizers:regex:^.+$" csv_output_row_filter "Total:count=0" redirect csv ./OldEmptySharedDrives.csv multiprocess redirect stderr - multiprocess csv ./TeamDriveOrganizers.csv gam user "~organizers" print filecounts select shareddriveid "~id" showsize
# Inspect OldEmptySharedDrives.csv, if you're confident of the results, proceed # Inspect OldEmptySharedDrives.csv, if you're confident of the results, proceed

View File

@@ -37,6 +37,9 @@ gam user user@domain.com update serviceaccount
[*] 11) Chat API - User Sections (supports readonly) [*] 11) Chat API - User Sections (supports readonly)
``` ```
`Chat API - User Sections` is in Developer Preview; you must have a the following variables set in `gam.cfg` to use these commands.
* `developer_preview_apis = chat`
* `developer_preview_api_key = <String>`
Added `use_chat_admin_access` Boolean variable to `gam.cfg`. Added `use_chat_admin_access` Boolean variable to `gam.cfg`.
``` ```
@@ -211,14 +214,16 @@ gam <UserTypeEntity> create chatspace
[members <UserTypeEntity>] [members <UserTypeEntity>]
[displayname <String>] [displayname <String>]
[description <String>] [guidelines <String>] [description <String>] [guidelines <String>]
[history <Boolean>]
[<ChatContent>] [<ChatContent>]
[formatjson|returnidonly] [formatjson|returnidonly]
``` ```
For `type space`, the following apply: For `type space`, the following apply:
* `members <UserTypeEntity>` - Optional, can not specify more than 20 users * `members <UserTypeEntity>` - Optional, can not specify more that 20 users
* `displayname <String>` - Required * `displayname <String>` - Required
* `description <String>` - Optional * `description <String>` - Optional
* `guidelines <String>` - Optional * `guidelines <String>` - Optional
* `history <Boolean>` - Optional
* `announcement|collaboration` - Initial permission settings; default is `collaboration` * `announcement|collaboration` - Initial permission settings; default is `collaboration`
For `type groupchat`, the following apply: For `type groupchat`, the following apply:
@@ -226,60 +231,23 @@ For `type groupchat`, the following apply:
* `displayname <String>` - Ignored * `displayname <String>` - Ignored
* `description <String>` - Optional * `description <String>` - Optional
* `guidelines <String>` - Optional * `guidelines <String>` - Optional
* `history <Boolean>` - Optional
For `type directmessage`, the following apply: For `type directmessage`, the following apply:
* `members <UserTypeEntity>` - Required, must specify 1 user * `members <UserTypeEntity>` - Required, must specify 1 user
* `displayname <String>` - Ignored * `displayname <String>` - Ignored
* `description <String>` - Ignored * `description <String>` - Ignored
* `guidelines <String>` - Ignored * `guidelines <String>` - Ignored
* `history <Boolean>` - Optional
By default, Gam displays the information about the created chatspace as an indented list of keys and values. By default, Gam displays the information about the created chatspace as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format. * `formatjson` - Display the fields in JSON format.
* `returnidonly` - Display the chatspace name only * `returnidonly` - Display the chatspace name only
Alternately, you can display the information about the created chatspace as columns of fields.
* `csv [todrive <ToDriveAttribute>*]` - Write Chat Space information to a CSV file.
* `addcsvdata <FieldName> <String>` - Add additional columns of data from the command line to the output
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
Use the `<ChatContent>` option to send an initial message to the created chatspace. Use the `<ChatContent>` option to send an initial message to the created chatspace.
By default, details about the chatmessage are displayed. By default, details about the chatmessage are displayed.
* `formatjson` - Display the chat message name in JSON format.
* `returnidonly` - Display the chatmessage name only * `returnidonly` - Display the chatmessage name only
* `csv` - The column `message.name` is added the CSV file output
### Bulk build chat spaces
You want to create Chat Spaces for use by users that don't currently have Chat enabled;
all commands will be run by a super admin.
Make a CSV file NewSpaces.csv with columns: displayName,manager,members
```
displayName,manager,members
Chat 123,user1@domain.com,user1@domain.com user2@domain.com user3@domain.com
Chat 456,user4@domain.com,user4@domain.com user5@domain.com user6@domain.com
```
The manager column specifies the member that will be updated to be a manager.
Create the spaces
```
gam redirect csv ./NewSpaceDetails.csv multiprocess csv NewSpaces.csv gam user admin@domain.com create chatspace type space collaboration displayname "~displayName" members "~members" csv addcsvdata manager "~manager"
```
Update the specified member from ROLE_MEMBER to ROLE_MANAGER
```
gam redirect stdout ./UpdateMemberToManager.txt multiprocess redirect stderr stdout csv NewSpaceDetails.csv gam user admin@domain.com update chatmember "~name" role manager user "~manager"
```
Delete the super admin from the space
```
gam redirect stdout ./DeleteAdmin.txt multiprocess redirect stderr stdout csv NewSpaceDetails.csv gam user admin@domain.com delete chatmember "~name" user admin@domain.com
```
### Update a user's chat space ### Update a user's chat space
``` ```

View File

@@ -18,8 +18,8 @@
<SharedDriveID> ::= <String> <SharedDriveID> ::= <String>
<SharedDriveName> ::= <String> <SharedDriveName> ::= <String>
<SharedDriveEntity> ::= <SharedDriveEntity> ::=
<SharedDriveID>|(shareddriveid <SharedDriveID>)|(shareddriveid:<SharedDriveID>)| <SharedDriveID>|(teamdriveid <SharedDriveID>)|(teamdriveid:<SharedDriveID>)|
(shareddrive <SharedDriveName>)|(shareddrive:<SharedDriveName>) (teamdrive <SharedDriveName>)|(teamdrive:<SharedDriveName>)
``` ```
## Display empty folders ## Display empty folders
``` ```

View File

@@ -68,10 +68,10 @@
(parentid <DriveFolderID>)| (parentid <DriveFolderID>)|
(parentname <DriveFolderName>)| (parentname <DriveFolderName>)|
(anyownerparentname <DriveFolderName>)| (anyownerparentname <DriveFolderName>)|
(shareddriveparentid <DriveFolderID>)| (teamdriveparentid <DriveFolderID>)|
(shareddriveparent <SharedDriveName>)| (teamdriveparent <SharedDriveName>)|
(shareddriveparentid <SharedDriveID> shareddriveparentname <DriveFolderName>)| (teamdriveparentid <SharedDriveID> teamdriveparentname <DriveFolderName>)|
(shareddriveparent <SharedDriveName> shareddriveparentname <DriveFolderName>) (teamdriveparent <SharedDriveName> teamdriveparentname <DriveFolderName>)
<DriveFileCopyAttribute> ::= <DriveFileCopyAttribute> ::=
(contentrestrictions readonly false)| (contentrestrictions readonly false)|
@@ -120,7 +120,6 @@ gam <UserTypeEntity> copy drivefile <DriveFileEntity>
[copyfilepermissions [<Boolean>]] [copyfilepermissions [<Boolean>]]
[copyfileinheritedpermissions [<Boolean>] [copyfileinheritedpermissions [<Boolean>]
[copyfilenoninheritedpermissions [<Boolean>] [copyfilenoninheritedpermissions [<Boolean>]
[copyfolderpermissions [<Boolean>]]
[copymergewithparentfolderpermissions [<Boolean>]] [copymergewithparentfolderpermissions [<Boolean>]]
[copymergedtopfolderpermissions [<Boolean>]] [copymergedtopfolderpermissions [<Boolean>]]
[copytopfolderpermissions [<Boolean>]] [copytopfolderpermissions [<Boolean>]]
@@ -140,6 +139,7 @@ gam <UserTypeEntity> copy drivefile <DriveFileEntity>
(mappermissionsdomain <DomainName> <DomainName>)* (mappermissionsdomain <DomainName> <DomainName>)*
[sendemailifrequired [<Boolean>]] [sendemailifrequired [<Boolean>]]
[verifyorganizer [<Boolean>]] [verifyorganizer [<Boolean>]]
[enforceexpansiveaccess [<Boolean>]]
``` ```
The files/folders specified by `<DriveFileEntity>` are referred to as `source`, `target` refers to where those files are being copied. The files/folders specified by `<DriveFileEntity>` are referred to as `source`, `target` refers to where those files are being copied.
The files/folders specified by `<DriveFileEntity>` are referred to as `top`; when a folder is being copied recursively, the files/folders that it contains are referred as `sub`. The files/folders specified by `<DriveFileEntity>` are referred to as `top`; when a folder is being copied recursively, the files/folders that it contains are referred as `sub`.
@@ -231,10 +231,10 @@ and "Template" is replaced by "NewCustomer" in all copied sub files and folders
* `parentid <DriveFolderID>` - The target folder is identified by `<DriveFolderID>` which must be writable by `<UserTypeEntity>`. * `parentid <DriveFolderID>` - The target folder is identified by `<DriveFolderID>` which must be writable by `<UserTypeEntity>`.
* `parentname <DriveFolderName>` - A search is performed for a folder named `<DriveFolderName>` owned by `<UserTypeEntity>`. * `parentname <DriveFolderName>` - A search is performed for a folder named `<DriveFolderName>` owned by `<UserTypeEntity>`.
* `anyownerparentname <DriveFolderName>` - A search is performed for a folder named `<DriveFolderName>` owned by any user but must be writable by `<UserTypeEntity>`. * `anyownerparentname <DriveFolderName>` - A search is performed for a folder named `<DriveFolderName>` owned by any user but must be writable by `<UserTypeEntity>`.
* `shareddriveparentid <DriveFolderID>` - Shared Drive folder ID; when used alone, this indicates a specific Shared Drive folder. * `teamdriveparentid <DriveFolderID>` - Shared Drive folder ID; when used alone, this indicates a specific Shared Drive folder.
* `shareddriveparent <SharedDriveName>` - Shared Drive name; when used alone, this indicates the root level of the Shared Drive. * `teamdriveparent <SharedDriveName>` - Shared Drive name; when used alone, this indicates the root level of the Shared Drive.
* `shareddriveparentid <SharedDriveID> shareddriveparentname <DriveFolderName>` - A Shared Drive ID and a folder name on that Shared Drive. * `teamdriveparentid <SharedDriveID> teamdriveparentname <DriveFolderName>` - A Shared Drive ID and a folder name on that Shared Drive.
* `shareddriveparent <SharedDriveName> shareddriveparentname <DriveFolderName>` - A Shared Drive name and a folder name on that Shared Drive. * `teamdriveparent <SharedDriveName> teamdriveparentname <DriveFolderName>` - A Shared Drive name and a folder name on that Shared Drive.
* If none of the parent options are specified, the copied file/folder will be located in the source folder. * If none of the parent options are specified, the copied file/folder will be located in the source folder.
### Duplicate files ### Duplicate files
@@ -294,8 +294,6 @@ When a folder is copied, its permissions are not copied; these options control c
of the form `option [<Boolean>]`; if `<Boolean>` is omitted, `true` is assumed. of the form `option [<Boolean>]`; if `<Boolean>` is omitted, `true` is assumed.
When copied, a target folder inherits the permissions of its parent folder; these options control whether/how GAM copies the existing source folder permissions. When copied, a target folder inherits the permissions of its parent folder; these options control whether/how GAM copies the existing source folder permissions.
* `copyfolderpermissions false` - The permissions of the source folders are not copied to the target folder.
* `copyfolderpermissions true` - The permissions of the source folders are copied to the target folder based on the following options; this is the default action.
When `mergewithparent` is `true`: When `mergewithparent` is `true`:
* `copymergewithparentfolderpermissions false` - The permissions of the source top folder are not not copied to the target folder; this is the default action. * `copymergewithparentfolderpermissions false` - The permissions of the source top folder are not not copied to the target folder; this is the default action.
@@ -416,15 +414,15 @@ Specify the target location on the Shared Drive, either the ID of the Shared Dri
Files/folders in root of My Drive will be merged into `<DriveFolderID>` Files/folders in root of My Drive will be merged into `<DriveFolderID>`
``` ```
gam user user@domain.com copy drivefile root recursive shareddriveparentid <DriveFolderID> mergewithparent true gam user user@domain.com copy drivefile root recursive teamdriveparentid <DriveFolderID> mergewithparent true
``` ```
Files/folders in root of My Drive will be in a new folder named `My Drive` created in `<DriveFolderID>` Files/folders in root of My Drive will be in a new folder named `My Drive` created in `<DriveFolderID>`
``` ```
gam user user@domain.com copy drivefile root recursive shareddriveparentid <DriveFolderID> mergewithparent false gam user user@domain.com copy drivefile root recursive teamdriveparentid <DriveFolderID> mergewithparent false
``` ```
Files/folders in root of My Drive will be in a new folder named `<String>` created in `<DriveFolderID>` Files/folders in root of My Drive will be in a new folder named `<String>` created in `<DriveFolderID>`
``` ```
gam user user@domain.com copy drivefile root recursive shareddriveparentid <SharedDriveID> mergewithparent false newfilename <String> gam user user@domain.com copy drivefile root recursive teamdriveparentid <SharedDriveID> mergewithparent false newfilename <String>
``` ```
### Copy content of a Shared Drive to another Shared Drive ### Copy content of a Shared Drive to another Shared Drive
@@ -440,7 +438,7 @@ The example is assuming that the target drive is empty.
* Non-inherited sub folder permissions are copied. * Non-inherited sub folder permissions are copied.
* Non-inherited file permissions are copied. * Non-inherited file permissions are copied.
``` ```
gam user user@domain.com copy drivefile shareddriveid 0AC_1AB shareddriveparentid 0AE_9ZX mergewithparent recursive gam user user@domain.com copy drivefile teamdriveid 0AC_1AB teamdriveparentid 0AE_9ZX mergewithparent recursive
copymergewithparentfolderpermissions true copymergewithparentfolderpermissions true
copytopfolderinheritedpermissions false copytopfolderinheritedpermissions false
copytopfoldernoninheritedpermissions always copytopfoldernoninheritedpermissions always
@@ -460,7 +458,7 @@ Suppose that the source drive has been updated and you want to refresh the targe
* Non-inherited file permissions are copied. * Non-inherited file permissions are copied.
* Files and folders that have been deleted from the source drive will remain on the target drive * Files and folders that have been deleted from the source drive will remain on the target drive
``` ```
gam user user@domain.com copy drivefile shareddriveid 0AC_1AB shareddriveparentid 0AE_9ZX mergewithparent recursive gam user user@domain.com copy drivefile teamdriveid 0AC_1AB teamdriveparentid 0AE_9ZX mergewithparent recursive
copymergewithparentfolderpermissions true copymergewithparentfolderpermissions true
copytopfolderinheritedpermissions false copytopfolderinheritedpermissions false
copytopfoldernoninheritedpermissions syncallfolders copytopfoldernoninheritedpermissions syncallfolders
@@ -480,7 +478,7 @@ gam redirect csv ./TopSDItems.csv user user@domain.com print filelist select 0AC
``` ```
Copy the top level items to target Shared Drive; append desired permission options Copy the top level items to target Shared Drive; append desired permission options
``` ```
gam redirect stdout ./CopySharedDrive.txt multiprocess redirect stderr stdout csv TopSDItems.csv gam user user@domain.com copy drivefile "~id" recursive shareddriveparentid 0AE_9ZX gam redirect stdout ./CopySharedDrive.txt multiprocess redirect stderr stdout csv TopSDItems.csv gam user user@domain.com copy drivefile "~id" recursive teamdriveparentid 0AE_9ZX
``` ```
### Copy content of a source Shared Drive folder to a target Shared Drive with parallel Processing ### Copy content of a source Shared Drive folder to a target Shared Drive with parallel Processing
@@ -490,31 +488,31 @@ gam redirect csv ./TopSDItems.csv user user@domain.com print filelist select 1Bx
``` ```
Create a folder on target Shared Drive with ID 0AE_9ZX, replace "New Folder Name" as desired. Create a folder on target Shared Drive with ID 0AE_9ZX, replace "New Folder Name" as desired.
``` ```
gam user user@domain.com create drivefile mimetype gfolder shareddriveparentid 0AE-9ZX drivefilename "New Folder Name" returnidonly gam user user@domain.com create drivefile mimetype gfolder teamdriveparentid 0AE-9ZX drivefilename "New Folder Name" returnidonly
``` ```
Copy the folder top level items to target Shared Drive folder, assume ID 2CY-45G was returned in previous step Copy the folder top level items to target Shared Drive folder, assume ID 2CY-45G was returned in previous step
``` ```
gam redirect stdout ./CopySharedDrive.txt multiprocess redirect stderr stdout csv TopSDItems.csv gam user user@domain.com copy drivefile "~id" recursive shareddriveparentid 2CY-45G gam redirect stdout ./CopySharedDrive.txt multiprocess redirect stderr stdout csv TopSDItems.csv gam user user@domain.com copy drivefile "~id" recursive teamdriveparentid 2CY-45G
``` ```
You can script the steps: You can script the steps:
Linux/MacOS Linux/MacOS
``` ```
gam redirect csv ./TopSDItems.csv user user@domain.com print filelist select 1Bx-8W3 fields id,name,mimetype depth 0 gam redirect csv ./TopSDItems.csv user user@domain.com print filelist select 1Bx-8W3 fields id,name,mimetype depth 0
targetFolderId=$(gam user user@domain.com create drivefile mimetype gfolder shareddriveparentid 0AE-9ZX drivefilename "New Folder Name" returnidonly) targetFolderId=$(gam user user@domain.com create drivefile mimetype gfolder teamdriveparentid 0AE-9ZX drivefilename "New Folder Name" returnidonly)
gam redirect stdout ./CopySharedDrive.txt multiprocess redirect stderr stdout csv TopSDItems.csv gam user user@domain.com copy drivefile "~id" recursive shareddriveparentid $targetFolderId gam redirect stdout ./CopySharedDrive.txt multiprocess redirect stderr stdout csv TopSDItems.csv gam user user@domain.com copy drivefile "~id" recursive teamdriveparentid $targetFolderId
``` ```
Windows PowerShell Windows PowerShell
``` ```
gam redirect csv ./TopSDItems.csv user user@domain.com print filelist select 1Bx-8W3 fields id,name,mimetype depth 0 gam redirect csv ./TopSDItems.csv user user@domain.com print filelist select 1Bx-8W3 fields id,name,mimetype depth 0
$targetFolderId = & gam user user@domain.com create drivefile mimetype gfolder shareddriveparentid 0AE-9ZX drivefilename "New Folder Name" returnidonly $targetFolderId = & gam user user@domain.com create drivefile mimetype gfolder teamdriveparentid 0AE-9ZX drivefilename "New Folder Name" returnidonly
gam redirect stdout ./CopySharedDrive.txt multiprocess redirect stderr stdout csv TopSDItems.csv gam user user@domain.com copy drivefile "~id" recursive shareddriveparentid $targetFolderId gam redirect stdout ./CopySharedDrive.txt multiprocess redirect stderr stdout csv TopSDItems.csv gam user user@domain.com copy drivefile "~id" recursive teamdriveparentid $targetFolderId
``` ```
Windows Command Prompt Windows Command Prompt
``` ```
gam redirect csv ./TopSDItems.csv user user@domain.com print filelist select 1Bx-8W3 fields id,name,mimetype depth 0 gam redirect csv ./TopSDItems.csv user user@domain.com print filelist select 1Bx-8W3 fields id,name,mimetype depth 0
for /f "delims=" %a in ('gam user user@domain.com create drivefile mimetype gfolder shareddriveparentid 0AE-9ZX drivefilename "New Folder Name" returnidonly') do set taregtFolderId=%a for /f "delims=" %a in ('gam user user@domain.com create drivefile mimetype gfolder teamdriveparentid 0AE-9ZX drivefilename "New Folder Name" returnidonly') do set taregtFolderId=%a
gam redirect stdout ./CopySharedDrive.txt multiprocess redirect stderr stdout csv TopSDItems.csv gam user user@domain.com copy drivefile "~id" recursive shareddriveparentid %targetFolderId% gam redirect stdout ./CopySharedDrive.txt multiprocess redirect stderr stdout csv TopSDItems.csv gam user user@domain.com copy drivefile "~id" recursive teamdriveparentid %targetFolderId%
``` ```
## Move files and folders ## Move files and folders
@@ -573,7 +571,6 @@ gam <UserTypeEntity> move drivefile <DriveFileEntity> [newfilename <DriveFileNam
[createshortcutsfornonmovablefiles [<Boolean>]] [createshortcutsfornonmovablefiles [<Boolean>]]
[duplicatefiles overwriteolder|overwriteall|duplicatename|uniquename|skip] [duplicatefiles overwriteolder|overwriteall|duplicatename|uniquename|skip]
[duplicatefolders merge|duplicatename|uniquename|skip] [duplicatefolders merge|duplicatename|uniquename|skip]
[copyfolderpermissions [<Boolean>]]
[copymergewithparentfolderpermissions [<Boolean>]] [copymergewithparentfolderpermissions [<Boolean>]]
[copymergedtopfolderpermissions [<Boolean>]] [copymergedtopfolderpermissions [<Boolean>]]
[copytopfolderpermissions [<Boolean>]] [copytopfolderpermissions [<Boolean>]]
@@ -589,6 +586,7 @@ gam <UserTypeEntity> move drivefile <DriveFileEntity> [newfilename <DriveFileNam
[retainsourcefolders [<Boolean>]] [retainsourcefolders [<Boolean>]]
[sendemailifrequired [<Boolean>]] [sendemailifrequired [<Boolean>]]
[verifyorganizer [<Boolean>]] [verifyorganizer [<Boolean>]]
[enforceexpansiveaccess [<Boolean>]]
``` ```
The files/folders specified by `<DriveFileEntity>` are referred to as `source`, `target` refers to where those files are being moved. The files/folders specified by `<DriveFileEntity>` are referred to as `source`, `target` refers to where those files are being moved.
The files/folders specified by `<DriveFileEntity>` are referred to as `top`; when a folder is being moved, the files/folders that it contains are referred as `sub`. The files/folders specified by `<DriveFileEntity>` are referred to as `top`; when a folder is being moved, the files/folders that it contains are referred as `sub`.
@@ -616,10 +614,10 @@ This is the default mode.
* `parentid <DriveFolderID>` - The target folder is identified by `<DriveFolderID>` which must be writable by `<UserTypeEntity>`. * `parentid <DriveFolderID>` - The target folder is identified by `<DriveFolderID>` which must be writable by `<UserTypeEntity>`.
* `parentname <DriveFolderName>` - A search is performed for a folder named `<DriveFolderName>` owned by `<UserTypeEntity>`. * `parentname <DriveFolderName>` - A search is performed for a folder named `<DriveFolderName>` owned by `<UserTypeEntity>`.
* `anyownerparentname <DriveFolderName>` - A search is performed for a folder named `<DriveFolderName>` owned by any user but must be writable by `<UserTypeEntity>`. * `anyownerparentname <DriveFolderName>` - A search is performed for a folder named `<DriveFolderName>` owned by any user but must be writable by `<UserTypeEntity>`.
* `shareddriveparentid <DriveFolderID>` - Shared Drive folder ID; when used alone, this indicates a specific Shared Drive folder. * `teamdriveparentid <DriveFolderID>` - Shared Drive folder ID; when used alone, this indicates a specific Shared Drive folder.
* `shareddriveparent <SharedDriveName>` - Shared Drive name; when used alone, this indicates the root level of the Shared Drive. * `teamdriveparent <SharedDriveName>` - Shared Drive name; when used alone, this indicates the root level of the Shared Drive.
* `shareddriveparentid <SharedDriveID> shareddriveparentname <DriveFolderName>` - A Shared Drive ID and a folder name on that Shared Drive. * `teamdriveparentid <SharedDriveID> teamdriveparentname <DriveFolderName>` - A Shared Drive ID and a folder name on that Shared Drive.
* `shareddriveparent <SharedDriveName> shareddriveparentname <DriveFolderName>` - A Shared Drive name and a folder name on that Shared Drive. * `teamdriveparent <SharedDriveName> teamdriveparentname <DriveFolderName>` - A Shared Drive name and a folder name on that Shared Drive.
* If none of the parent options are specified, the moved file/folder will be located in the source folder. * If none of the parent options are specified, the moved file/folder will be located in the source folder.
### Duplicate files ### Duplicate files
@@ -662,8 +660,6 @@ When a folder is moved by recreating it, its permissions are not copied by the D
For options of the form `option [<Boolean>]`; if `<Boolean>` is omitted, `true` is assumed. For options of the form `option [<Boolean>]`; if `<Boolean>` is omitted, `true` is assumed.
When recreated, a target folder inherits the permissions of its parent folder; these options control whether/how GAM copies the existing source folder permissions; When recreated, a target folder inherits the permissions of its parent folder; these options control whether/how GAM copies the existing source folder permissions;
* `copyfolderpermissions false` - The permissions of the source folders are not copied to the target folder.
* `copyfolderpermissions true` - The permissions of the source folders are copied to the target folder based on the following options; this is the default action.
When `mergewithparent` is `true`: When `mergewithparent` is `true`:
* `copymergewithparentfolderpermissions false` - The permissions of the source top folder are not not copied to the target folder; this is the default action. * `copymergewithparentfolderpermissions false` - The permissions of the source top folder are not not copied to the target folder; this is the default action.
@@ -765,14 +761,14 @@ The following command will change the parents of the top level files and folders
* No permissions are processed. * No permissions are processed.
``` ```
gam user user@domain.com move drivefile shareddriveid 0AC_1AB shareddriveparentid 0AE_9ZX mergewithparent gam user user@domain.com move drivefile teamdriveid 0AC_1AB teamdriveparentid 0AE_9ZX mergewithparent
``` ```
If you want the source Shared Drive with ID 0AC_1AB to be contained in a top level folder of the target Shared Drive with ID 0AE_9ZX, omit the `mergewithparent` argument. If you want the source Shared Drive with ID 0AC_1AB to be contained in a top level folder of the target Shared Drive with ID 0AE_9ZX, omit the `mergewithparent` argument.
The folder on the target Shared Drive will have the same name as the name of the source Shared Drive; use the `newfilename <DriveFileName>` to use a different name. The folder on the target Shared Drive will have the same name as the name of the source Shared Drive; use the `newfilename <DriveFileName>` to use a different name.
``` ```
gam user user@domain.com move drivefile shareddriveid 0AC_1AB shareddriveparentid 0AE_9ZX gam user user@domain.com move drivefile teamdriveid 0AC_1AB teamdriveparentid 0AE_9ZX
gam user user@domain.com move drivefile shareddriveid 0AC_1AB shareddriveparentid 0AE_9ZX newfilename "Copy of source Shared Drive" gam user user@domain.com move drivefile teamdriveid 0AC_1AB teamdriveparentid 0AE_9ZX newfilename "Copy of source Shared Drive"
``` ```
### Inter-workspace moves ### Inter-workspace moves
@@ -782,7 +778,7 @@ Due to a restructuring, you want to move data from Shared Drive A in domaina.com
* `user@domaina.com` is a manager of both Shared Drives. * `user@domaina.com` is a manager of both Shared Drives.
``` ```
$ gam user user@domaina move drivefile shareddriveid <SharedDriveAID> shareddriveparentid <SharedDriveBID> mergewithparent $ gam user user@domaina move drivefile teamdriveid <SharedDriveAID> teamdriveparentid <SharedDriveBID> mergewithparent
User: user@domaina.com, Move 1 Drive File/Folder User: user@domaina.com, Move 1 Drive File/Folder
User: user@domaina.com, Drive Folder: Shared Drive A(<SharedDriveAID>), Move(Merge) contents with Drive Folder: Shared Drive B(<SharedDriveBID>) User: user@domaina.com, Drive Folder: Shared Drive A(<SharedDriveAID>), Move(Merge) contents with Drive Folder: Shared Drive B(<SharedDriveBID>)
User: user@domaina.com, Drive File: Filename(<FileID>), Move Failed: Bad Request. User message: "shareOutNotPermitted" User: user@domaina.com, Drive File: Filename(<FileID>), Move Failed: Bad Request. User message: "shareOutNotPermitted"
@@ -798,13 +794,13 @@ The following command will change the parents of the top level files and folders
* No permissions are processed. * No permissions are processed.
``` ```
gam user user@domain.com move drivefile shareddriveid 0AC_1AB parentid root mergewithparent gam user user@domain.com move drivefile teamdriveid 0AC_1AB parentid root mergewithparent
``` ```
If you want the contents of Shared Drive with ID 0AC_1AB to be contained in a top level folder of the My Drive, omit the `mergewithparent` argument. If you want the contents of Shared Drive with ID 0AC_1AB to be contained in a top level folder of the My Drive, omit the `mergewithparent` argument.
The folder on the My Drive will have the same name as the name of the Shared Drive; use the `newfilename <DriveFileName>` to use a different name. The folder on the My Drive will have the same name as the name of the Shared Drive; use the `newfilename <DriveFileName>` to use a different name.
``` ```
gam user user@domain.com move drivefile shareddriveid 0AC_1AB parentid root gam user user@domain.com move drivefile teamdriveid 0AC_1AB parentid root
gam user user@domain.com move drivefile shareddriveid 0AC_1AB parentid root newfilename "Copy of Shared Drive" gam user user@domain.com move drivefile teamdriveid 0AC_1AB parentid root newfilename "Copy of Shared Drive"
``` ```

View File

@@ -65,9 +65,9 @@
<SharedDriveID> ::= <String> <SharedDriveID> ::= <String>
<SharedDriveName> ::= <String> <SharedDriveName> ::= <String>
<SharedDriveIDEntity> ::= (shareddriveid <SharedDriveID>) | (shareddriveid:<SharedDriveID>) <SharedDriveIDEntity> ::= (teamdriveid <SharedDriveID>) | (teamdriveid:<SharedDriveID>)
<SharedDriveNameEntity> ::= (shareddrive <SharedDriveName>) | (shareddrive:<SharedDriveName>) <SharedDriveNameEntity> ::= (teamdrive <SharedDriveName>) | (teamdrive:<SharedDriveName>)
<SharedDriveFileNameEntity> ::= (shareddrivefilename <DriveFileName>) | (shareddrivefilename:<DriveFileName>) <SharedDriveFileNameEntity> ::= (teamdrivefilename <DriveFileName>) | (teamdrivefilename:<DriveFileName>)
<SharedDriveEntity> ::= <SharedDriveEntity> ::=
<SharedDriveIDEntity> | <SharedDriveIDEntity> |
@@ -315,8 +315,8 @@
size| size|
spaces| spaces|
starred| starred|
shareddriveid| teamdriveid|
shareddrivename| teamdrivename|
thumbnaillink| thumbnaillink|
thumbnailversion| thumbnailversion|
title| title|
@@ -405,7 +405,7 @@ quotaBytesUsed - The number of storage quota bytes used by the file.
size - Size in bytes of blobs and first party editor files. size - Size in bytes of blobs and first party editor files.
``` ```
Previously, GAM used the `size` field when totaling file sizes, it now uses the `quotaBytesUsed` field. Previously, GAM used the `size` field when totaling file sizes, it now uses the `quotaBytesUsed` field.
The option `sizefield quotabytesused|size` allows you to select which field to use; `quotabytesused` is the default. The option `sizefield quotabytesused|size` allows you to select which field to use.
For most MIME types, the values are the same; for the following MIME types, `quotabytesused` is larger. For most MIME types, the values are the same; for the following MIME types, `quotabytesused` is larger.
``` ```
@@ -619,10 +619,8 @@ This option is not available for `print|show filetree`.
``` ```
((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>) (querytime<String> <Time>)* ((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>) (querytime<String> <Time>)*
``` ```
GAM initializes the query to `'me' in owners`.
* `query "xxx"` - ` and xxx` is appended to the current query; you can repeat the query argument to build up a longer query. * `query "xxx"` - ` and xxx` is appended to the current query; you can repeat the query argument to build up a longer query.
* `fullquery "xxx"` - The query is set to `xxx` eliminating the initial `'me' in owners`. You must also use `showownedby any|others` as desired. * `fullquery "xxx"` - The query is set to `xxx` eliminating the initial `'me' in owners`.
* `<DriveFileQueryShortcut>` - Predefined queries * `<DriveFileQueryShortcut>` - Predefined queries
Use the `querytime<String> <Time>` option to allow times, usually relative, to be substituted into the `query <QueryDriveFile>` option. Use the `querytime<String> <Time>` option to allow times, usually relative, to be substituted into the `query <QueryDriveFile>` option.
@@ -719,7 +717,7 @@ gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
[filenamematchpattern <REMatchPattern>] [filenamematchpattern <REMatchPattern>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed] [excludetrashed]
[showsize] [showsizeunits] [showmimetypesize] [showsize] [showmimetypesize]
[showlastmodification] [pathdelimiter <Character>] [showlastmodification] [pathdelimiter <Character>]
(addcsvdata <FieldName> <String>)* (addcsvdata <FieldName> <String>)*
[summary none|only|plus] [summaryuser <String>] [summary none|only|plus] [summaryuser <String>]
@@ -735,7 +733,7 @@ gam <UserTypeEntity> show filecounts
[filenamematchpattern <REMatchPattern>] [filenamematchpattern <REMatchPattern>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed] [excludetrashed]
[showsize] [showsizeunits] [showmimetypesize] [showsize] [showmimetypesize]
[showlastmodification] [pathdelimiter <Character>] [showlastmodification] [pathdelimiter <Character>]
[summary none|only|plus] [summaryuser <String>] [summary none|only|plus] [summaryuser <String>]
``` ```
@@ -748,11 +746,7 @@ saying that the query is invalid when, in fact, it is but the user does not have
When `continueoninvalidquery` is true, GAM prints an error message and proceeds to the next user rather that terminating When `continueoninvalidquery` is true, GAM prints an error message and proceeds to the next user rather that terminating
as it does now. Of course, if the query really is invalid, you will get the message for every user. as it does now. Of course, if the query really is invalid, you will get the message for every user.
The `showsize` option displays the total size (in bytes) of the files counted; e.g., `31549200951`. The `showsize` option displays the total size (in bytes) of the files counted.
With `print filecounts`, this will be in a column labelled `Size`.
The `showsizeunits` option displays the total size of the files counted with two decimal places and units; e.g., `31.55 GB`.
With `print filecounts`, this will be in a column labelled `SizeUnits`.
The `showmimetypesize` option displays the total size (in bytes) of each MIME type counted. The `showmimetypesize` option displays the total size (in bytes) of each MIME type counted.
@@ -1104,7 +1098,7 @@ gam <UserTypeEntity> print|show filelist [todrive <ToDriveAttribute>*]
[excludetrashed] [excludetrashed]
[maxfiles <Integer>] [nodataheaders <String>] [maxfiles <Integer>] [nodataheaders <String>]
[countsonly [summary none|only|plus] [summaryuser <String>] [countsonly [summary none|only|plus] [summaryuser <String>]
[showsource] [showsize] [showsizeunits] [showmimetypesize]] [showsource] [showsize] [showmimetypesize]]
[countsrowfilter] [countsrowfilter]
[filepath|fullpath [folderpathonly [<Boolean>]] [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree] [filepath|fullpath [folderpathonly [<Boolean>]] [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree]
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)] [allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
@@ -1308,9 +1302,7 @@ The `summaryuser <String>` option replaces the default summary user `Summary` w
The `countsonly` suboption `showsource` adds additional columns `Source` and `Name` that identify the top level folder ID and Name from which the counts are derived. The `countsonly` suboption `showsource` adds additional columns `Source` and `Name` that identify the top level folder ID and Name from which the counts are derived.
The `countsonly` suboption `showsize` adds an additional column `Size` that indicates the total size (in bytes) of the files represented on the row; e.g., `31549200951`. The `countsonly` suboption `showsize` adds an additional column `Size` that indicates the total size (in bytes) of the files represented on the row.
The `countsonly` suboption `showsizeunits` adds an additional column `SizeUnits` that indicates the total size of the files represented on the row with two decimal places and units; e.g., `31.55 GB`.
The `countsonly` suboption `showmimetypesize` adds additional columns `<MimeType>:Size` that indicate the total size (in bytes) of each MIME type. The `countsonly` suboption `showmimetypesize` adds additional columns `<MimeType>:Size` that indicate the total size (in bytes) of each MIME type.

View File

@@ -149,10 +149,10 @@
(parentid <DriveFolderID>)| (parentid <DriveFolderID>)|
(parentname <DriveFolderName>)| (parentname <DriveFolderName>)|
(anyownerparentname <DriveFolderName>)| (anyownerparentname <DriveFolderName>)|
(shareddriveparentid <DriveFolderID>)| (teamdriveparentid <DriveFolderID>)|
(shareddriveparent <SharedDriveName>)| (teamdriveparent <SharedDriveName>)|
(shareddriveparentid <SharedDriveID> shareddriveparentname <DriveFolderName>)| (teamdriveparentid <SharedDriveID> teamdriveparentname <DriveFolderName>)|
(shareddriveparent <SharedDriveName> shareddriveparentname <DriveFolderName>) (teamdriveparent <SharedDriveName> teamdriveparentname <DriveFolderName>)
<DriveFileCreateAttribute> ::= <DriveFileCreateAttribute> ::=
<DriveFileAttribute>| <DriveFileAttribute>|
@@ -196,10 +196,10 @@ You can specify where the new file is to be located:
* `parentid <DriveFolderID>` - Folder ID. * `parentid <DriveFolderID>` - Folder ID.
* `parentname <DriveFolderName>` - Folder name; the folder must be owned by `<UserTypeEntity>`. * `parentname <DriveFolderName>` - Folder name; the folder must be owned by `<UserTypeEntity>`.
* `anyownerparentname <DriveFolderName>` - Folder name; the folder can be owned by any user, `<UserTypeEntity>` must be able to write to the folder. * `anyownerparentname <DriveFolderName>` - Folder name; the folder can be owned by any user, `<UserTypeEntity>` must be able to write to the folder.
* `shareddriveparentid <DriveFolderID>` - Shared Drive folder ID; when used alone, this indicates a specfic Shared Drive folder. * `teamdriveparentid <DriveFolderID>` - Shared Drive folder ID; when used alone, this indicates a specfic Shared Drive folder.
* `shareddriveparent <SharedDriveName>` - Shared Drive name; when used alone, this indicates the root level of the Shared Drive. * `teamdriveparent <SharedDriveName>` - Shared Drive name; when used alone, this indicates the root level of the Shared Drive.
* `shareddriveparentid <SharedDriveID> shareddriveparentname <DriveFolderName>` - A Shared Drive ID and a folder name on that Shared Drive. * `teamdriveparentid <SharedDriveID> teamdriveparentname <DriveFolderName>` - A Shared Drive ID and a folder name on that Shared Drive.
* `shareddriveparent <SharedDriveName> shareddriveparentname <DriveFolderName>` - A Shared Drive name and a folder name on that Shared Drive. * `teamdriveparent <SharedDriveName> teamdriveparentname <DriveFolderName>` - A Shared Drive name and a folder name on that Shared Drive.
* If none of the parent options are specified, the parent folder is the root folder. * If none of the parent options are specified, the parent folder is the root folder.
By default, Google assigns the current time to the attributes `createdTime` and `modifiedTime`; you can assign your own values By default, Google assigns the current time to the attributes `createdTime` and `modifiedTime`; you can assign your own values
@@ -290,7 +290,7 @@ This will create a three column CSV file SharedDriveNamesIDs.csv with columns: U
You are building student folders on a Shared Drive as an admin and want to add ACLs to the folders You are building student folders on a Shared Drive as an admin and want to add ACLs to the folders
allowing the student write access and you want a shortcut on the student's My Drive pointing to the folder. allowing the student write access and you want a shortcut on the student's My Drive pointing to the folder.
By adding the student's primary email address to the CSV output, it can be used in subsequent commands. By adding the student's primary email address to the CSV output, it can be used in subsequent commands.
Sustitute for admin@domain.com and `<SharedDriveID>`. Sustitute for admin@domain.com and `<TeamDriveID>`.
``` ```
Students.csv Students.csv
primaryEmail,Name primaryEmail,Name
@@ -299,7 +299,7 @@ mary@domain.com, Mary Smith
... ...
# Create the student folders on the Shared Drive # Create the student folders on the Shared Drive
gam redirect csv ./StudentFolders.csv multiprocess csv Students.csv gam user admin@domain.com create drivefile mimetype gfolder drivefilename "~~Name~~ Digital Portfolio" parentid <SharedDriveID> csv addcsvdata primaryEmail "~primaryEmail" gam redirect csv ./StudentFolders.csv multiprocess csv Students.csv gam user admin@domain.com create drivefile mimetype gfolder drivefilename "~~Name~~ Digital Portfolio" parentid <TeamDriveID> csv addcsvdata primaryEmail "~primaryEmail"
# Add ACLs granting the students write access to their folders; "~User" refers to admin@domain.com # Add ACLs granting the students write access to their folders; "~User" refers to admin@domain.com
gam csv StudentFolders.csv gam user "~User" add drivefileacl "~id" user "~primaryEmail" role fileorganizer gam csv StudentFolders.csv gam user "~User" add drivefileacl "~id" user "~primaryEmail" role fileorganizer
# Add a shortcut to the folder on the student's My Drive # Add a shortcut to the folder on the student's My Drive
@@ -389,7 +389,7 @@ User: user@domain.com, Drive Folder Path:, Create
Build in a Shared Drive Folder Build in a Shared Drive Folder
``` ```
gam user user@domain.com create drivefolderpath path "Top Folder/Middle Folder/Bottom Folder/Sub Folder" shareddriveparent "TS Shared Drive" shareddriveparentname "TS SD6 Folder" gam user user@domain.com create drivefolderpath path "Top Folder/Middle Folder/Bottom Folder/Sub Folder" teamdriveparent "TS Shared Drive" teamdriveparentname "TS SD6 Folder"
Getting all Drive Files/Folders that match query (mimeType = 'application/vnd.google-apps.folder' and name = 'TS SD6 Folder' and trashed = false) for user@domain.com Getting all Drive Files/Folders that match query (mimeType = 'application/vnd.google-apps.folder' and name = 'TS SD6 Folder' and trashed = false) for user@domain.com
Got 1 Drive File/Folder that matched query (mimeType = 'application/vnd.google-apps.folder' and name = 'TS SD6 Folder' and trashed = false) for user@domain.com... Got 1 Drive File/Folder that matched query (mimeType = 'application/vnd.google-apps.folder' and name = 'TS SD6 Folder' and trashed = false) for user@domain.com...
User: user@domain.com, Drive Folder Path:, Create User: user@domain.com, Drive Folder Path:, Create
@@ -495,10 +495,10 @@ You can change where the new file is to be located; this removes all other paren
* `parentid <DriveFolderID>` - Folder ID. * `parentid <DriveFolderID>` - Folder ID.
* `parentname <DriveFolderName>` - Folder name; the folder must be owned by `<UserTypeEntity>`. * `parentname <DriveFolderName>` - Folder name; the folder must be owned by `<UserTypeEntity>`.
* `anyownerparentname <DriveFolderName>` - Folder name; the folder can be owned by any user, `<UserTypeEntity>` must be able to write to the folder. * `anyownerparentname <DriveFolderName>` - Folder name; the folder can be owned by any user, `<UserTypeEntity>` must be able to write to the folder.
* `shareddriveparentid <DriveFolderID>` - Shared Drive folder ID; when used alone, this indicates a specfic Shared Drive folder. * `teamdriveparentid <DriveFolderID>` - Shared Drive folder ID; when used alone, this indicates a specfic Shared Drive folder.
* `shareddriveparent <SharedDriveName>` - Shared Drive name; when used alone, this indicates the root level of the Shared Drive. * `teamdriveparent <SharedDriveName>` - Shared Drive name; when used alone, this indicates the root level of the Shared Drive.
* `shareddriveparentid <SharedDriveID> shareddriveparentname <DriveFolderName>` - A Shared Drive ID and a folder name on that Shared Drive. * `teamdriveparentid <SharedDriveID> teamdriveparentname <DriveFolderName>` - A Shared Drive ID and a folder name on that Shared Drive.
* `shareddriveparent <SharedDriveName> shareddriveparentname <DriveFolderName>` - A Shared Drive name and a folder name on that Shared Drive. * `teamdriveparent <SharedDriveName> teamdriveparentname <DriveFolderName>` - A Shared Drive name and a folder name on that Shared Drive.
You can add/remove parent folders without affecting other parent folders. You can add/remove parent folders without affecting other parent folders.
* `addparents|removeparents <DriveFolderIDList>` - Specify the parent folders by ID. * `addparents|removeparents <DriveFolderIDList>` - Specify the parent folders by ID.

View File

@@ -30,13 +30,13 @@
(parentid <DriveFolderID>)| (parentid <DriveFolderID>)|
(parentname <DriveFolderName>)| (parentname <DriveFolderName>)|
(anyownerparentname <DriveFolderName>)| (anyownerparentname <DriveFolderName>)|
(shareddriveparentid <DriveFolderID>)| (teamdriveparentid <DriveFolderID>)|
(shareddriveparent <SharedDriveName>)| (teamdriveparent <SharedDriveName>)|
(shareddriveparentid <SharedDriveID> shareddriveparentname <DriveFolderName>)| (teamdriveparentid <SharedDriveID> teamdriveparentname <DriveFolderName>)|
(shareddriveparent <SharedDriveName> shareddriveparentname <DriveFolderName>))| (teamdriveparent <SharedDriveName> teamdriveparentname <DriveFolderName>))|
(shareddriveparentid <DriveFolderID>)|(shareddriveparent <SharedDriveName>)| (teamdriveparentid <DriveFolderID>)|(teamdriveparent <SharedDriveName>)|
(shareddriveparentid <SharedDriveID> shareddriveparentname <DriveFolderName>)| (teamdriveparentid <SharedDriveID> teamdriveparentname <DriveFolderName>)|
(shareddriveparent <SharedDriveName> shareddriveparentname <DriveFolderName>) (teamdriveparent <SharedDriveName> teamdriveparentname <DriveFolderName>)
<DriveOrderByFieldName> ::= <DriveOrderByFieldName> ::=
createddate|createdtime| createddate|createdtime|
@@ -61,6 +61,7 @@ Use [Users - Drive - Transfer](Users-Drive-Transfer) for more complex ownership
``` ```
gam <UserTypeEntity> transfer ownership <DriveFileEntity> <UserItem> gam <UserTypeEntity> transfer ownership <DriveFileEntity> <UserItem>
[<DriveFileParentAttribute>] [includetrashed] [norecursion [<Boolean>]] [<DriveFileParentAttribute>] [includetrashed] [norecursion [<Boolean>]]
[enforceexpansiveaccess [<Boolean>]]
(orderby <DriveOrderByFieldName> [ascending|descending])* (orderby <DriveOrderByFieldName> [ascending|descending])*
[preview] [filepath] [pathdelimiter <Character>] [buildtree] [todrive <ToDriveAttribute>*] [preview] [filepath] [pathdelimiter <Character>] [buildtree] [todrive <ToDriveAttribute>*]
``` ```
@@ -100,6 +101,7 @@ gam <UserTypeEntity> claim ownership <DriveFileEntity>
[skipids <DriveFileEntity>] [onlyusers|skipusers <UserTypeEntity>] [subdomains <DomainNameEntity>] [skipids <DriveFileEntity>] [onlyusers|skipusers <UserTypeEntity>] [subdomains <DomainNameEntity>]
[restricted [<Boolean>]] [writerscanshare|writerscantshare [<Boolean>]] [restricted [<Boolean>]] [writerscanshare|writerscantshare [<Boolean>]]
[keepuser | (retainrole reader|commenter|writer|editor|none)] [noretentionmessages] [keepuser | (retainrole reader|commenter|writer|editor|none)] [noretentionmessages]
[enforceexpansiveaccess [<Boolean>]]
(orderby <DriveOrderByFieldName> [ascending|descending])* (orderby <DriveOrderByFieldName> [ascending|descending])*
[preview] [filepath] [pathdelimiter <Character>] [buildtree] [todrive <ToDriveAttribute>*] [preview] [filepath] [pathdelimiter <Character>] [buildtree] [todrive <ToDriveAttribute>*]
``` ```

View File

@@ -15,7 +15,6 @@
- [Remove domainCanFind-domainWithLink ACLs for internal domain](#remove-domaincanfind-domainwithlink-acls-for-internal-domain) - [Remove domainCanFind-domainWithLink ACLs for internal domain](#remove-domaincanfind-domainwithlink-acls-for-internal-domain)
- [Remove My Drive ACLs for external domains](#remove-my-drive-acls-for-external-domains) - [Remove My Drive ACLs for external domains](#remove-my-drive-acls-for-external-domains)
- [Remove anyoneCanFind-anyoneWithLink ACLs](#remove-anyonecanfind-anyonewithlink-acls) - [Remove anyoneCanFind-anyoneWithLink ACLs](#remove-anyonecanfind-anyonewithlink-acls)
- [Target Audiences](#target-audiences)
## API documentation ## API documentation
* [Drive API - Permissions](https://developers.google.com/drive/api/v3/reference/permissions) * [Drive API - Permissions](https://developers.google.com/drive/api/v3/reference/permissions)
@@ -144,7 +143,6 @@ specify `basicpermissions` and additional permission fields, e.g., `permissions.
<FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector> <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/GAM-team/GAM/wiki/Collections-of-Items See: https://github.com/GAM-team/GAM/wiki/Collections-of-Items
``` ```
## GUI API permission name mapping ## GUI API permission name mapping
| GUI setting | API setting | | GUI setting | API setting |
@@ -220,7 +218,7 @@ By default, when an ACL is created, GAM outputs details of the ACL as indented k
``` ```
gam <UserTypeEntity> update drivefileacl <DriveFileEntity> <DriveFilePermissionIDorEmail> gam <UserTypeEntity> update drivefileacl <DriveFileEntity> <DriveFilePermissionIDorEmail>
(role <DriveFileACLRole>) [expiration <Time>] [removeexpiration [<Boolean>]] (role <DriveFileACLRole>) [expiration <Time>] [removeexpiration [<Boolean>]]
[updatesheetprotectedranges [<Boolean>]] [updatesheetprotectedranges [<Boolean>]] [enforceexpansiveaccess [<Boolean>]]
[showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])] [showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])]
``` ```
There is no change of parents when a new user is updated to be a file's owner. There is no change of parents when a new user is updated to be a file's owner.
@@ -236,7 +234,10 @@ The option `updatesheetprotectedranges` only applies to items in `<DriveFileEnti
* ACLs with role reader or commenter will be removed from existing protected ranges * ACLs with role reader or commenter will be removed from existing protected ranges
* ACLs with role writer or higher will be added to existing protected ranges * ACLs with role writer or higher will be added to existing protected ranges
Inherited ACLs can not be updated. `enforceexpansiveaccess` defaults to the value of `gam.cfg/enforce_expansive_access` that controls
the ability to update inherited ACLs.
* False - Inherited ACLs can be updated
* True = Inherited ACLs can not be updated
By default, the file ID is displayed in the output; to see the file name, use the `showtitles` By default, the file ID is displayed in the output; to see the file name, use the `showtitles`
option; this requires an additional API call per file. option; this requires an additional API call per file.
@@ -248,7 +249,7 @@ By default, when an ACL is updated, GAM outputs details of the ACL as indented k
### Delete ### Delete
``` ```
gam <UserTypeEntity> delete|del drivefileacl <DriveFileEntity> <DriveFilePermissionIDorEmail> gam <UserTypeEntity> delete|del drivefileacl <DriveFileEntity> <DriveFilePermissionIDorEmail>
[updatesheetprotectedranges [<Boolean>]] [updatesheetprotectedranges [<Boolean>]] [enforceexpansiveaccess [<Boolean>]]
[showtitles] [showtitles]
``` ```
The option `updatesheetprotectedranges` only applies to items in `<DriveFileEntity>` that are Google Sheets. The option `updatesheetprotectedranges` only applies to items in `<DriveFileEntity>` that are Google Sheets.
@@ -258,7 +259,10 @@ The option `updatesheetprotectedranges` only applies to items in `<DriveFileEnti
* Sheet Protected Ranges are updated to reflect the deleted ACL; additional API calls are required. * Sheet Protected Ranges are updated to reflect the deleted ACL; additional API calls are required.
* ACLs with any role will be removed from existing protected ranges * ACLs with any role will be removed from existing protected ranges
Inherited ACLs can not be deleted. `enforceexpansiveaccess` defaults to the value of `gam.cfg/enforce_expansive_access` that controls
the ability to delete inherited ACLs.
* False - Inherited ACLs can be deleted
* True = Inherited ACLs can not be deleted
By default, the file ID is displayed in the output; to see the file name, use the `showtitles` By default, the file ID is displayed in the output; to see the file name, use the `showtitles`
option; this requires an additional API call per file. option; this requires an additional API call per file.
@@ -300,8 +304,12 @@ When adding permissions from JSON data, permissions with `deleted` true are neve
``` ```
gam <UserTypeEntity> delete permissions <DriveFileEntity> <DriveFilePermissionIDEntity> gam <UserTypeEntity> delete permissions <DriveFileEntity> <DriveFilePermissionIDEntity>
<PermissionMatch>* [<PermissionMatchAction>] <PermissionMatch>* [<PermissionMatchAction>]
[enforceexpansiveaccess [<Boolean>]]
``` ```
Inherited ACLs can not be deleted. `enforceexpansiveaccess` defaults to the value of `gam.cfg/enforce_expansive_access` that controls
the ability to delete inherited ACLs.
* False - Inherited ACLs can be deleted
* True = Inherited ACLs can not be deleted
When deleting permissions from JSON data, permissions with role `owner` true are never processed. When deleting permissions from JSON data, permissions with role `owner` true are never processed.
@@ -349,8 +357,8 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
For example, to get the ACLs for your Team Drives with the Team Drive name included in the output: For example, to get the ACLs for your Team Drives with the Team Drive name included in the output:
``` ```
gam redirect csv ./SharedDrives.csv print shareddrives gam redirect csv ./TeamDrives.csv print teamdrives
gam redirect csv ./SharedDriveACLs.csv multiprocess csv ./SharedDrives.csv gam print drivefileacls shareddriveid "~id" addtitle "~name" fields id,domain,emailaddress,role,type,deleted gam redirect csv ./TeamDriveACLs.csv multiprocess csv ./TeamDrives.csv gam print drivefileacls teamdriveid "~id" addtitle "~name" fields id,domain,emailaddress,role,type,deleted
``` ```
## Delete all ACLs except owner from a file ## Delete all ACLs except owner from a file
@@ -608,51 +616,3 @@ Delete those Shared Drive ACLs.
``` ```
gam config num_threads 20 redirect stdout ./DeleteSharedDriveShares.txt multiprocess redirect stderr stdout csv SharedDriveShares.csv gam user "~Owner" delete drivefileacl "~id" "id:~~permission.id~~" gam config num_threads 20 redirect stdout ./DeleteSharedDriveShares.txt multiprocess redirect stderr stdout csv SharedDriveShares.csv gam user "~Owner" delete drivefileacl "~id" "id:~~permission.id~~"
``` ```
## Target Audiences
* See: https://support.google.com/a/answer/9934697
You can manage target audiences in the admin console at Directory/Target audiences.
If you click on a target audience the URL will look like this: `https://admin.google.com/ac/targetaudiences/02xcytpi0xrdqxi`
You can add this target audience to a file with:
```
gam user user@domain.com create drivefileacl <DriveFileID> domain 02xcytpi0xrdqxi.audience.googledomains.com role reader
User: user@domain.com, Add 1 Drive File/Folder ACL
User: user@domain.com, Drive File/Folder ID: <DriveFileID>, Permission ID: 02xcytpi0xrdqxi.audience.googledomains.com, Added
Test Audience
id: 02897912034288871303
type: domain
domain: 02xcytpi0xrdqxi.audience.googledomains.com
role: reader
permissionDetails:
role: reader
type: file
inherited: False
allowFileDiscovery: False
```
You can update the target audience role with:
```
gam user user@domain.com update drivefileacl <DriveFileID> id:02897912034288871303 role writer
User: user@domain.com, Update 1 Drive File/Folder ACL
User: user@domain.com, Drive File/Folder ID: <DriveFileID>, Permission ID: 02897912034288871303, Updated
Test Audience
id: 02897912034288871303
type: domain
domain: 02xcytpi0xrdqxi.audience.googledomains.com
role: writer
permissionDetails:
role: writer
type: file
inherited: False
allowFileDiscovery: False
```
You can delete the target audience from a file with:
```
gam user user@domain.com delete drivefileacl <DriveFileID> id:02897912034288871303
User: user@domain.com, Delete 1 Drive File/Folder ACL
User: user@domain.com, Drive File/Folder ID: <DriveFileID>, Permission ID: 02897912034288871303, Deleted
```

View File

@@ -26,10 +26,10 @@
(parentid <DriveFolderID>)| (parentid <DriveFolderID>)|
(parentname <DriveFolderName>)| (parentname <DriveFolderName>)|
(anyownerparentname <DriveFolderName>)| (anyownerparentname <DriveFolderName>)|
(shareddriveparentid <DriveFolderID>)| (teamdriveparentid <DriveFolderID>)|
(shareddriveparent <SharedDriveName>)| (teamdriveparent <SharedDriveName>)|
(shareddriveparentid <SharedDriveID> shareddriveparentname <DriveFolderName>)| (teamdriveparentid <SharedDriveID> teamdriveparentname <DriveFolderName>)|
(shareddriveparent <SharedDriveName> shareddriveparentname <DriveFolderName>) (teamdriveparent <SharedDriveName> teamdriveparentname <DriveFolderName>)
``` ```
## Create shortcuts ## Create shortcuts
@@ -48,10 +48,10 @@ There are two modes of operaton:
* `parentid <DriveFolderID>` - Folder ID. * `parentid <DriveFolderID>` - Folder ID.
* `parentname <DriveFolderName>` - Folder name; the folder must be owned by `<UserTypeEntity>`. * `parentname <DriveFolderName>` - Folder name; the folder must be owned by `<UserTypeEntity>`.
* `anyownerparentname <DriveFolderName>` - Folder name; the folder can be owned by any user, `<UserTypeEntity>` must be able to write to the folder. * `anyownerparentname <DriveFolderName>` - Folder name; the folder can be owned by any user, `<UserTypeEntity>` must be able to write to the folder.
* `shareddriveparentid <DriveFolderID>` - Shared Drive folder ID; when used alone, this indicates a specfic Shared Drive folder. * `teamdriveparentid <DriveFolderID>` - Shared Drive folder ID; when used alone, this indicates a specfic Shared Drive folder.
* `shareddriveparent <SharedDriveName>` - Shared Drive name; when used alone, this indicates the root level of the Shared Drive. * `teamdriveparent <SharedDriveName>` - Shared Drive name; when used alone, this indicates the root level of the Shared Drive.
* `shareddriveparentid <SharedDriveID> shareddriveparentname <DriveFolderName>` - A Shared Drive ID and a folder name on that Shared Drive. * `teamdriveparentid <SharedDriveID> teamdriveparentname <DriveFolderName>` - A Shared Drive ID and a folder name on that Shared Drive.
* `shareddriveparent <SharedDriveName> shareddriveparentname <DriveFolderName>` - A Shared Drive name and a folder name on that Shared Drive. * `teamdriveparent <SharedDriveName> teamdriveparentname <DriveFolderName>` - A Shared Drive name and a folder name on that Shared Drive.
* `convertparents` - Convert all but the last parent reference in `<DriveFileEntity>` to shortcuts. My testing shows that as parents are added to a file, they are added to the front of the parents list; thus, the last parent is the original parent. * `convertparents` - Convert all but the last parent reference in `<DriveFileEntity>` to shortcuts. My testing shows that as parents are added to a file, they are added to the front of the parents list; thus, the last parent is the original parent.
If neither `<DriveFileParentAttribute>` nor `convertparents` are specified, the shortcut is placed in the root folder (My Drive). If neither `<DriveFileParentAttribute>` nor `convertparents` are specified, the shortcut is placed in the root folder (My Drive).
@@ -142,6 +142,6 @@ gam csv Shortcuts.csv matchfield code 4 gam user "~owner" create drivefileshortc
## Check shortcut validity on Shared Drives ## Check shortcut validity on Shared Drives
``` ```
gam redirect csv ./TDShortcuts.csv user organizer@domain.com print filelist select shareddriveid <SharedDriveID> showmimetype gshortcut fields id gam redirect csv ./TDShortcuts.csv user organizer@domain.com print filelist select teamdriveid <SharedDriveID> showmimetype gshortcut fields id
gam redirect csv ./Shortcuts.csv user organizer@domain.com check drivefileshortcut csvfile TDShortcuts.csv:id csv gam redirect csv ./Shortcuts.csv user organizer@domain.com check drivefileshortcut csvfile TDShortcuts.csv:id csv
``` ```

View File

@@ -48,6 +48,7 @@ gam <UserTypeEntity> transfer drive <UserItem> [select <DriveFileEntity>]
[noretentionmessages] [noretentionmessages]
[nonowner_retainrole reader|commenter|writer|editor|contentmanager|fileorganizer|current|none] [nonowner_retainrole reader|commenter|writer|editor|contentmanager|fileorganizer|current|none]
[nonowner_targetrole reader|commenter|writer|editor|contentmanager|fileorganizer|current|none|source] [nonowner_targetrole reader|commenter|writer|editor|contentmanager|fileorganizer|current|none|source]
[enforceexpansiveaccess [<Boolean>]]
(orderby <DriveFileOrderByFieldName> [ascending|descending])* (orderby <DriveFileOrderByFieldName> [ascending|descending])*
[preview] [todrive <ToDriveAttribute>*] [preview] [todrive <ToDriveAttribute>*]
``` ```

View File

@@ -430,6 +430,8 @@ user@domain.com,18e9fc6581b9acab,Archived,
user@domain.com,18e9fc58c5491f4c,Archived, user@domain.com,18e9fc58c5491f4c,Archived,
``` ```
See below for message selection.
## Export messages/threads ## Export messages/threads
Export messages in EML format. Export messages in EML format.
``` ```
@@ -462,18 +464,7 @@ By default, when exporting a message, an existing local file will not be overwri
* `overwrite true` - Overwite an existing file * `overwrite true` - Overwite an existing file
* `overwrite false` - Do not overwite an existing file; add a numeric prefix and create a new file * `overwrite false` - Do not overwite an existing file; add a numeric prefix and create a new file
### Export a specific set of messages See below for message selection.
* `ids <MessageIDEntity>` - A list of message ids
### Export a selected set of messages
* `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
* `labelids <LabelIDList>` - Select messages with labels that match all of the specified label IDs.
* `max_to_export <Number>` - Limit the number of messages that will be exported; use a value of 0 for no limit
When `matchlabel <LabelName>` is specified, the following characters are replaced with a `-` in the generated query.
```
&()"|{}/
```
## Forward messages/threads ## Forward messages/threads
``` ```
@@ -501,19 +492,7 @@ If `addorigfieldstosubject` is specified, GAM appends the original `from`, `to`
Fwd: Ross to TestUser (Original From: Ross Scroggs <ross.scroggs@gmail.com> To: testuser@domain.com Date: Thu, 23 Nov 2023 07:01:59 -0800) Fwd: Ross to TestUser (Original From: Ross Scroggs <ross.scroggs@gmail.com> To: testuser@domain.com Date: Thu, 23 Nov 2023 07:01:59 -0800)
``` ```
### Forward a specific set of messages See below for message selection.
* `ids <MessageIDEntity>` - A list of message ids
### Forward a selected set of messages
* `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
* `labelids <LabelIDList>` - Select messages with labels that match all of the specified label IDs.
* `max_to_forward <Number>` - Limit the number of messages that will be forwarded; use a value of 0 for no limit
* `doit` - No messages are processed unless you specify `doit`. By not specifying `doit`, you can preview the messages selected to verify that the results match your expectations.
When `matchlabel <LabelName>` is specified, the following characters are replaced with a `-` in the generated query.
```
&()"|{}/
```
## Manage messages/threads ## Manage messages/threads
``` ```

View File

@@ -1,6 +1,5 @@
# Users - Photo # Users - Photo
- [API documentation](#api-documentation) - [API documentation](#api-documentation)
- [Notes](#notes)
- [Definitions](#definitions) - [Definitions](#definitions)
- [Upload a user's photo from a default file](#upload-a-users-photo-from-a-default-file) - [Upload a user's photo from a default file](#upload-a-users-photo-from-a-default-file)
- [Upload a user's photo specifying file name](#upload-a-users-photo-specifying-file-name) - [Upload a user's photo specifying file name](#upload-a-users-photo-specifying-file-name)
@@ -8,16 +7,11 @@
- [Upload a user's photo specifying a Google Drive owner and file name](#upload-a-users-photo-specifying-a-google-drive-owner-and-file-name) - [Upload a user's photo specifying a Google Drive owner and file name](#upload-a-users-photo-specifying-a-google-drive-owner-and-file-name)
- [Download a user's photo](#download-a-users-photo) - [Download a user's photo](#download-a-users-photo)
- [Delete a user's photo](#delete-a-users-photo) - [Delete a user's photo](#delete-a-users-photo)
- [Update photo fails to change user's photo](#update-photo-fails-to-change-users-photo)
- [Download a user's profile photo](Users-Profile-Photo) - [Download a user's profile photo](Users-Profile-Photo)
## API documentation ## API documentation
* [Directory API - Users Photos](https://developers.google.com/admin-sdk/directory/reference/rest/v1/users.photos) * [Directory API - Users Photos](https://developers.google.com/admin-sdk/directory/reference/rest/v1/users.photos)
## Notes
As of version 7.34.09, `gam <UserTypeEntity> update photo` was updated to delete the user's existing photo
before performing the update as the API update will succeed but not replace a user's existing self-set photo.
## Definitions ## Definitions
* [`<DriveFileEntity>`](Drive-File-Selection) * [`<DriveFileEntity>`](Drive-File-Selection)
* [`<UserTypeEntity>`](Collections-of-Users) * [`<UserTypeEntity>`](Collections-of-Users)
@@ -87,7 +81,3 @@ By default, the Base64 encoded data is dumped to stdout.
``` ```
gam <UserTypeEntity> delete|del photo gam <UserTypeEntity> delete|del photo
``` ```
## Update photo fails to change user's photo
If you use `gam <UserTypeEntity> update photo ...` to change a user's photo and the command succeeds
but the photo doesn't change, use `gam <UserTypeEntity> delete photo` first and then do the update.

View File

@@ -148,8 +148,6 @@
<CSVkmdSelector> | <CSVkmdSelector> |
<CSVDataSelector> <CSVDataSelector>
<QuerySharedDrive> ::= <String> See: https://developers.google.com/workspace/drive/api/guides/search-shareddrives
<SharedDriveACLRole> ::= <SharedDriveACLRole> ::=
manager|organizer|owner| manager|organizer|owner|
contentmanager|fileorganizer| contentmanager|fileorganizer|
@@ -161,8 +159,8 @@
<SharedDriveName> ::= <String> <SharedDriveName> ::= <String>
<SharedDriveEntity> ::= <SharedDriveEntity> ::=
<SharedDriveID>| <SharedDriveID>|
(shareddriveid <SharedDriveID>)|(shareddriveid:<SharedDriveID>)| (teamdriveid <SharedDriveID>)|(teamdriveid:<SharedDriveID>)|
(shareddrive <SharedDriveName>)|(shareddrive:<SharedDriveName>) (teamdrive <SharedDriveName>)|(teamdrive:<SharedDriveName>)
<SharedDriveFieldName> ::= <SharedDriveFieldName> ::=
backgroundimagefile| backgroundimagefile|
@@ -176,10 +174,10 @@
themeid themeid
<SharedDriveFieldNameList> ::= "<SharedDriveFieldName>(,<SharedDriveFieldName>)*" <SharedDriveFieldNameList> ::= "<SharedDriveFieldName>(,<SharedDriveFieldName>)*"
<SharedDriveIDEntity> ::= (shareddriveid <DriveFileItem>) | (shareddriveid:<DriveFileItem>) <SharedDriveIDEntity> ::= (teamdriveid <DriveFileItem>) | (teamdriveid:<DriveFileItem>)
<SharedDriveNameEntity> ::= (shareddrive <SharedDriveName>) | (shareddrive:<SharedDriveName>) <SharedDriveNameEntity> ::= (teamdrive <SharedDriveName>) | (teamdrive:<SharedDriveName>)
<SharedDriveFileNameEntity> ::= (shareddrivefilename <DriveFileName>) | (shareddrivefilename:<DriveFileName>) <SharedDriveFileNameEntity> ::= (teamdrivefilename <DriveFileName>) | (teamdrivefilename:<DriveFileName>)
<SharedDriveFileQueryEntity> ::= (shareddrivequery <QueryDriveFile>) | (shareddrivequery:<QueryDriveFile>) <SharedDriveFileQueryEntity> ::= (teamdrivequery <QueryDriveFile>) | (teamdrivequery:<QueryDriveFile>)
<SharedDriveFileQueryShortcut> ::= <SharedDriveFileQueryShortcut> ::=
all_files | all_folders | all_google_files | all_non_google_files | all_items all_files | all_folders | all_google_files | all_non_google_files | all_items
@@ -293,11 +291,11 @@ When either of these options is chosen, no infomation about Shared Drive restric
To retrieve the Shared Drive ID with `returnidonly`: To retrieve the Shared Drive ID with `returnidonly`:
``` ```
Linux/MacOS Linux/MacOS
shareddriveId=$(gam user user@domain.com create shareddrive ... returnidonly) teamDriveId=$(gam user user@domain.com create shareddrive ... returnidonly)
Windows PowerShell Windows PowerShell
$shareddriveId = & gam user user@domain.com create shareddrive ... returnidonly $teamDriveId = & gam user user@domain.com create shareddrive ... returnidonly
Windows Command Prompt Windows Command Prompt
for /f "delims=" %a in ('gam user user@domain.com create shareddrive ... returnidonly') do set shareddriveId=%a for /f "delims=" %a in ('gam user user@domain.com create shareddrive ... returnidonly') do set teamDriveId=%a
``` ```
## Bulk Create Shared Drives ## Bulk Create Shared Drives
@@ -419,12 +417,12 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
Display the number of Shared Drives. Display the number of Shared Drives.
``` ```
gam <UserTypeEntity> show|print shareddrives gam <UserTypeEntity> show|print shareddrives
[shareddriveadminquery|query <QuerySharedDrive>] [teamdriveadminquery|query <QueryTeamDrive>]
[matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
showitemcountonly showitemcountonly
``` ```
By default, all Shared Drives are counted; use the following options to select a subset of Shared Drives: By default, all Shared Drives are counted; use the following options to select a subset of Shared Drives:
* `shareddriveadminquery|query <QuerySharedDrive>` - Use a query to select Shared Drives * `teamdriveadminquery|query <QueryTeamDrive>` - Use a query to select Shared Drives
* `matchname <REMatchPattern>` - Retrieve Shared Drives with names that match a pattern. * `matchname <REMatchPattern>` - Retrieve Shared Drives with names that match a pattern.
* `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected * `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected
@@ -468,7 +466,7 @@ Options `shareddriveadminquery|query` and `shareddrives|teamdrives` are mutually
Options `shareddriveadminquery|query` and `orgunit|org|ou` require `adminaccess|asadmin`. Options `shareddriveadminquery|query` and `orgunit|org|ou` require `adminaccess|asadmin`.
By default, organizers for all Shared Drives are displayed; use the following options to select a subset of Shared Drives: By default, organizers for all Shared Drives are displayed; use the following options to select a subset of Shared Drives:
* `shareddriveadminquery|query <QueryTeamDrive>` - Use a query to select Shared Drives * `teamdriveadminquery|query <QueryTeamDrive>` - Use a query to select Shared Drives
* `shareddrives|teamdrives <SharedDriveIDList>` - Select the Shared Drive IDs specified in `<SharedDriveIDList>` * `shareddrives|teamdrives <SharedDriveIDList>` - Select the Shared Drive IDs specified in `<SharedDriveIDList>`
* `shareddrives|teamdrives select <FileSelector>|<CSVFileSelector>` - Select the Shared Drive IDs specified in `<FileSelector>|<CSVFileSelector>` * `shareddrives|teamdrives select <FileSelector>|<CSVFileSelector>` - Select the Shared Drive IDs specified in `<FileSelector>|<CSVFileSelector>`
* `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected * `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected
@@ -488,7 +486,7 @@ To select organizers from any domain, use: `domainlist ""`
For example, to get a single user organizer from your domain for all Shared Drives including no organizer drives: For example, to get a single user organizer from your domain for all Shared Drives including no organizer drives:
``` ```
gam redirect csv ./ShareddriveOrganizers.csv print shareddriveorganizers gam redirect csv ./TeamDriveOrganizers.csv print shareddriveorganizers
``` ```
## Manage Shared Drive access ## Manage Shared Drive access
@@ -598,14 +596,14 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
## Display Shared Drive access for selected Shared Drives ## Display Shared Drive access for selected Shared Drives
``` ```
gam <UserTypeEntity> show shareddriveacls gam <UserTypeEntity> show shareddriveacls
adminaccess [shareddriveadminquery|query <QuerySharedDrive>] adminaccess [teamdriveadminquery|query <QueryTeamDrive>]
[matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
[user|group <EmailAddress> [checkgroups]] (role|roles <SharedDriveACLRoleList>)* [user|group <EmailAddress> [checkgroups]] (role|roles <SharedDriveACLRoleList>)*
<PermissionMatch>* [<PermissionMatchAction>] [pmselect] <PermissionMatch>* [<PermissionMatchAction>] [pmselect]
[oneitemperrow] [<DrivePermissionsFieldName>*|(fields <DrivePermissionsFieldNameList>)] [oneitemperrow] [<DrivePermissionsFieldName>*|(fields <DrivePermissionsFieldNameList>)]
[formatjson [quotechar <Character>]] [formatjson [quotechar <Character>]]
gam <UserTypeEntity> print shareddriveacls [todrive <ToDriveAttribute>*] gam <UserTypeEntity> print shareddriveacls [todrive <ToDriveAttribute>*]
adminaccess [shareddriveadminquery|query <QuerySharedDrive>] adminaccess [teamdriveadminquery|query <QueryTeamDrive>]
[matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
[user|group <EmailAddress> [checkgroups]] (role|roles <SharedDriveACLRoleList>)* [user|group <EmailAddress> [checkgroups]] (role|roles <SharedDriveACLRoleList>)*
<PermissionMatch>* [<PermissionMatchAction>] [pmselect] <PermissionMatch>* [<PermissionMatchAction>] [pmselect]
@@ -617,7 +615,7 @@ Shared Drives in the workspace, `<UserTypeEntity>` should specify a super admin
option shoud be used. option shoud be used.
By default, all Shared Drives are displayed; use the following options to select a subset of Shared Drives: By default, all Shared Drives are displayed; use the following options to select a subset of Shared Drives:
* `shareddriveadminquery|query <QuerySharedDrive>` - Use a query to select Shared Drives * `teamdriveadminquery|query <QueryTeamDrive>` - Use a query to select Shared Drives
* `matchname <REMatchPattern>` - Retrieve Shared Drives with names that match a pattern. * `matchname <REMatchPattern>` - Retrieve Shared Drives with names that match a pattern.
* `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected * `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected
* `<PermissionMatch>* [<PermissionMatchAction>] pmselect` - Use permission matching to select Shared Drives * `<PermissionMatch>* [<PermissionMatchAction>] pmselect` - Use permission matching to select Shared Drives

View File

@@ -1,6 +1,5 @@
# Users - Tokens # Users - Tokens
- [API documentation](#api-documentation) - [API documentation](#api-documentation)
- [Get Google Cloud organization ID for your workspace](#get-google-cloud-organization-id-for-your-workspace)
- [Definitions](#definitions) - [Definitions](#definitions)
- [Delete a user's token](#delete-a-users-token) - [Delete a user's token](#delete-a-users-token)
- [Display individual user's tokens](#display-individual-users-tokens) - [Display individual user's tokens](#display-individual-users-tokens)
@@ -10,15 +9,6 @@
## API documentation ## API documentation
* [Directory API - Tokens](https://developers.google.com/admin-sdk/directory/reference/rest/v1/tokens) * [Directory API - Tokens](https://developers.google.com/admin-sdk/directory/reference/rest/v1/tokens)
## Get Google Cloud organization ID for your workspace
This ID is used by `gam print|show token gcpdetails`; to eliminate additional API calls,
you can get the value and store it in the `gam.cfg/gcp_org_id` variable.
```
$ gam info gcporgid
organizations/906207637890
$ gam config gcp_org_id organizations/906207637890 save
```
## Definitions ## Definitions
* [`<UserTypeEntity>`](Collections-of-Users) * [`<UserTypeEntity>`](Collections-of-Users)
@@ -33,18 +23,14 @@ gam <UserTypeEntity> delete|del token|tokens clientid <ClientID>
``` ```
gam <UserTypeEntity> print tokens|token [todrive <ToDriveAttributes>*] [clientid <ClientID>] gam <UserTypeEntity> print tokens|token [todrive <ToDriveAttributes>*] [clientid <ClientID>]
[orderby clientid|id|appname|displaytext] [delimiter <Character>] [orderby clientid|id|appname|displaytext] [delimiter <Character>]
[gcpdetails]
gam <UserTypeEntity> show tokens|token|3lo|oauth [clientid <ClientID>] gam <UserTypeEntity> show tokens|token|3lo|oauth [clientid <ClientID>]
[orderby clientid|id|appname|displaytext] [orderby clientid|id|appname|displaytext]
[gcpdetails]
gam print tokens|token [todrive <ToDriveAttributes>*] [clientid <ClientID>] gam print tokens|token [todrive <ToDriveAttributes>*] [clientid <ClientID>]
[orderby clientid|id|appname|displaytext] [delimiter <Character>] [orderby clientid|id|appname|displaytext] [delimiter <Character>]
[<UserTypeEntity>] [<UserTypeEntity>]
[gcpdetails]
gam show tokens|token [clientid <ClientID>] gam show tokens|token [clientid <ClientID>]
[orderby clientid|id|appname|displaytext] [delimiter <Character>] [orderby clientid|id|appname|displaytext] [delimiter <Character>]
[<UserTypeEntity>] [<UserTypeEntity>]
[gcpdetails]
``` ```
By default, all client tokens for a user are displayed, use `clientid <ClientID>` to display a specific client token. By default, all client tokens for a user are displayed, use `clientid <ClientID>` to display a specific client token.
@@ -52,9 +38,6 @@ For each user, select the order of token presentation:
* `orderby clientid|id` - Display each user's tokens ordered by Client ID * `orderby clientid|id` - Display each user's tokens ordered by Client ID
* `orderby appname|displaytext` - Display each user's tokens ordered by App Name * `orderby appname|displaytext` - Display each user's tokens ordered by App Name
Use `gcpdetails` to get project information about the client; you get the project number
and whether it is an internal project. In order to accurately determine if a project is internal, your GAM admin user must have at least the `Browser` [IAM role for the entire GCP organization](https://docs.cloud.google.com/iam/docs/roles-permissions/browser) which allows them to lookup basic metadata about your organization projects. If your admin is not able to see all GCP projects in your organization results may not be accurate.
For `print tokens`: For `print tokens`:
* `delimiter <Character>` - Separate `scopes` entries with `<Character>`; the default value is `csv_output_field_delimiter` from `gam.cfg`. * `delimiter <Character>` - Separate `scopes` entries with `<Character>`; the default value is `csv_output_field_delimiter` from `gam.cfg`.

View File

@@ -40,7 +40,6 @@
- [Print user list](#print-user-list) - [Print user list](#print-user-list)
- [Display user counts](#display-user-counts) - [Display user counts](#display-user-counts)
- [Verify domain membership](#verify-domain-membership) - [Verify domain membership](#verify-domain-membership)
- [Guest Users](#guest-users)
## API documentation ## API documentation
* [Directory API - Users](https://developers.google.com/admin-sdk/directory/reference/rest/v1/users) * [Directory API - Users](https://developers.google.com/admin-sdk/directory/reference/rest/v1/users)
@@ -170,7 +169,6 @@ queries "`"orgUnitPath=\'/Students/Lower\ School/2027\'`",`"orgUnitPath=\'/Stude
fullname| fullname|
gender| gender|
givenname|firstname| givenname|firstname|
guestaccountinfo|
id| id|
ims|im| ims|im|
includeinglobaladdresslist|gal| includeinglobaladdresslist|gal|
@@ -178,7 +176,6 @@ queries "`"orgUnitPath=\'/Students/Lower\ School/2027\'`",`"orgUnitPath=\'/Stude
isdelegatedadmin|admin|isadmin| isdelegatedadmin|admin|isadmin|
isenforcedin2sv|is2svenforced| isenforcedin2sv|is2svenforced|
isenrolledin2sv|is2svenrolled| isenrolledin2sv|is2svenrolled|
isguestuser|
ismailboxsetup| ismailboxsetup|
keyword|keywords| keyword|keywords|
language|languages| language|languages|
@@ -329,20 +326,6 @@ You can remove all instances of a `<UserMultiAttribute>` with `<UserClearAttribu
<UserMultiAttribute>| <UserMultiAttribute>|
<UserClearAttribute> <UserClearAttribute>
``` ```
```
<UserMultiAttributeFilterName> ::=
address|addresses|
externalid|externalids|
im|ims|
keyword|keywords|
location|locations|
orgainzation|organizations|
otheremail|otheremails|
phone|phones|
relation|relations|
website|websites
```
## Admin Console User Info ## Admin Console User Info
When defining a user in the admin console, there is a section labelled `Employee information` with the following items: When defining a user in the admin console, there is a section labelled `Employee information` with the following items:
* `Employee ID` * `Employee ID`
@@ -666,7 +649,7 @@ If the mailbox is setup, a zero return code is returned; if the retries are exha
``` ```
gam update user <UserItem> [ignorenullpassword] <UserAttribute>* gam update user <UserItem> [ignorenullpassword] <UserAttribute>*
[verifynotinvitable|alwaysevict] [noactionifalias] [verifynotinvitable|alwaysevict] [noactionifalias]
[updateprimaryemail <RESearchPattern> <RESubstitution> [preview]] [updateprimaryemail <RESearchPattern> <RESubstitution>]
[updateoufromgroup <FileName> [charset <Charset>] [updateoufromgroup <FileName> [charset <Charset>]
[columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>] [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
[fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]] [fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]]
@@ -688,7 +671,7 @@ gam update user <UserItem> [ignorenullpassword] <UserAttribute>*
[logpassword <FileName>] [logpassword <FileName>]
gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>* gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>*
[verifynotinvitable|alwaysevict] [noactionifalias] [verifynotinvitable|alwaysevict] [noactionifalias]
[updateprimaryemail <RESearchPattern> <RESubstitution> [preview]] [updateprimaryemail <RESearchPattern> <RESubstitution>]
[updateoufromgroup <FileName> [charset <Charset>] [updateoufromgroup <FileName> [charset <Charset>]
[columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>] [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
[fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]] [fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]]
@@ -709,7 +692,7 @@ gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>*
[logpassword <FileName>] [logpassword <FileName>]
gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>* gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>*
[verifynotinvitable|alwaysevict] [noactionifalias] [verifynotinvitable|alwaysevict] [noactionifalias]
[updateprimaryemail <RESearchPattern> <RESubstitution> [preview]] [updateprimaryemail <RESearchPattern>`< <RESubstitution>]
[updateoufromgroup <FileName> [charset <Charset>] [updateoufromgroup <FileName> [charset <Charset>]
[columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>] [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
[fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]] [fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]]
@@ -812,18 +795,16 @@ You can simply update a user's primary email address with the `primaryemail` opt
``` ```
gam update user userold@domain.com primaryemail usernew@domain.com gam update user userold@domain.com primaryemail usernew@domain.com
``` ```
The `updateprimaryemail <RESearchPattern> <RESubstitution> [preview]` option allows modification of the user's current primary email address. The `updateprimaryemail <RESearchPattern> <RESubstitution>` option allows modification of the user's current primary email address.
For example, to change the domain of a set of users from the current domain.com to newdomain.com: For example, to change the domain of a set of users from the current domain to newdomain.com:
``` ```
gam ou /Path/To/Ou update user updateprimaryemail "^(.+)@domain.com$" "\1@newdomain.com" gam ou /Path/To/Ou update user updateprimaryemail "^(.+)@.*$" "\1@newdomain.com"
``` ```
To change graduating students email addresses from flastname@domain.com to flastname_grad@domain.com: To change graduating students email addresses from flastname@domain.com to flastname_grad@domain.com:
``` ```
gam ou /Path/To/Ou update user updateprimaryemail "^(.+)@(.+)$" "\1_grad@\2" gam ou /Path/To/Ou update user updateprimaryemail "^(.+)@(.+)$" "\1_grad@\2"
``` ```
The `preview` option allows verification of the primary email address changes before commiting the changes.
If the user's current primary email address does not match the <REMatchPattern> then no modification is made. If the user's current primary email address does not match the <REMatchPattern> then no modification is made.
## Update a user's attributes with JSON data ## Update a user's attributes with JSON data
@@ -987,8 +968,6 @@ gam info user [<UserItem>]
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)] [(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)] [noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
[userview] <UserFieldName>* [fields <UserFieldNameList>] [userview] <UserFieldName>* [fields <UserFieldNameList>]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[formatjson] [formatjson]
``` ```
### Display information about multiple users ### Display information about multiple users
@@ -1002,8 +981,6 @@ gam info users <UserTypeEntity>
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)] [(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)] [noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
[userview] <UserFieldName>* [fields <UserFieldNameList>] [userview] <UserFieldName>* [fields <UserFieldNameList>]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[formatjson] [formatjson]
gam <UserTypeEntity> info users gam <UserTypeEntity> info users
[quick] [quick]
@@ -1014,8 +991,6 @@ gam <UserTypeEntity> info users
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)] [(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)] [noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
[userview] <UserFieldName>* [fields <UserFieldNameList>] [userview] <UserFieldName>* [fields <UserFieldNameList>]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[formatjson] [formatjson]
``` ```
For `info users`, unlike all other GAM commands, a `<UserTypeEntity>` value of `all users` is actually `all users_ns_susp` not `all users_ns`. For `info users`, unlike all other GAM commands, a `<UserTypeEntity>` value of `all users` is actually `all users_ns_susp` not `all users_ns`.
@@ -1053,11 +1028,6 @@ By default, Gam displays fields that only an adminstrator can view.
By default, Gam displays all fields for a user. By default, Gam displays all fields for a user.
* `<UserFieldName>* [fields <UserFieldNameList>]` - Only display selected fields. * `<UserFieldName>* [fields <UserFieldNameList>]` - Only display selected fields.
By default, all instances of `<UserMultiAttribute>` are displayed, use these options to only display instances
of a specified `type` or `customType`.
* `filtermultiattrtype <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `type` is `<String>`
* `filtermultiattrcustom <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `customType` is `<String>`
By default, Gam displays the information as an indented list of keys and values. By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format. * `formatjson` - Display the fields in JSON format.
@@ -1089,8 +1059,6 @@ gam print users [todrive <ToDriveAttribute>*]
[schemas|custom|customschemas all|<SchemaNameList>] [schemas|custom|customschemas all|<SchemaNameList>]
[emailpart|emailparts|username] [emailpart|emailparts|username]
[userview] [allfields|basic|full|(<UserFieldName>*|fields <UserFieldNameList>)] [userview] [allfields|basic|full|(<UserFieldName>*|fields <UserFieldNameList>)]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]] [delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
[formatjson [quotechar <Character>]] [quoteplusphonenumbers] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>] [issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
@@ -1117,8 +1085,6 @@ gam print users [todrive <ToDriveAttribute>*] select <UserTypeEntity>
[schemas|custom|customschemas all|<SchemaNameList>] [schemas|custom|customschemas all|<SchemaNameList>]
[emailpart|emailparts|username] [emailpart|emailparts|username]
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)] [userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]] [delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
[formatjson [quotechar <Character>]] [quoteplusphonenumbers] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>] [issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
@@ -1133,8 +1099,6 @@ gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
[schemas|custom|customschemas all|<SchemaNameList>] [schemas|custom|customschemas all|<SchemaNameList>]
[emailpart|emailparts|username] [emailpart|emailparts|username]
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)] [userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]] [delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
[formatjson [quotechar <Character>]] [quoteplusphonenumbers] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>] [issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
@@ -1170,11 +1134,6 @@ By default, Gam displays only the primary email address for each user.
* `schemas|custom all` - Display custom schema information for all schemas. * `schemas|custom all` - Display custom schema information for all schemas.
* `schemas|custom <SchemaNameList>` - Display all fields or selected fields of the specified custom schemas * `schemas|custom <SchemaNameList>` - Display all fields or selected fields of the specified custom schemas
By default, all instances of `<UserMultiAttribute>` are displayed, use these options to only display instances
of a specified `type` or `customType`.
* `filtermultiattrtype <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `type` is `<String>`
* `filtermultiattrcustom <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `customType` is `<String>`
By default, when aliases are displayed, all aliases are displayed. Use `aliasmatchpattern <REMatchPattern>` By default, when aliases are displayed, all aliases are displayed. Use `aliasmatchpattern <REMatchPattern>`
to limit the display of aliases to those that match `<REMatchPattern>`. to limit the display of aliases to those that match `<REMatchPattern>`.
@@ -1425,11 +1384,3 @@ testuser1@domain.com,118080758787650801331,True,Test User 1
testuserxxx@domain.com,,False,Test User XXX testuserxxx@domain.com,,False,Test User XXX
testuser2@domain.com,107344800159717682514,True,Test User 2 testuser2@domain.com,107344800159717682514,True,Test User 2
``` ```
## Guest Users
* See: https://support.google.com/a/answer/16558545
```
gam create guestuser <EmailAddress>
```
Guest users are in the OU "/Workspace guests".

View File

@@ -11,7 +11,7 @@ It's important to confirm you are always running an official GAM7 release. The f
# GitHub Attestation (Linux/MacOS/Windows) # GitHub Attestation (Linux/MacOS/Windows)
GitHub offers [artifict attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds) which prove if a given GAM binary or archive was built by the [GAM-team/GAM](https://gitHub.com/GAM-team/GAM) project and links to the build job. This offers you certainty that the GAM executable you are running or the GAM package you downloaded were officially generated by the [GAM-team/GAM](https://gitHub.com/GAM-team/GAM) project. GitHub offers [artifict attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds) which prove if a given GAM binary or archive was built by the [GAM-team/GAM](https://gitHub.com/GAM-team/GAM) project and links to the build job. This offers you certainty that the GAM executable you are running or the GAM package you downloaded were officially generated by the [GAM-team/GAM](https://gitHub.com/GAM-team/GAM) project.
To verify a given GAM executable file or package (.zip, .exe or .tar.xz) is legitimate, use the following steps: To verify a given GAM executable file or package (.zip, .msi or .tar.xz) is legitimate, use the following steps:
1. Install the [GitHub CLI command line tool](https://github.com/cli/cli#installation). 1. Install the [GitHub CLI command line tool](https://github.com/cli/cli#installation).
2. Login to the tool with the command. You need a [free GitHub account](https://gitHub.com/join) for this. 2. Login to the tool with the command. You need a [free GitHub account](https://gitHub.com/join) for this.
``` ```
@@ -27,7 +27,7 @@ gh attestation verify --repo GAM-team/GAM --format=json \
4. If the GAM file or package is legit you'll see output like: 4. If the GAM file or package is legit you'll see output like:
``` ```
Loaded digest sha256:a63dc5e71c0b3335865877fc7dc9248bbf7481d22995c18253a2ae71fcb9793a for file://gam-7.00.00-windows-x86_64.exe Loaded digest sha256:a63dc5e71c0b3335865877fc7dc9248bbf7481d22995c18253a2ae71fcb9793a for file://gam-7.00.00-windows-x86_64.msi
Loaded 1 attestation from GitHub API Loaded 1 attestation from GitHub API
✓ Verification succeeded! ✓ Verification succeeded!
@@ -77,7 +77,7 @@ origin=Developer ID Application: Jay Lee (GZ85H2DRLM)
If you do not see "accepted" and "Jay Lee" as the developer ID, there may be a problem. Please report any suspicious files or concerns to the [GAM Group](https://groups.google.com/g/google-apps-manager) or the [GAM Chat Space](https://git.io/gam-chat). If you do not see "accepted" and "Jay Lee" as the developer ID, there may be a problem. Please report any suspicious files or concerns to the [GAM Group](https://groups.google.com/g/google-apps-manager) or the [GAM Chat Space](https://git.io/gam-chat).
# Windows Code Sign # Windows Code Sign
On Windows, Official gam.exe files and EXE installer packages are signed by a [Certum Open Source code signing certificate](https://shop.certum.eu/open-source-code-signing.html). You can validate the signature and thus be sure you are running official GAM7 from the command line and GUI: On Windows, Official gam.exe files and MSI installer packages are signed by a [Certum Open Source code signing certificate](https://shop.certum.eu/open-source-code-signing.html). You can validate the signature and thus be sure you are running official GAM7 from the command line and GUI:
# Command Line # Command Line
From PowerShell, run the following command: From PowerShell, run the following command:
@@ -113,6 +113,6 @@ SignerCertificate : [Subject]
confirm that status is "Valid" and the SignerCertificate says "Open Source Developer, James Lee" (yes, James is Jay's legal name, now you know). confirm that status is "Valid" and the SignerCertificate says "Open Source Developer, James Lee" (yes, James is Jay's legal name, now you know).
## GUI ## GUI
From File Manager, you can right click on gam.exe or the EXE installer package and go to the Digital Signatures tab. From there you'll see the signing certificate which should show "Open Source Developer, James Lee". From File Manager, you can right click on gam.exe or the MSI package and go to the Digital Signatures tab. From there you'll see the signing certificate which should show "Open Source Developer, James Lee".
![image](https://github.com/user-attachments/assets/dceb8cb8-36e0-4ed7-8b03-09322b49b06a) ![image](https://github.com/user-attachments/assets/dceb8cb8-36e0-4ed7-8b03-09322b49b06a)

View File

@@ -3,23 +3,23 @@
Print the current version of Gam with details Print the current version of Gam with details
``` ```
gam version gam version
GAM 7.39.08 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.33.03 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.4 64-bit final Python 3.14.2 64-bit final
macOS Tahoe 26.4 arm64 macOS Tahoe 26.2 x86_64
Path: /Users/gamteam/bin/gam7 Path: /Users/Admin/bin/gam7
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
Time: 2026-02-15T07:51:00-08:00 Time: 2025-12-23T13:57:00-08:00
``` ```
Print the current version of Gam with details and time offset information Print the current version of Gam with details and time offset information
``` ```
gam version timeoffset gam version timeoffset
GAM 7.39.08 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.33.03 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.4 64-bit final Python 3.14.2 64-bit final
macOS Tahoe 26.4 arm64 macOS Tahoe 26.2 x86_64
Path: /Users/gamteam/bin/gam7 Path: /Users/Admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
Your system time differs from www.googleapis.com by less than 1 second Your system time differs from www.googleapis.com by less than 1 second
``` ```
@@ -27,29 +27,29 @@ Your system time differs from www.googleapis.com by less than 1 second
Print the current version of Gam with extended details and SSL information Print the current version of Gam with extended details and SSL information
``` ```
gam version extended gam version extended
GAM 7.39.08 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.33.03 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.4 64-bit final Python 3.14.2 64-bit final
macOS Tahoe 26.4 arm64 macOS Tahoe 26.2 x86_64
Path: /Users/gamteam/bin/gam7 Path: /Users/Admin/bin/gam7
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
Time: 2026-02-15T07:51:00-08:00 Time: 2025-12-23T13:57:00-08:00
Your system time differs from admin.googleapis.com by less than 1 second Your system time differs from admin.googleapis.com by less than 1 second
OpenSSL 3.6.2 7 Apr 2026 OpenSSL 3.6.1 27 Jan 2026
arrow 1.4.0 arrow 1.3.0
chardet 5.2.0 chardet 5.2.0
cryptography 46.0.5 cryptography 46.0.1
filelock 3.21.2 filelock 3.19.1
google-api-python-client 2.190.0 google-api-python-client 2.182.0
google-auth-httplib2 0.3.0 google-auth-httplib2 0.2.0
google-auth-oauthlib 1.2.4 google-auth-oauthlib 1.2.2
google-auth 2.48.0 google-auth 2.40.3
lxml 6.0.2 lxml 6.0.1
httplib2 0.31.2 httplib2 0.31.0
passlib 1.7.4 passlib 1.7.4
pathvalidate 3.3.1 pathvalidate 3.3.1
pyscard 2.3.1 pyscard 2.3.0
yubikey-manager 5.9.0 yubikey-manager 5.8.0
admin.googleapis.com connects using TLSv1.3 TLS_AES_256_GCM_SHA384 admin.googleapis.com connects using TLSv1.3 TLS_AES_256_GCM_SHA384
``` ```
@@ -65,10 +65,10 @@ google-api-python-client 2.77.0
httplib2 0.16.0 httplib2 0.16.0
oauth2client 4.1.3 oauth2client 4.1.3
MacOS High Sierra 10.13.6 x86_64 MacOS High Sierra 10.13.6 x86_64
Path: /Users/gamteam/bin/gam7 Path: /Users/Admin/bin/gam7
Version Check: Version Check:
Current: 5.35.08 Current: 5.35.08
Latest: 7.39.08 Latest: 7.33.03
echo $? echo $?
1 1
``` ```
@@ -76,7 +76,7 @@ echo $?
Print the current version number without details Print the current version number without details
``` ```
gam version simple gam version simple
7.39.08 7.33.03
``` ```
In Linux/MacOS you can do: In Linux/MacOS you can do:
``` ```
@@ -86,13 +86,13 @@ echo $VER
Print the current version of Gam and address of this Wiki Print the current version of Gam and address of this Wiki
``` ```
gam help gam help
GAM 7.39.08 - https://github.com/GAM-team/GAM GAM 7.33.03 - https://github.com/GAM-team/GAM
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.4 64-bit final Python 3.14.2 64-bit final
macOS Tahoe 26.4 arm64 macOS Tahoe 26.2 x86_64
Path: /Users/gamteam/bin/gam7 Path: /Users/Admin/bin/gam7
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
Time: 2026-02-15T07:51:00-08:00 Time: 2025-12-23T13:57:00-08:00
Help: Syntax in file /Users/gamteam/bin/gam7/GamCommands.txt Help: Syntax in file /Users/Admin/bin/gam7/GamCommands.txt
Help: Documentation is at https://github.com/GAM-team/GAM/wiki Help: Documentation is at https://github.com/GAM-team/GAM/wiki
``` ```

View File

@@ -232,11 +232,6 @@ csv_output_header_order
Any headers in the file but not in the list will appear after Any headers in the file but not in the list will appear after
the headers in the list the headers in the list
Default: '' Default: ''
csv_output_header_required
A list of <Strings> used to specify column headers
for inclusion in the CSV file written by a gam print command
even if the API didn't return any data for those columns.
Default: ''
csv_output_line_terminator csv_output_line_terminator
Allowed values: cr, lf, crlf Allowed values: cr, lf, crlf
Designates character(s) used to terminate the lines of a CSV file. Designates character(s) used to terminate the lines of a CSV file.
@@ -355,6 +350,17 @@ enable_dasa
admin_email, customer_id and domain must be set when enable_dasa is True, admin_email, customer_id and domain must be set when enable_dasa is True,
customer_id may not be set to my_customer customer_id may not be set to my_customer
Signal file: OldGamPath/enabledasa.txt Signal file: OldGamPath/enabledasa.txt
enforce_expansive_access
The default value for option `enforceexpansiveaccess` in all commands that delete or update
drive file ACLs/permissions.
gam <UserTypeEntity> delete permissions
gam <UserTypeEntity> delete drivefileacl
gam <UserTypeEntity> update drivefileacl
gam <UserTypeEntity> copy drivefile
gam <UserTypeEntity> move drivefile
gam <UserTypeEntity> transfer ownership
gam <UserTypeEntity> claim ownership
Default: True
event_max_results event_max_results
When retrieving lists of Calendar events from API, When retrieving lists of Calendar events from API,
how many should be retrieved in each API call how many should be retrieved in each API call
@@ -364,21 +370,6 @@ extra_args
Path to extra_args.txt Path to extra_args.txt
Default: Blank Default: Blank
Data file: extra_args.txt Data file: extra_args.txt
gcp_org_id
The Google Cloud organization ID for your workspace.
Default: Blank
This value is used by the following commands;
by setting the value, additional API calls are eliminated.
gam create project
gam create gcpfolder
gam create|update|delete caalevel
gam print|show caalevels
gam print|show tokens gcpdetails
You can get and save the `gcp_org_id` value with these commands:
$ gam info gcporgid
organizations/906207637890
$ gam config gcp_org_id organizations/906207637890 save
gmail_cse_incert_dir gmail_cse_incert_dir
Directory for the S/MIME certificate files used by Gmail Client Side Encryption. Directory for the S/MIME certificate files used by Gmail Client Side Encryption.
Default: Blank Default: Blank
@@ -739,8 +730,6 @@ Section: DEFAULT
csv_output_header_drop_filter = '' csv_output_header_drop_filter = ''
csv_output_header_filter = '' csv_output_header_filter = ''
csv_output_header_force = '' csv_output_header_force = ''
csv_output_header_order = ''
csv_output_header_required = ''
csv_output_line_terminator = lf csv_output_line_terminator = lf
csv_output_no_escape_char = false csv_output_no_escape_char = false
csv_output_quote_char = '"' csv_output_quote_char = '"'
@@ -987,7 +976,6 @@ csv_output_header_drop_filter = ''
csv_output_header_filter = '' csv_output_header_filter = ''
csv_output_header_force = '' csv_output_header_force = ''
csv_output_header_order = '' csv_output_header_order = ''
csv_output_header_required = ''
csv_output_line_terminator = lf csv_output_line_terminator = lf
csv_output_no_escape_char = false csv_output_no_escape_char = false
csv_output_quote_char = '"' csv_output_quote_char = '"'
@@ -1012,6 +1000,7 @@ drive_max_results = 1000
email_batch_size = 50 email_batch_size = 50
enable_dasa = false enable_dasa = false
enable_gcloud_reauth = false enable_gcloud_reauth = false
enforce_expansive_access = true
event_max_results = 250 event_max_results = 250
extra_args = '' extra_args = ''
gmail_cse_incert_dir = '' gmail_cse_incert_dir = ''