Compare commits

..

18 Commits

Author SHA1 Message Date
Ross Scroggs
e18a70e55b Added hideinvitationssetting to <UserCalendarSettingsField> 2026-02-07 06:55:07 -08:00
Ross Scroggs
e11123fccd Update Users-Gmail-Delegates.md 2026-02-07 06:51:43 -08:00
Ross Scroggs
536ea84321 Update No-Owner-Secondary-Calendars.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
2026-02-06 12:45:36 -08:00
Ross Scroggs
4d953ac09b Update No-Owner-Secondary-Calendars.md 2026-02-06 12:43:54 -08:00
Ross Scroggs
d9ce0acd83 Secondary Calendars with no Owner 2026-02-06 12:42:07 -08:00
Ross Scroggs
f735e5e268 Added option shownopolicy to gam print chromepolicies
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2026-02-05 12:14:11 -08:00
Ross Scroggs
97358d15ef Added option shownopolicy to `gam print chromepolicies 2026-02-05 11:27:19 -08:00
Ross Scroggs
ea0886229e Update gam.cfg.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
2026-02-03 13:53:45 -08:00
Ross Scroggs
4e5462c704 Added variable developer_preview_apis to gam.cfg
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2026-02-03 10:17:24 -08:00
Ross Scroggs
ed2291bedf Added variable developer_preview_apis to gam.cfg 2026-02-03 10:16:51 -08:00
Ross Scroggs
44ff2eba62 Added option includepermissionsforview published to print filelist/show fileinfo
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2026-01-31 10:16:26 -08:00
Ross Scroggs
77fb2d0693 Added option includepermissionsforview published to print filelist/show fileinfo 2026-01-31 09:58:40 -08:00
Ross Scroggs
cea5a33856 Added option includepermissionsforview published to print filelist/show fileinfo 2026-01-31 09:58:28 -08:00
Ross Scroggs
3a7f84e49d Update Cloud-Identity-Groups-Membership.md 2026-01-31 08:53:41 -08:00
Ross Scroggs
5136c0a268 Update Cloud-Identity-Groups-Membership.md 2026-01-31 08:49:48 -08:00
Ross Scroggs
8e877a938e Update Cloud-Identity-Groups-Membership.md 2026-01-31 08:45:47 -08:00
Ross Scroggs
ed695b234f Update GamUpdates.md
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2026-01-29 20:07:00 -08:00
Ross Scroggs
83179be184 Allow filtering on modifiedTime in copy drivefile 2026-01-29 19:36:04 -08:00
21 changed files with 503 additions and 118 deletions

View File

@@ -2789,21 +2789,23 @@ gam create chromepolicyimage <ChromePolicyImageSchemaName> <FileName>
gam update chromepolicy [convertcrnl]
(<SchemaName> ((<Field> <Value>)+ | <JSONData>))+
((ou|orgunit <OrgUnitItem>)|(cigroup <GroupItem>))
((ou|orgunit <OrgUnitItem>)|(group <GroupItem>))
[(printerid <PrinterID>)|(appid <AppID>)]
gam delete chromepolicy
(<SchemaName> [<JSONData>])+
((ou|orgunit <OrgUnitItem>)|(cigroup <GroupItem>))
((ou|orgunit <OrgUnitItem>)|(group <GroupItem>))
[(printerid <PrinterID>)|(appid <AppID>)]
gam show chromepolicies
((ou|orgunit <OrgUnitItem> [show all|direct|inherited])|(cigroup <GroupItem>))
((ou|orgunit <OrgUnitItem> [show all|direct|inherited])|(group <GroupItem>))
[(printerid <PrinterID>)|(appid <AppID>)]
(filter <StringList>)* (namespace <NamespaceList>)*
[show all|direct|inherited]
[formatjson]
gam print chromepolicies [todrive <ToDriveAttribute>*]
((ou|orgunit <OrgUnitItem> [show all|direct|inherited])|(cigroup <GroupItem>))
((ou|orgunit <OrgUnitItem> [show all|direct|inherited])|(group <GroupItem>))
[(printerid <PrinterID>)|(appid <AppID>)]
(filter <StringList>)* (namespace <NamespaceList>)*
[show all|direct|inherited] [shownopolicy]
[[formatjson [quotechar <Character>]]
<ChromePolicySchemaFieldName> ::=
@@ -6166,6 +6168,7 @@ Display a users calendar settings
defaulteventlength|
format24hourtime|
hideinvitations|
hideinvitationssetting|
hideweekends|
locale|
remindonrespondedeventsonly|
@@ -6974,6 +6977,7 @@ gam <UserTypeEntity> info drivefile <DriveFileEntity>
[returnidonly]
[filepath|fullpath] [folderpathonly [<Boolean>]] [pathdelimiter <Character>]
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
[includepermissionsforview published]
(orderby <DriveFileOrderByFieldName> [ascending|descending])*
[showdrivename] [showshareddrivepermissions]
[(showlabels details|ids)|(includelabels <ClassificationLabelIDList>)]
@@ -7457,6 +7461,7 @@ gam <UserTypeEntity> show fileinfo <DriveFileEntity>
[returnidonly]
[filepath|fullpath] [folderpathonly [<Boolean>]] [pathdelimiter <Character>]
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
[includepermissionsforview published]
(orderby <DriveFileOrderByFieldName> [ascending|descending])*
[showdrivename] [showshareddrivepermissions]
[(showlabels details|ids)|(includelabels <ClassificationLabelIDList>)]
@@ -7570,6 +7575,7 @@ gam <UserTypeEntity> print filelist [todrive <ToDriveAttribute>*]
[sizefield quotabytesused|size] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
[filenamematchpattern <REMatchPattern>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] [pmfilter] [oneitemperrow]
[includepermissionsforview published]
[excludetrashed]
[maxfiles <Integer>] [nodataheaders <String>]
[countsonly [summary none|only|plus] [summaryuser <String>]

View File

@@ -1,7 +1,39 @@
7.33.02
Added `hideinvitationssetting` to `<UserCalendarSettingsField>` used by
`gam <UserTypeEntity> print|show calsettings`.
7.33.01
Added option `shownopolicy` to `gam print chromepolicies` that will display output like the following
if no policies apply to the selected OU or group.
```
gam print chromepolicies ou /Test appid chrome:emidddocikgklceeeifefomdnbkldhng namespace chrome.users.apps shownopolicy
Getting all Chrome Policies that match query (chrome.users.apps.*) for /Test
Got 0 Chrome Policies that matched query (chrome.users.apps.*) for /Test...
name,orgUnitPath,parentOrgUnitPath,direct,appId
noPolicy,/Test,/,False,chrome:emidddocikgklceeeifefomdnbkldhng
```
7.33.00
Added variable `developer_preview_apis` to `gam.cfg` that is a comma separated list of APIs requiring a Developer Preview key.
Currently, `chat` is the only API that requires a Developer Preview key; it is required for the User Sections commands.
* See: https://github.com/GAM-team/GAM/wiki/Users-Chat#introduction
* See: https://github.com/GAM-team/GAM/wiki/Users-Chat#manage-chat-user-sections
7.32.07
Added option `includepermissionsforview published` to `gam <UserTypeEntity> print filelist` and
`gam <UserTypeEntity> show fileinfo`. From the Drive API documentation:
```
Specifies which additional view's permissions to include in the response. Only published is supported.
```
7.32.06
Added options to `gam <UserTypeEntity> copy drivefile ... copysubfiles` to limit copying
of files whose `modifiedTime` meets specified requirements.
to files whose `modifiedTime` meets specified requirements.
* `start|starttime <Date>|<Time>` - If specified, `modifiedTime` must be >= the value
* `end|endtime <Date>|<Time>` - If specified, `modifiedTime` must be <= the value
* `range <Date>|<Time> <Date>|<Time>` - first value <= `modifiedTime` <= second value

View File

@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
"""
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
__version__ = '7.32.06'
__version__ = '7.33.02'
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
# pylint: disable=wrong-import-position
@@ -2308,10 +2308,10 @@ def getMatchSkipFields(fieldNames):
def checkMatchSkipFields(row, fieldnames, matchFields, skipFields):
for matchField, matchPattern in matchFields.items():
if (matchField not in row) or not matchPattern.search(row[matchField]):
if (matchField not in row) or not matchPattern.search(str(row[matchField])):
return False
for skipField, matchPattern in skipFields.items():
if (skipField in row) and matchPattern.search(row[skipField]):
if (skipField in row) and matchPattern.search(str(row[skipField])):
return False
if fieldnames and (GC.Values[GC.CSV_INPUT_ROW_FILTER] or GC.Values[GC.CSV_INPUT_ROW_DROP_FILTER]):
return RowFilterMatch(row, fieldnames,
@@ -3752,6 +3752,15 @@ def SetGlobalVariables():
if (productId, sku) not in GM.Globals[GM.LICENSE_SKUS]:
GM.Globals[GM.LICENSE_SKUS].append((productId, sku))
def _validateDeveloperPreviewAPIs(sectionName, itemName, apiList):
GM.Globals[GM.DEVELOPER_PREVIEW_APIS] = set()
validAPIs = API.getAPIsList()
for api in apiList.split(','):
if api in validAPIs:
GM.Globals[GM.DEVELOPER_PREVIEW_APIS].add(api)
else:
_printValueError(sectionName, itemName, api, f'{Msg.EXPECTED}: {",".join(sorted(validAPIs))}')
def _getCfgString(sectionName, itemName):
value = _stripStringQuotes(GM.Globals[GM.PARSER].get(sectionName, itemName))
if itemName == GC.DOMAIN:
@@ -3760,6 +3769,8 @@ def SetGlobalVariables():
if ((minLen is None) or (len(value) >= minLen)) and ((maxLen is None) or (len(value) <= maxLen)):
if itemName == GC.LICENSE_SKUS and value:
_validateLicenseSKUs(sectionName, itemName, value)
elif itemName == GC.DEVELOPER_PREVIEW_APIS and value:
_validateDeveloperPreviewAPIs(sectionName, itemName, value.lower())
return value
_printValueError(sectionName, itemName, f'"{value}"', f'{Msg.EXPECTED}: {integerLimits(minLen, maxLen, Msg.STRING_LENGTH)}')
return ''
@@ -4820,11 +4831,12 @@ def getService(api, httpObj):
triesLimit = 3
for n in range(1, triesLimit+1):
try:
if api not in {API.CHAT} or not GC.Values[GC.DEVELOPER_PREVIEW_API_KEY]:
if api not in GM.Globals[GM.DEVELOPER_PREVIEW_APIS] or not GC.Values[GC.DEVELOPER_PREVIEW_API_KEY]:
discoveryServiceUrl = DISCOVERY_URIS[v2discovery]
developerKey = ''
else:
discoveryServiceUrl = DEVELOPER_PREVIEW_DISCOVERY_URI
developerKey = GC.Values[GC.DEVELOPER_PREVIEW_API_KEY]
developerKey = GC.Values[GC.DEVELOPER_PREVIEW_API_KEY]
service = googleapiclient.discovery.build(api, version, http=httpObj, cache_discovery=False,
discoveryServiceUrl=discoveryServiceUrl, developerKey=developerKey, static_discovery=False)
GM.Globals[GM.CURRENT_API_SERVICES].setdefault(api, {})
@@ -27063,6 +27075,8 @@ def createUpdateChatSection(users):
except GAPI.failedPrecondition:
userChatServiceNotEnabledWarning(user, i, count)
continue
except AttributeError:
systemErrorExit(GOOGLE_API_ERROR_RC, Msg.DEVELOPER_PREVIEW_REQUIRED)
# gam <UserTypeEntity> delete chatsection <ChatSection>
def deleteChatSection(users):
@@ -27093,6 +27107,8 @@ def deleteChatSection(users):
except GAPI.failedPrecondition:
userChatServiceNotEnabledWarning(user, i, count)
continue
except AttributeError:
systemErrorExit(GOOGLE_API_ERROR_RC, Msg.DEVELOPER_PREVIEW_REQUIRED)
# gam <UserTypeEntity> show chatsections
# [formatjson]
@@ -27127,6 +27143,8 @@ def printShowChatSections(users):
except GAPI.failedPrecondition:
userChatServiceNotEnabledWarning(user, i, count)
continue
except AttributeError:
systemErrorExit(GOOGLE_API_ERROR_RC, Msg.DEVELOPER_PREVIEW_REQUIRED)
jcount = len(sections)
if jcount == 0:
setSysExitRC(NO_ENTITIES_FOUND_RC)
@@ -27181,6 +27199,8 @@ def moveShowChatSectionItem(users):
except GAPI.failedPrecondition:
userChatServiceNotEnabledWarning(user, i, count)
continue
except AttributeError:
systemErrorExit(GOOGLE_API_ERROR_RC, Msg.DEVELOPER_PREVIEW_REQUIRED)
# gam <UserTypeEntity> show chatsectionitems <ChatSection>
# [space <ChatSpace>]
@@ -27252,6 +27272,8 @@ def printShowChatSectionItems(users):
except GAPI.failedPrecondition:
userChatServiceNotEnabledWarning(user, i, count)
continue
except AttributeError:
systemErrorExit(GOOGLE_API_ERROR_RC, Msg.DEVELOPER_PREVIEW_REQUIRED)
jcount = len(sectionItems)
if jcount == 0:
setSysExitRC(NO_ENTITIES_FOUND_RC)
@@ -30067,7 +30089,7 @@ CHROME_POLICY_SHOW_CHOICE_MAP = {
# ((ou|orgunit <OrgUnitItem>)|(group <GroupItem>))
# [(printerid <PrinterID>)|(appid <AppID>)]
# (filter <StringList>)* (namespace <NamespaceList>)*
# [show all|direct|inherited]
# [show all|direct|inherited] [shownopolicy]
# [[formatjson [quotechar <Character>]]
def doPrintShowChromePolicies():
def normalizedPolicy(policy):
@@ -30138,25 +30160,54 @@ def doPrintShowChromePolicies():
showJSON(None, policy, sortDictKeys=False)
Ind.Decrement()
def _printPolicyRow(policy):
row = flattenJSON(policy)
if not FJQC.formatJSON:
csvPF.WriteRowTitles(row)
elif (not csvPF.rowFilter and not csvPF.rowDropFilter) or csvPF.CheckRowTitles(row):
if entityType == Ent.ORGANIZATIONAL_UNIT:
csvPF.WriteRowNoFilter({'name': policy['name'],
'orgUnitPath': policy['orgUnitPath'],
'parentOrgUnitPath': policy['parentOrgUnitPath'],
'direct': policy['direct'],
'JSON': json.dumps(cleanJSON(policy),
ensure_ascii=False, sort_keys=True)})
else:
csvPF.WriteRowNoFilter({'name': policy['name'],
'group': policy['group'],
'JSON': json.dumps(cleanJSON(policy),
ensure_ascii=False, sort_keys=True)})
def _printPolicy(policy):
nonlocal policiesShown
policy = normalizedPolicy(policy)
if (entityType == Ent.GROUP) or showPolicies in (CHROME_POLICY_SHOW_ALL, policy['direct']):
row = flattenJSON(policy)
if not FJQC.formatJSON:
csvPF.WriteRowTitles(row)
elif (not csvPF.rowFilter and not csvPF.rowDropFilter) or csvPF.CheckRowTitles(row):
if entityType == Ent.ORGANIZATIONAL_UNIT:
csvPF.WriteRowNoFilter({'name': policy['name'],
'orgUnitPath': policy['orgUnitPath'],
'parentOrgUnitPath': policy['parentOrgUnitPath'],
'direct': policy['direct'],
'JSON': json.dumps(cleanJSON(policy),
ensure_ascii=False, sort_keys=True)})
else:
csvPF.WriteRowNoFilter({'name': policy['name'],
'group': policy['group'],
'JSON': json.dumps(cleanJSON(policy),
ensure_ascii=False, sort_keys=True)})
policiesShown += 1
_printPolicyRow(policy)
def _printNoPolicy():
nonlocal targetName
policy = {'name': 'noPolicy'}
if app_id:
policy['appId'] = app_id
elif printer_id:
policy['printerId'] = printer_id
if entityType == Ent.ORGANIZATIONAL_UNIT:
policy['orgUnitPath'] = targetName
if targetName == '/':
policy['parentOrgUnitPath'] = '/'
else:
targetName = makeOrgUnitPathRelative(targetName)
policy['parentOrgUnitPath'] = callGAPI(cd.orgunits(), 'get',
throwReasons=GAPI.ORGUNIT_GET_THROW_REASONS,
customerId=GC.Values[GC.CUSTOMER_ID],
orgUnitPath=encodeOrgUnitPath(targetName),
fields='parentOrgUnitPath')['parentOrgUnitPath']
policy['direct'] = False
else:
policy['group'] = targetName
_printPolicyRow(policy)
cp = buildGAPIObject(API.CHROMEPOLICY)
cd = buildGAPIObject(API.DIRECTORY)
@@ -30168,6 +30219,8 @@ def doPrintShowChromePolicies():
app_id = groupEmail = orgUnit = printer_id = targetResource = None
showPolicies = CHROME_POLICY_SHOW_ALL
psFilters = []
showNoPolicy = False
policiesShown = 0
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if csvPF and myarg == 'todrive':
@@ -30191,6 +30244,8 @@ def doPrintShowChromePolicies():
psFilters.append(f'{psFilter}.*')
elif myarg == 'show':
showPolicies = getChoice(CHROME_POLICY_SHOW_CHOICE_MAP, mapChoice=True)
elif csvPF and myarg == 'shownopolicy':
showNoPolicy = True
else:
FJQC.GetFormatJSONQuoteChar(myarg, False)
checkPolicyArgs(targetResource, printer_id, app_id)
@@ -30280,7 +30335,8 @@ def doPrintShowChromePolicies():
else:
for policy in policies:
_printPolicy(policy)
if csvPF:
if showNoPolicy and policiesShown == 0:
_printNoPolicy()
csvPF.writeCSVfile(f'Chrome Policies - {targetName}')
CHROME_IMAGE_SCHEMAS_MAP = {
@@ -54125,6 +54181,7 @@ USER_CALENDAR_SETTINGS_FIELDS_CHOICE_MAP = {
'defaulteventlength': 'defaultEventLength',
'format24hourtime': 'format24HourTime',
'hideinvitations': 'hideInvitations',
'hideinvitationssetting': 'hideInvitationsSetting',
'hideweekends': 'hideWeekends',
'locale': 'locale',
'remindonrespondedeventsonly': 'remindOnRespondedEventsOnly',
@@ -57294,6 +57351,31 @@ FILEPATH_FIELDS = ','.join(FILEPATH_FIELDS_TITLES)
DRIVE_TIME_OBJECTS = {'createdTime', 'viewedByMeTime', 'modifiedByMeTime', 'modifiedTime', 'restrictionTime', 'sharedWithMeTime', 'trashedTime'}
def _getIncludeLabels(includeLabels):
labelIds = getEntityList(Cmd.OB_CLASSIFICATION_LABEL_ID, shlexSplit=True)
for labelId in labelIds:
includeLabels.add(normalizeDriveLabelID(labelId))
def _finalizeIncludeLabels(includeLabels):
if includeLabels:
return ','.join(includeLabels)
return None
DRIVEFILE_PERMISSIONS_FOR_VIEW_CHOICES = ['published']
def _getIncludePermissionsForView(includePermissionsForView):
ipfwList = getEntityList(Cmd.OB_STRING_LIST)
for ipfw in ipfwList:
if ipfw in DRIVEFILE_PERMISSIONS_FOR_VIEW_CHOICES:
includePermissionsForView.add(ipfw)
else:
invalidChoiceExit(ipfw, DRIVEFILE_PERMISSIONS_FOR_VIEW_CHOICES, True)
def _finalizeIncludePermissionsForView(includePermissionsForView):
if includePermissionsForView:
return ','.join(includePermissionsForView)
return None
def _getDriveFieldSubField(field, fieldsList, parentsSubFields):
field, subField = field.split('.', 1)
if field in DRIVE_SUBFIELDS_CHOICE_MAP:
@@ -57320,7 +57402,8 @@ class DriveFileFields():
self.allFields = False
self.OBY = OrderBy(DRIVEFILE_ORDERBY_CHOICE_MAP)
self.fieldsList = []
self.includeLabels = []
self.includeLabels = set()
self.includePermissionsForView = set()
self.parentsSubFields = {'id': False, 'isRoot': False, 'rootFolderId': None}
def SetAllParentsSubFields(self):
@@ -57354,9 +57437,9 @@ class DriveFileFields():
else:
_getDriveFieldSubField(field, self.fieldsList, self.parentsSubFields)
elif myarg == 'includelabels':
labelIds = getEntityList(Cmd.OB_CLASSIFICATION_LABEL_ID, shlexSplit=True)
for labelId in labelIds:
self.includeLabels.append(normalizeDriveLabelID(labelId))
_getIncludeLabels(self.includeLabels)
elif myarg == 'includepermissionsforview':
_getIncludePermissionsForView(self.includePermissionsForView)
elif myarg.find('.') != -1:
_getDriveFieldSubField(myarg, self.fieldsList, self.parentsSubFields)
elif myarg == 'orderby':
@@ -57416,6 +57499,7 @@ def _formatFileDriveLabels(showLabels, labels, result, printMode, delimiter):
# (orderby <DriveFileOrderByFieldName> [ascending|descending])*
# [showdrivename] [showshareddrivepermissions]
# [(showlabels details|ids)|(includelabels <DriveLabelIDList>)]
# [includepermissionsforview published]
# [showparentsidsaslist] [followshortcuts [<Boolean>]]
# [stripcrsfromname] [formatjson]
# gam <UserTypeEntity> show fileinfo <DriveFileEntity>
@@ -57425,6 +57509,7 @@ def _formatFileDriveLabels(showLabels, labels, result, printMode, delimiter):
# (orderby <DriveFileOrderByFieldName> [ascending|descending])*
# [showdrivename] [showshareddrivepermissions]
# [(showlabels details|ids)|(includelabels <DriveLabelIDList>)]
# [includepermissionsforview published]
# [showparentsidsaslist] [followshortcuts [<Boolean>]]
# [stripcrsfromname] [formatjson]
def showFileInfo(users):
@@ -57487,7 +57572,8 @@ def showFileInfo(users):
DFF.SetAllParentsSubFields()
skipObjects = skipObjects.union(DEFAULT_SKIP_OBJECTS)
showNoParents = True
includeLabels = ','.join(DFF.includeLabels)
includeLabels = _finalizeIncludeLabels(DFF.includeLabels)
includePermissionsForView = _finalizeIncludePermissionsForView(DFF.includePermissionsForView)
pathFields = FILEPATH_FIELDS
i, count, users = getEntityArgument(users)
for user in users:
@@ -57526,12 +57612,14 @@ def showFileInfo(users):
try:
result = callGAPI(drive.files(), 'get',
throwReasons=GAPI.DRIVE_GET_THROW_REASONS+[GAPI.INVALID],
fileId=fileId, includeLabels=includeLabels, fields=fields, supportsAllDrives=True)
fileId=fileId, includeLabels=includeLabels, includePermissionsForView=includePermissionsForView,
fields=fields, supportsAllDrives=True)
if followShortcuts and result['mimeType'] == MIMETYPE_GA_SHORTCUT:
fileId = result['shortcutDetails']['targetId']
result = callGAPI(drive.files(), 'get',
throwReasons=GAPI.DRIVE_GET_THROW_REASONS+[GAPI.INVALID],
fileId=fileId, includeLabels=includeLabels, fields=fields, supportsAllDrives=True)
fileId=fileId, includeLabels=includeLabels, includePermissionsForView=includePermissionsForView,
fields=fields, supportsAllDrives=True)
if stripCRsFromName:
result['name'] = _stripControlCharsFromName(result['name'])
driveId = result.get('driveId')
@@ -58859,6 +58947,7 @@ SIZE_FIELD_CHOICE_MAP = {
# [allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
# [showdrivename] [showshareddrivepermissions]
# (showlabels details|ids)|(includelabels <DriveLabelIDList>)]
# [includepermissionsforview published]
# [showparentsidsaslist] [showpermissionslast]
# (orderby <DriveFileOrderByFieldName> [ascending|descending])* [delimiter <Character>]
# [stripcrsfromname]
@@ -59039,7 +59128,8 @@ def printFileList(users):
throwReasons=GAPI.DRIVE_USER_THROW_REASONS+[GAPI.INVALID_QUERY, GAPI.INVALID,
GAPI.BAD_REQUEST],
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS+[GAPI.UNKNOWN_ERROR],
q=q, orderBy=DFF.orderBy, includeLabels=includeLabels, fields=pagesFields,
q=q, orderBy=DFF.orderBy, includeLabels=includeLabels, includePermissionsForView=includePermissionsForView,
fields=pagesFields,
pageSize=GC.Values[GC.DRIVE_MAX_RESULTS], includeItemsFromAllDrives=True, supportsAllDrives=True)
for childEntryInfo in children:
childFileId = childEntryInfo['id']
@@ -59056,8 +59146,12 @@ def printFileList(users):
_printFileInfo(drive, user, childEntryInfo.copy(), stripCRsFromName)
if childEntryInfo['mimeType'] == MIMETYPE_GA_FOLDER and (maxdepth == -1 or depth < maxdepth):
_printChildDriveFolderContents(drive, childEntryInfo, user, i, count, depth+1)
except (GAPI.invalidQuery, GAPI.invalid, GAPI.badRequest):
entityActionFailedWarning([Ent.USER, user, Ent.DRIVE_FILE, None], invalidQuery(selectSubQuery), i, count)
except (GAPI.invalidQuery, GAPI.invalid, GAPI.badRequest) as e:
errMsg = str(e)
if 'Invalid field selection' in errMsg or "Only a 'published' value is supported." in errMsg:
entityActionFailedWarning([Ent.USER, user, Ent.DRIVE_FILE_OR_FOLDER, None], errMsg, i, count)
else:
entityActionFailedWarning([Ent.USER, user, Ent.DRIVE_FILE, None], invalidQuery(selectSubQuery), i, count)
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
userDriveServiceNotEnabledWarning(user, str(e), i, count)
@@ -59279,7 +59373,8 @@ def printFileList(users):
if filepath and not countsOnly:
csvPF.AddTitles('paths')
csvPF.SetFixPaths(True)
includeLabels = ','.join(DFF.includeLabels)
includeLabels = _finalizeIncludeLabels(DFF.includeLabels)
includePermissionsForView = _finalizeIncludePermissionsForView(DFF.includePermissionsForView)
csvPF.RemoveTitles(['capabilities'])
if DLP.queryTimes and selectSubQuery:
for queryTimeName, queryTimeValue in DLP.queryTimes.items():
@@ -59352,7 +59447,8 @@ def printFileList(users):
GAPI.BAD_REQUEST, GAPI.FILE_NOT_FOUND,
GAPI.NOT_FOUND, GAPI.TEAMDRIVE_MEMBERSHIP_REQUIRED],
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS+[GAPI.UNKNOWN_ERROR],
q=DLP.fileIdEntity['query'], orderBy=DFF.orderBy, includeLabels=includeLabels,
q=DLP.fileIdEntity['query'], orderBy=DFF.orderBy,
includeLabels=includeLabels, includePermissionsForView=includePermissionsForView,
fields=pagesFields, pageSize=GC.Values[GC.DRIVE_MAX_RESULTS], **btkwargs)
for files in feed:
if showLabels is not None:
@@ -59383,7 +59479,7 @@ def printFileList(users):
DLP.GetLocationFileIdsFromTree(fileTree, fileIdEntity)
except (GAPI.invalidQuery, GAPI.invalid, GAPI.badRequest) as e:
errMsg = str(e)
if 'Invalid field selection' in errMsg:
if 'Invalid field selection' in errMsg or "Only a 'published' value is supported." in errMsg:
entityActionFailedWarning([Ent.USER, user, Ent.DRIVE_FILE_OR_FOLDER, None], errMsg, i, count)
break
entityActionFailedWarning([Ent.USER, user, Ent.DRIVE_FILE_OR_FOLDER, None], invalidQuery(DLP.fileIdEntity['query']), i, count)
@@ -59415,8 +59511,9 @@ def printFileList(users):
else:
try:
fileEntryInfo = callGAPI(drive.files(), 'get',
throwReasons=GAPI.DRIVE_GET_THROW_REASONS,
fileId=fileId, includeLabels=includeLabels, fields=fields, supportsAllDrives=True)
throwReasons=GAPI.DRIVE_GET_THROW_REASONS+[GAPI.INVALID],
fileId=fileId, includeLabels=includeLabels, includePermissionsForView=includePermissionsForView,
fields=fields, supportsAllDrives=True)
if stripCRsFromName:
fileEntryInfo['name'] = _stripControlCharsFromName(fileEntryInfo['name'])
if showLabels is not None:
@@ -59427,6 +59524,9 @@ def printFileList(users):
_formatFileDriveLabels(showLabels, labels, fileEntryInfo, True, delimiter)
if filepath:
fileTree[fileId] = {'info': fileEntryInfo}
except GAPI.invalid as e:
entityActionFailedWarning([Ent.USER, user, Ent.DRIVE_FILE_OR_FOLDER, fileId], str(e), j, jcount)
continue
except GAPI.fileNotFound:
entityActionFailedWarning([Ent.USER, user, Ent.DRIVE_FILE_OR_FOLDER, fileId], Msg.NOT_FOUND, j, jcount)
continue
@@ -67410,8 +67510,6 @@ def infoDriveFileACLs(users, useDomainAdminAccess=False):
def doInfoDriveFileACLs():
infoDriveFileACLs([_getAdminEmail()], True)
DRIVEFILE_PERMISSIONS_FOR_VIEW_CHOICES = ['published']
def getDriveFilePermissionsFields(myarg, fieldsList):
if myarg in DRIVE_PERMISSIONS_SUBFIELDS_CHOICE_MAP:
fieldsList.append(DRIVE_PERMISSIONS_SUBFIELDS_CHOICE_MAP[myarg])
@@ -67466,7 +67564,7 @@ def printShowDriveFileACLs(users, useDomainAdminAccess=False):
addTitle = None
roles = set()
oneItemPerRow = pmselect = showTitles = False
includePermissionsForView = None
includePermissionsForView = set()
fieldsList = []
OBY = OrderBy(DRIVEFILE_ORDERBY_CHOICE_MAP)
PM = PermissionMatch()
@@ -67501,13 +67599,14 @@ def printShowDriveFileACLs(users, useDomainAdminAccess=False):
elif PM.ProcessArgument(myarg):
pass
elif myarg == 'includepermissionsforview':
includePermissionsForView = getChoice(DRIVEFILE_PERMISSIONS_FOR_VIEW_CHOICES)
_getIncludePermissionsForView(includePermissionsForView)
else:
FJQC.GetFormatJSONQuoteChar(myarg, True)
_checkFileIdEntityDomainAccess(fileIdEntity, useDomainAdminAccess)
if fieldsList:
if roles:
fieldsList.append('role')
includePermissionsForView = _finalizeIncludePermissionsForView(includePermissionsForView)
fields = getItemFieldsFromFieldsList('permissions', fieldsList, True)
printKeys, timeObjects = _getDriveFileACLPrintKeysTimeObjects()
i, count, users = getEntityArgument(users)

View File

@@ -812,6 +812,12 @@ def getVersion(api):
api = _INFO[api].get('mappedAPI', api)
return (api, version, v2discovery)
def getAPIsList():
apisList = set()
for api, value in _INFO.items():
apisList.add(value.get('mappedAPI', api))
return apisList
def getClientScopesSet(api):
return {scope['scope'] for scope in _CLIENT_SCOPES if scope['api'] == api}

View File

@@ -151,6 +151,8 @@ CUSTOMER_ID = 'customer_id'
DEBUG_LEVEL = 'debug_level'
# redact sensitive credentials from debug output
DEBUG_REDACTION = 'debug_redaction'
# Developer Preview APIs
DEVELOPER_PREVIEW_APIS = 'developer_preview_apis'
# Developer Preview API Key
DEVELOPER_PREVIEW_API_KEY = 'developer_preview_api_key'
# When retrieving lists of ChromeOS devices from API, how many should be retrieved in each chunk
@@ -385,6 +387,7 @@ Defaults = {
CUSTOMER_ID: MY_CUSTOMER,
DEBUG_LEVEL: '0',
DEBUG_REDACTION: TRUE,
DEVELOPER_PREVIEW_APIS: '',
DEVELOPER_PREVIEW_API_KEY: '',
DEVICE_MAX_RESULTS: '200',
DOMAIN: '',
@@ -557,6 +560,7 @@ VAR_INFO = {
CUSTOMER_ID: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'CUSTOMER_ID', VAR_LIMITS: (0, None)},
DEBUG_LEVEL: {VAR_TYPE: TYPE_INTEGER, VAR_SIGFILE: 'debug.gam', VAR_LIMITS: (0, None), VAR_SFFT: ('0', '4')},
DEBUG_REDACTION: {VAR_TYPE: TYPE_BOOLEAN},
DEVELOPER_PREVIEW_APIS: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
DEVELOPER_PREVIEW_API_KEY: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
DEVICE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 200)},
DOMAIN: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'GA_DOMAIN', VAR_LIMITS: (0, None)},

View File

@@ -111,6 +111,8 @@ DEBUG_LEVEL = 'dbgl'
DEBUG_REDACTION = 'dbrd'
# Decoded ID token
DECODED_ID_TOKEN = 'didt'
# Developer Preview APIs
DEVELOPER_PREVIEW_APIS = 'dapi'
# Index of start of <UserTypeEntity> in command line
ENTITY_CL_DELAY_START = 'ecld'
ENTITY_CL_START = 'ecls'
@@ -267,6 +269,7 @@ Globals = {
DEBUG_LEVEL: 0,
DEBUG_REDACTION: True,
DECODED_ID_TOKEN: None,
DEVELOPER_PREVIEW_APIS: set(),
ENTITY_CL_DELAY_START: 1,
ENTITY_CL_START: 1,
EXTRA_ARGS_LIST: [],

View File

@@ -236,6 +236,7 @@ DATA_TRANSFER_COMPLETED = 'Data Transfer completed: {0}\n'
DATA_UPLOADED_TO_DRIVE_FILE = 'Data uploaded to Drive File'
DEFAULT_SMIME = 'Default S/MIME'
DELETED = 'Deleted'
DEVELOPER_PREVIEW_REQUIRED = 'Developer Preview is required for this command\n'
DEVICE_LIST_BUG = 'GAM hit Google internal bug 237397223. Please file a Google Support ticket stating that you are encountering this bug.'
DEVICE_LIST_BUG_WORKAROUND_NOT_POSSIBLE = 'GAM workaround for this issue only works if orderby argument is not used and query does not contain \'register\'.'
DEVICE_LIST_BUG_ATTEMPTING_WORKAROUND = 'GAM is attempting to work around the bug by filtering for devices created on or after the newest we\'ve seen ({0})...\n'

View File

@@ -282,10 +282,11 @@ gam show chromepolicies
((ou|orgunit <OrgUnitItem> [show all|direct|inherited])|(group <GroupItem>))
[(printerid <PrinterID>)|(appid <AppID>)]
[filter <StringList>] [namespace <NamespaceList>]
[show all|direct|inherited]
[formatjson]
```
By default, all Chrome policies for the OU or group are displayed.
* `filter <String>` - Display policies based on fields like its resource name, description and additionalTargetKeyNames.
* `filter <StringList>` - Display policies based on fields like its resource name, description and additionalTargetKeyNames.
* `show all` - For OUs, display policies regardless of where set; this is the default
* `show direct` - For OUs, display policies set directly in the OU
* `show inherited` - For OUs, display policies set in a parent OU
@@ -329,15 +330,25 @@ By default, Gam displays the information as an indented list of keys and values.
gam print chromepolicies [todrive <ToDriveAttribute>*]
((ou|orgunit <OrgUnitItem> [show all|direct|inherited])|(group <GroupItem>))
[(printerid <PrinterID>)|(appid <AppID>)]
[filter <String>] [namespace <NamespaceList>]
[filter <StringList>] [namespace <NamespaceList>]
[show all|direct|inherited] [shownopolicy]
[[formatjson [quotechar <Character>]]
```
By default, all Chrome policies for the OU or group are displayed.
* `filter <String>` - Display policies based on fields like its resource name, description and additionalTargetKeyNames.
* `filter <StringList>` - Display policies based on fields like its resource name, description and additionalTargetKeyNames.
* `show all` - For OUs, display policies regardless of where set; this is the default
* `show direct` - For OUs, display policies set directly in the OU
* `show inherited` - For OUs, display policies set in a parent OU
Use option `shownopolicy` to display output like the following if no policies apply to the OU or group.
```
gam print chromepolicies ou /Test appid chrome:emidddocikgklceeeifefomdnbkldhng namespace chrome.users.apps shownopolicy
Getting all Chrome Policies that match query (chrome.users.apps.*) for /Test
Got 0 Chrome Policies that matched query (chrome.users.apps.*) for /Test...
name,orgUnitPath,parentOrgUnitPath,direct,appId
noPolicy,/Test,/,False,chrome:emidddocikgklceeeifefomdnbkldhng
```
These are the default namespaces; use `namespace <NamespaceList>` to override.
* `default`
* chrome.users

View File

@@ -13,7 +13,7 @@
- [Display user group member options](#display-user-group-member-options)
- [Display group membership in CSV format](#display-group-membership-in-csv-format)
- [Display group membership in hierarchical format](#display-group-membership-in-hierarchical-format)
- [Display external users in groups with allowExternalMembers False](#display-external-users-in-groups-with-allowexternalmembers-false)
- [Manage external users in groups with allowExternalMembers False](#manage-external-users-in-groups-with-allowexternalmembers-false)
## API documentation
* [Cloud Identity Groups Overview](https://cloud.google.com/identity/docs/groups)
* [Cloud Identity Groups API - Groups](https://cloud.google.com/identity/docs/reference/rest/v1/groups)
@@ -534,6 +534,40 @@ To show the structure of all groups you can do the following; it will be time co
gam redirect stdout ./groups.txt show cigroup-members types group
```
## Display external users in groups with allowExternalMembers False
When printing group membership, the option `verifyallowexternal` causes
GAM to only display external users in groups with `allowExternalMembers=False`.
## Manage external users in groups with allowExternalMembers False
* See: https://support.google.com/a/answer/16778447
Get external members of groups with allowExternalMembers = False
```
gam redirect csv ./ExternalMembersGroupsWithAEMFalse.csv print cigroup-members verifyallowexternal
```
Update selected groups to allowExternalMembers = True
* Add a column labelled `update` to ExternalMembersGroupsWithAEMFalse.csv
* For groups to be updated, add an x to the `update` column for any member of the group to be updated
```
gam redirect stdout ./UpdateGroupsWithAEMFalseToAEMTrue.txt redirect stderr stdout update group csvkmd ExternalMembersGroupsWithAEMFalse.csv keyfield group matchfield update x allowexternalmembers true
```
Update all groups to allowExternalMembers = True
**Caution, be sure that this is what you want**
```
gam redirect stdout ./UpdateGroupsWithAEMFalseToEMTrue.txt redirect stderr stdout update group csvkmd ExternalMembersGroupsWithAEMFalse.csv keyfield group allowexternalmembers true
```
Delete selected external members from groups with allowExternalMembers = False
* Add a column labelled `delete` to ExternalMembersGroupsWithAEMFalse.csv
* For exernal members to be deleted, add an x to the `delete` column
* The `preview` option let's you verify what external members are to be deleted, remove it to do the deletions
```
gam redirect csv ./DeletedMembersFromGroupsWithAEMFalse.csv redirect stdout ./DeleteMembersFromGroupsWithAEMFalse.txt redirect stderr stdout update group csvkmd ExternalMembersGroupsWithAEMFalse.csv keyfield group matchfield delete x datafield email delete preview actioncsv csvdata email
```
Delete all external members from groups with allowExternalMembers = False
**Caution, be sure that this is what you want**
* The `preview` option let's you verify what external members are to be deleted, remove it to do the deletions
```
gam redirect csv ./DeletedMembersFromGroupsWithAEMFalse.csv redirect stdout ./DeleteMembersFromGroupsWithAEMFalse.txt redirect stderr stdout update group csvkmd ExternalMembersGroupsWithAEMFalse.csv keyfield group datafield email delete preview actioncsv csvdata email
```

View File

@@ -10,6 +10,41 @@ 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
### 7.33.01
Added option `shownopolicy` to `gam print chromepolicies` that will display output like the following
if no policies apply to the selected OU or group.
```
gam print chromepolicies ou /Test appid chrome:emidddocikgklceeeifefomdnbkldhng namespace chrome.users.apps shownopolicy
Getting all Chrome Policies that match query (chrome.users.apps.*) for /Test
Got 0 Chrome Policies that matched query (chrome.users.apps.*) for /Test...
name,orgUnitPath,parentOrgUnitPath,direct,appId
noPolicy,/Test,/,False,chrome:emidddocikgklceeeifefomdnbkldhng
```
### 7.33.00
Added variable `developer_preview_apis` to `gam.cfg` that is a comma separated list of APIs requiring a Developer Preview key.
Currently, `chat` is the only API that requires a Developer Preview key; it is required for the User Sections commands.
* See: https://github.com/GAM-team/GAM/wiki/Users-Chat#introduction
* See: https://github.com/GAM-team/GAM/wiki/Users-Chat#manage-chat-user-sections
### 7.32.07
Added option `includepermissionsforview published` to `gam <UserTypeEntity> print filelist` and
`gam <UserTypeEntity> show fileinfo`. From the Drive API documentation:
```
Specifies which additional view's permissions to include in the response. Only published is supported.
```
### 7.32.06
Added options to `gam <UserTypeEntity> copy drivefile ... copysubfiles` to limit copying
to files whose `modifiedTime` meets specified requirements.
* `start|starttime <Date>|<Time>` - If specified, `modifiedTime` must be >= the value
* `end|endtime <Date>|<Time>` - If specified, `modifiedTime` must be <= the value
* `range <Date>|<Time> <Date>|<Time>` - first value <= `modifiedTime` <= second value
### 7.32.05
Fixed bug in `gam <UserTypeEntity> print messages|threads ... headers <SMTPHeaderList>` where

View File

@@ -252,7 +252,7 @@ writes the credentials into the file oauth2.txt.
admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt
admin@server:/Users/admin$ gam version
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
GAM 7.32.05 - https://github.com/GAM-team/GAM - pyinstaller
GAM 7.33.01 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.2 64-bit final
macOS Tahoe 26.2 x86_64
@@ -550,6 +550,7 @@ Section: DEFAULT
cache_discovery_only = true
channel_customer_id = ''
charset = utf-8
chat_max_results = 100
classroom_max_results = 0
client_secrets_json = client_secrets.json ; /Users/admin/GAMConfig/client_secrets.json
clock_skew_in_seconds = 10
@@ -559,6 +560,7 @@ Section: DEFAULT
config_dir = /Users/admin/GAMConfig
contact_max_results = 100
csv_input_column_delimiter = ,
csv_input_no_escape_char = true
csv_input_quote_char = '"'
csv_input_row_drop_filter = ''
csv_input_row_drop_filter_mode = anymatch
@@ -571,32 +573,47 @@ Section: DEFAULT
csv_output_header_drop_filter = ''
csv_output_header_filter = ''
csv_output_header_force = ''
csv_output_header_order = ''
csv_output_line_terminator = lf
csv_output_no_escape_char = false
csv_output_quote_char = '"'
csv_output_row_drop_filter = ''
csv_output_row_drop_filter_mode = anymatch
csv_output_row_filter = ''
csv_output_row_filter_mode = allmatch
csv_output_row_limit = 0
csv_output_sort_headers = ''
csv_output_subfield_delimiter = '.'
csv_output_timestamp_column = ''
csv_output_users_audit = false
customer_id = C01234567
debug_level = 0
debug_redaction = true
developer_preview_api_key = ''
developer_preview_apis = ''
device_max_results = 200
domain = domain.com
drive_dir = /Users/admin/GAMWork
drive_max_results = 1000
drive_v3_native_names = true
email_batch_size = 50
enable_dasa = false
enable_gcloud_reauth = false
enforce_expansive_access = true
event_max_results = 250
extra_args = ''
gmail_cse_incert_dir = ''
gmail_cse_inkey_dir = ''
input_dir = .
inter_batch_wait = 0
license_max_results = 100
license_skus = ''
member_max_results = 200
member_max_results_ci_basic = 1000
member_max_results_ci_full = 500
message_batch_size = 50
message_max_results = 500
mobile_max_results = 100
multiprocess_pool_limit = 0
never_time = Never
no_browser = false
no_cache = false
@@ -606,13 +623,15 @@ Section: DEFAULT
num_threads = 5
oauth2_txt = oauth2.txt ; /Users/admin/GAMConfig/oauth2.txt
oauth2service_json = oauth2service.json ; /Users/admin/GAMConfig/oauth2service.json
output_dateformat = ''
output_timeformat = ''
people_max_results = 100
print_agu_domains = ''
print_cros_ous = ''
print_cros_ous_and_children = ''
process_wait_limit = 0
quick_cros_move = false
quick_info_user = False
quick_info_user = false
reseller_id = ''
retry_api_service_not_available = false
section = ''
@@ -629,12 +648,13 @@ Section: DEFAULT
smtp_username = ''
timezone = local
tls_max_version = ''
tls_min_version = 'TLSv1_2'
tls_min_version = 'TLSv1_3'
todrive_clearfilter = false
todrive_clientaccess = false
todrive_conversion = true
todrive_localcopy = false
todrive_locale = ''
todrive_no_escape_char = true
todrive_nobrowser = false
todrive_noemail = true
todrive_parent = root
@@ -647,6 +667,8 @@ Section: DEFAULT
todrive_user = ''
truncate_client_id = false
update_cros_ou_with_id = false
use_chat_admin_access = false
use_course_owner_access = false
use_projectid_as_name = false
user_max_results = 500
user_service_account_access_only = false
@@ -751,6 +773,7 @@ Section: DEFAULT
cache_discovery_only = true
channel_customer_id = ''
charset = utf-8
chat_max_results = 100
classroom_max_results = 0
client_secrets_json = client_secrets.json ; C:\GAMConfig\client_secrets.json
clock_skew_in_seconds = 10
@@ -760,6 +783,7 @@ Section: DEFAULT
config_dir = C:\GAMConfig
contact_max_results = 100
csv_input_column_delimiter = ,
csv_input_no_escape_char = true
csv_input_quote_char = '"'
csv_input_row_drop_filter = ''
csv_input_row_drop_filter_mode = anymatch
@@ -772,32 +796,47 @@ Section: DEFAULT
csv_output_header_drop_filter = ''
csv_output_header_filter = ''
csv_output_header_force = ''
csv_output_header_order = ''
csv_output_line_terminator = lf
csv_output_no_escape_char = false
csv_output_quote_char = '"'
csv_output_row_drop_filter = ''
csv_output_row_drop_filter_mode = anymatch
csv_output_row_filter = ''
csv_output_row_filter_mode = allmatch
csv_output_row_limit = 0
csv_output_sort_headers = ''
csv_output_subfield_delimiter = '.'
csv_output_timestamp_column = ''
csv_output_users_audit = false
customer_id = my_customer
debug_level = 0
debug_redaction = true
developer_preview_api_key = ''
developer_preview_apis = ''
device_max_results = 200
domain = ''
drive_dir = C:\GAMWork
drive_max_results = 1000
drive_v3_native_names = true
email_batch_size = 50
enable_dasa = false
enable_gcloud_reauth = false
enforce_expansive_access = true
event_max_results = 250
extra_args = ''
gmail_cse_incert_dir = ''
gmail_cse_inkey_dir = ''
input_dir = .
inter_batch_wait = 0
license_max_results = 100
license_skus = ''
member_max_results = 200
member_max_results_ci_basic = 1000
member_max_results_ci_full = 500
message_batch_size = 50
message_max_results = 500
mobile_max_results = 100
multiprocess_pool_limit = 0
never_time = Never
no_browser = false
no_cache = false
@@ -807,13 +846,15 @@ Section: DEFAULT
num_threads = 5
oauth2_txt = oauth2.txt ; C:\GAMConfig\oauth2.txt
oauth2service_json = oauth2service.json ; C:\GAMConfig\oauth2service.json
output_dateformat = ''
output_timeformat = ''
people_max_results = 100
print_agu_domains = ''
print_cros_ous = ''
print_cros_ous_and_children = ''
process_wait_limit = 0
quick_cros_move = false
quick_info_user = False
quick_info_user = false
reseller_id = ''
retry_api_service_not_available = false
section = ''
@@ -830,12 +871,13 @@ Section: DEFAULT
smtp_username = ''
timezone = utc
tls_max_version = ''
tls_min_version = 'TLSv1_2'
tls_min_version = 'TLSv1_3'
todrive_clearfilter = false
todrive_clientaccess = false
todrive_conversion = true
todrive_localcopy = false
todrive_locale = ''
todrive_no_escape_char = true
todrive_nobrowser = false
todrive_noemail = true
todrive_parent = root
@@ -848,6 +890,8 @@ Section: DEFAULT
todrive_user = ''
truncate_client_id = false
update_cros_ou_with_id = false
use_chat_admin_access = false
use_course_owner_access = false
use_projectid_as_name = false
user_max_results = 500
user_service_account_access_only = false
@@ -990,7 +1034,7 @@ writes the credentials into the file oauth2.txt.
C:\>del C:\GAMConfig\oauth2.txt
C:\>gam version
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
GAM 7.32.05 - https://github.com/GAM-team/GAM - pythonsource
GAM 7.33.01 - https://github.com/GAM-team/GAM - pythonsource
GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.2 64-bit final
Windows 11 10.0.26200 AMD64
@@ -1289,6 +1333,7 @@ Section: DEFAULT
cache_discovery_only = true
channel_customer_id = ''
charset = utf-8
chat_max_results = 100
classroom_max_results = 0
client_secrets_json = client_secrets.json ; C:\GAMConfig\client_secrets.json
clock_skew_in_seconds = 10
@@ -1298,6 +1343,7 @@ Section: DEFAULT
config_dir = C:\GAMConfig
contact_max_results = 100
csv_input_column_delimiter = ,
csv_input_no_escape_char = true
csv_input_quote_char = '"'
csv_input_row_drop_filter = ''
csv_input_row_drop_filter_mode = anymatch
@@ -1310,32 +1356,47 @@ Section: DEFAULT
csv_output_header_drop_filter = ''
csv_output_header_filter = ''
csv_output_header_force = ''
csv_output_header_order = ''
csv_output_line_terminator = lf
csv_output_no_escape_char = false
csv_output_quote_char = '"'
csv_output_row_drop_filter = ''
csv_output_row_drop_filter_mode = anymatch
csv_output_row_filter = ''
csv_output_row_filter_mode = allmatch
csv_output_row_limit = 0
csv_output_sort_headers = ''
csv_output_subfield_delimiter = '.'
csv_output_timestamp_column = ''
csv_output_users_audit = false
customer_id = C01234567
debug_level = 0
debug_redaction = true
developer_preview_api_key = ''
developer_preview_apis = ''
device_max_results = 200
domain = domain.com
drive_dir = C:\GAMWork
drive_max_results = 1000
drive_v3_native_names = true
email_batch_size = 50
enable_dasa = false
enable_gcloud_reauth = false
enforce_expansive_access = true
event_max_results = 250
extra_args = ''
gmail_cse_incert_dir = ''
gmail_cse_inkey_dir = ''
input_dir = .
inter_batch_wait = 0
license_max_results = 100
license_skus = ''
member_max_results = 200
member_max_results_ci_basic = 1000
member_max_results_ci_full = 500
message_batch_size = 50
message_max_results = 500
mobile_max_results = 100
multiprocess_pool_limit = 0
never_time = Never
no_browser = false
no_cache = false
@@ -1353,7 +1414,7 @@ Section: DEFAULT
print_cros_ous_and_children = ''
process_wait_limit = 0
quick_cros_move = false
quick_info_user = False
quick_info_user = false
reseller_id = ''
retry_api_service_not_available = false
section = ''
@@ -1370,12 +1431,13 @@ Section: DEFAULT
smtp_username = ''
timezone = local
tls_max_version = ''
tls_min_version = 'TLSv1_2'
tls_min_version = 'TLSv1_3'
todrive_clearfilter = false
todrive_clientaccess = false
todrive_conversion = true
todrive_localcopy = false
todrive_locale = ''
todrive_no_escape_char = true
todrive_nobrowser = false
todrive_noemail = true
todrive_parent = root
@@ -1388,6 +1450,8 @@ Section: DEFAULT
todrive_user = ''
truncate_client_id = false
update_cros_ou_with_id = false
use_chat_admin_access = false
use_course_owner_access = false
use_projectid_as_name = false
user_max_results = 500
user_service_account_access_only = false

View File

@@ -0,0 +1,34 @@
# Secondary Calendars with no Owner
Here's a start on how to get information for non-owned secondary calendars
Save the CSV file that Google sent you as NoOwnerSecCals.csv
Get calendar description and summary for non-owned secondary calendars.
* There will be one row per calendar.
```
gam config num_threads 10 redirect csv ./NOSC_Details.csv multiprocess redirect stderr - multiprocess csv NoOwnerSecCals.csv gam calendar "~Secondary calendar email" print settings fields description,summary
```
Get event counts for non-owned secondary calendars.
* There will be one row per calendar.
```
gam config num_threads 10 redirect csv ./NOSC_EventCounts.csv multiprocess redirect stderr - multiprocess csv NOSC_Details.csv gam calendar "~calendarId" print events countsonly addcsvdata description "~description" addcsvdata summary "~summary"
```
Get summary for non-owned secondary calendars - Contains details, counts, ACLs
* There will be one row per calendar/ACL combination
```
gam config num_threads 10 redirect csv ./NOSC_Summary.csv multiprocess redirect stderr - multiprocess csv NOSC_EventCounts.csv gam calendar "~calendarId" print acls noselfowner addcsvdata description "~description" addcsvdata summary "~summary" addcsvdata events "~events"
```
You can add an owner.
* Replace `admin@domain.com` with the super admin from: `gam oauth info`
```
gam config num_threads 10 redirect stdout ./Add_NOSC_Owner.txt multiprocess redirect stderr stdout csv NoOwnerSecCals.csv gam calendar "~Secondary calendar email" add acls owner admin@domain.com
```
After inspecting NOSC_Summary.csv, you can delete the calendars if desired.
* Replace `admin@domain.com` with the super admin from: `gam oauth info`
```
gam config num_threads 10 redirect stdout ./Delete_NOSC.txt multiprocess redirect stderr stdout csv NoOwnerSecCals.csv gam user admin@domain.com remove calendar "~Secondary calendar email"
``

View File

@@ -37,7 +37,9 @@ gam user user@domain.com update serviceaccount
[*] 11) Chat API - User Sections (supports readonly)
```
`Chat API - User Sections` is in Developer Preview; you must have a `developer_preview_api_key` in `gam.cfg` to use these commands.
`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`.
```

View File

@@ -111,6 +111,7 @@ gam <UserTypeEntity> copy drivefile <DriveFileEntity>
notusers <EmailAddressList>|
regex <REMatchPattern>|
notregex <REMatchPattern>]
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]|
[copysubfolders [<Boolean>]] [foldernamematchpattern <REMatchPattern>]
[copysubshortcuts [<Boolean>]] [shortcutnamematchpattern <REMatchPattern>]
[duplicatefiles overwriteolder|overwriteall|duplicatename|uniquename|skip]
@@ -182,16 +183,18 @@ You can specify whether sub files, folders and shortcuts are copied. If sub fold
* `copysubshortcuts false` - Sub shortcuts are not copied
* `copysubshortcuts [true]` - Sub shortcuts are copied; this is the default
By default, GAM displays a message referencing files and folders not selected for copying by the options above.
* `suppressnotselectedmessages false` - Do not suppress these messages; this is the default
* `suppressnotselectedmessages [true]` - Suppress these messages
### By default, when copying sub files, all files, regardless of MIME type, are copied.
You can specify restrictions on the MIME types to be copied.
* `filemimetypes <MimeTypeList>` - Copy sub files with the specified MIME types
* `filemimetypes not <MimeTypeList>` - Copy sub files with MIME types other than those specified
* `filemimetypes category <MimeTypeNameList>` - Copy sub files with the specified MIME type categories
### By default, when copying sub files, all files, regardless of their `modifiedTime`, are copied.
You can specify restrictions on the `modifiedTime` to be copied.
* `start|starttime <Date>|<Time>` - If specified, `modifiedTime` must be >= the value
* `end|endtime <Date>|<Time>` - If specified, `modifiedTime` must be <= the value
* `range <Date>|<Time> <Date>|<Time>` - first value <= `modifiedTime` <= second value
### By default, when copying sub files, folders and shortcuts, all are copied.
You can specify `<REMatchPattern>` patterns that limit the items copied based on their name.
* `filenamematchpattern <REMatchPattern>` - Only files whose name matches `<REMatchPattern>` are copied
@@ -207,6 +210,10 @@ You can specify `<REMatchPattern>` patterns that limit the items copied based on
* `copysubfilesownedby regex <REMatchPattern>` - Only files owned by users whose email addresses match `<REMatchPattern>` are copied.
* `copysubfilesownedby notregex <REMatchPattern>` - Only files owned by users whose email addresses do not match `<REMatchPattern>` are copied.
### By default, GAM displays a message referencing files and folders not selected for copying by the options above.
* `suppressnotselectedmessages false` - Do not suppress these messages; this is the default
* `suppressnotselectedmessages [true]` - Suppress these messages
### Specify a new name for the file/folder
* `newfilename <DriveFileName>` - The copied file/folder will be named `<DriveFileName>`
* If `stripnameprefix <String>` is specified, `<String>` will be stripped from the front of `<DriveFileName>`

View File

@@ -430,6 +430,7 @@ gam <UserTypeEntity> show fileinfo <DriveFileEntity>
(orderby <DriveFileOrderByFieldName> [ascending|descending])*
[showdrivename] [showshareddrivepermissions]
[(showlabels details|ids)|(includelabels <ClassificationLabelIDList>)]
[includepermissionsforview published]
[showparentsidsaslist] [followshortcuts [<Boolean>]]
[stripcrsfromname]
[formatjson]
@@ -440,6 +441,7 @@ gam <UserTypeEntity> info drivefile <DriveFileEntity>
(orderby <DriveFileOrderByFieldName> [ascending|descending])*
[showdrivename] [showshareddrivepermissions]
[(showlabels details|ids)|(includelabels <ClassificationLabelIDList>)]
[includepermissionsforview published]
[showparentsidsaslist] [followshortcuts [<Boolean>]]
[stripcrsfromname]
[formatjson]
@@ -1102,6 +1104,7 @@ gam <UserTypeEntity> print|show filelist [todrive <ToDriveAttribute>*]
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
[showdrivename] [showshareddrivepermissions]
[(showlabels details|ids)|(includelabels <ClassificationLabelIDList>)]
[includepermissionsforview published]
[showparentsidsaslist] [showpermissionslast]
(orderby <DriveFileOrderByFieldName> [ascending|descending])* [delimiter <Character>]
[stripcrsfromname]

View File

@@ -3,7 +3,8 @@
- [API documentation](#api-documentation)
- [Definitions](#definitions)
- [Aliases](#aliases)
- [Delegation Notification](#delegation-notification)
- [Delegator Banner](#delegator-banner)
- [Delegate Notification](#delegate-notification)
- [Create Gmail delegates](#create-gmail-delegates)
- [Delete Gmail delegates](#delete-gmail-delegates)
- [Update Gmail delegates](#update-gmail-delegates)
@@ -57,7 +58,13 @@ The `convertalias` option causes GAM to make an extra API call per user in `<Use
to convert aliases to primary email addresses. If you know that all of the email addresses
in `<UserEntity>` are primary, you can omit `convertalias` and avoid the extra API calls.
## Delegation Notification
## Delegator Banner
When creating a delegate, the following banner is displayed in the delegator's Gmail inbox, it can not be suppressed.
```
<Delegate> now has delegated access to your account. This notice will end in 7 days.
```
## Delegate Notification
When creating a delegate, you can send a message to the delegate.
```
[notify [<Boolean>]

View File

@@ -404,7 +404,7 @@ Messages are archived to the group specified by `<GroupItem>`.
### Archive 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_archive` - Limit the number of messages that will be archived; use a value of 0 for no limit
* `max_to_archive <Number>` - Limit the number of messages that will be archived; use a value of 0 for no limit
* `doit` - No messages are archived 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.
@@ -412,8 +412,8 @@ When `matchlabel <LabelName>` is specified, the following characters are replace
&()"|{}/
```
By default, Gam fetches all matching messages from Google and then processes only `max_to_archive` of them.
To speed up fetching, specify `quick` and only `max_to_archive` of the matching messages will be fetched.
By default, Gam fetches all matching messages from Google and then archives only `max_to_archive <Number>` of them.
To speed up fetching, specify `quick` and only `max_to_archive <Number>` of the matching messages will be fetched.
You must still specify `doit` to perform the operation.
By default, the command results are displayed as indented keys and values. Use the `csv` option
@@ -447,6 +447,9 @@ gam <UserTypeEntity> export thread|threads
[targetfolder <FilePath>] [targetname <FileName>] [overwrite [<Boolean>]]
```
By default, Gam fetches all matching messages from Google and then exports only `max_to_export <Number>` of them.
To speed up fetching, specify `quick` and only `max_to_export <Number>` of the matching messages will be fetched.
By default, when exporting a message, it is downloaded to the directory specified in `gam.cfg/drive_dir`.
* `targetfolder <FilePath>` - Specify an alternate location for the downloaded file.
@@ -477,6 +480,9 @@ gam <UserTypeEntity> forward thread|threads recipient|to <RecipientEntity>
[subject <String>] [addorigfieldstosubject]
```
By default, Gam fetches all matching messages from Google and then forwards only `max_to_forward <Number>` of them.
To speed up fetching, specify `quick` and only `max_to_forwrd <Number>` of the matching messages will be fetched.
By default, the message subject has `Fwd: ` prepended; use `subject <String>` to specify a new subject.
All `Cc` addresses are removed from the forwarded message.
@@ -538,7 +544,7 @@ user@domain.com,18e9fc58c5491f4c,Deleted,
### Manage 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_xxx` - Limit the number of messages that will be processed; use a value of 0 for no limit
* `max_to_xxx <Number>` - Limit the number of messages that will be processed; 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.
@@ -546,8 +552,8 @@ When `matchlabel <LabelName>` is specified, the following characters are replace
&()"|{}/
```
By default, Gam fetches all matching messages from Google and then processes only `max_to_process` of them.
To speed up fetching, specify `quick` and only `max_to_process` of the matching messages will be fetched.
By default, Gam fetches all matching messages from Google and then processes only `max_to_process <Number>` of them.
To speed up fetching, specify `quick` and only `max_to_process <Number>` of the matching messages will be fetched.
You must still specify `doit` to perform the operation.
## Delete messages by Message-Id
@@ -611,7 +617,7 @@ gam <UserTypeEntity> print messages|threads [todrive <ToDriveAttribute>*]
```
## Display all messages
By default, Gam displays all messages.
* `max_to_xxx` - Limit the number of messages that will be displayed
* `max_to_print|max_to_show <Number>` - Limit the number of messages that will be displayed
* `includespamtrash` - Include messages in the Spam and Trash folders
By default, all messages in a thread are displayed with `print|show threads`.
@@ -627,7 +633,7 @@ gam user user@domain.com print|show threads maxmessagesperthread 1
## Display 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_xxx` - Limit the number of messages that will be displayed
* `max_to_print|max_to_show <Number>` - Limit the number of messages that will be displayed
* `includespamtrash` - Include messages in the Spam and Trash folders
* `labelmatchpattern <REMatchPattern>` - Only display messages with some label that matches `<REMatchPattern>`
* `labelmatchpattern xyz` - Label must start with xyz
@@ -641,8 +647,8 @@ When `matchlabel <LabelName>` is specified, the following characters are replace
&()"|{}/
```
By default, Gam fetches only `max_to_process` matching messages from Google and then displays them.
To see how many messages actually match, specify `notquick` and all matching messages will be fetched; only `max_to_process` of them will be displayed.
By default, Gam fetches only `max_to_process <Number>` matching messages from Google and then displays them.
To see how many messages actually match, specify `notquick` and all matching messages will be fetched; only `max_to_process <Number>` of them will be displayed.
### Difference between `From` and `Sender` headers
The `From` header specifies the author of the message, that is,

View File

@@ -586,6 +586,9 @@ Getting all Groups for testuser1@domain.com (1/2)
Getting all Groups for testuser2@domain.com (2/2)
User,Groups,GroupsList
testuser2@domain.com,0,
# Get group membership for all users
$ gam config auto_batch_min 1 num_threads 10 redirect csv ./UsersGroups.csv multiprocess sortheaders User,Group redirect stderr - multiprocess all users print groups
```
### Display groups and their parents
Display a user's groups and their parents as an indented list.

View File

@@ -3,7 +3,7 @@
Print the current version of Gam with details
```
gam version
GAM 7.32.05 - https://github.com/GAM-team/GAM - pyinstaller
GAM 7.33.01 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.2 64-bit final
macOS Tahoe 26.2 x86_64
@@ -15,7 +15,7 @@ Time: 2025-12-23T13:57:00-08:00
Print the current version of Gam with details and time offset information
```
gam version timeoffset
GAM 7.32.05 - https://github.com/GAM-team/GAM - pyinstaller
GAM 7.33.01 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.2 64-bit final
macOS Tahoe 26.2 x86_64
@@ -27,7 +27,7 @@ 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
```
gam version extended
GAM 7.32.05 - https://github.com/GAM-team/GAM - pyinstaller
GAM 7.33.01 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.2 64-bit final
macOS Tahoe 26.2 x86_64
@@ -35,7 +35,7 @@ Path: /Users/Admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
Time: 2025-12-23T13:57:00-08:00
Your system time differs from admin.googleapis.com by less than 1 second
OpenSSL 3.5.3 16 Sep 2025
OpenSSL 3.6.1 27 Jan 2026
arrow 1.3.0
chardet 5.2.0
cryptography 46.0.1
@@ -68,7 +68,7 @@ MacOS High Sierra 10.13.6 x86_64
Path: /Users/Admin/bin/gam7
Version Check:
Current: 5.35.08
Latest: 7.32.05
Latest: 7.33.01
echo $?
1
```
@@ -76,7 +76,7 @@ echo $?
Print the current version number without details
```
gam version simple
7.32.05
7.33.01
```
In Linux/MacOS you can do:
```
@@ -86,7 +86,7 @@ echo $VER
Print the current version of Gam and address of this Wiki
```
gam help
GAM 7.32.05 - https://github.com/GAM-team/GAM
GAM 7.33.01 - https://github.com/GAM-team/GAM
GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.2 64-bit final
macOS Tahoe 26.2 x86_64

View File

@@ -74,6 +74,7 @@ Client Access
* [Calendars](Calendars)
* [Calendars - Access](Calendars-Access)
* [Calendars - Events](Calendars-Events)
* [Calendars - Secondary Calendars with no Owner](No-Owner-Secondary-Calendars)
* [Chrome Auto Update Expiration Counts](Chrome-AUE-Counts)
* [Chrome Browser Cloud Management](Chrome-Browser-Cloud-Management)
* [Chrome Device Counts](Chrome-Device-Counts)

View File

@@ -307,6 +307,21 @@ debug_level
debug_redaction
Enable/disable redaction of sensitive data from API debugging output
Default: True
developer_preview_apis
A comma separated list of APIs requiring a Developer Preview key.
Default: Blank
Valid values:
accesscontextmanager,admin,alertcenter,analyticsadmin,calendar-json,cbcm,chat,
chromemanagement,chromepolicy,classroom,cloudchannel,cloudidentity,
cloudresourcemanager,contactdelegation,contacts,datastudio,docs,drive,
driveactivity,drivelabels,email-audit,forms,gmail,groupsmigration,groupssettings,
iam,iamcredentials,keep,licensing,meet,mybusinessaccountmanagement,oauth2,
orgpolicy,people,pubsub,reseller,searchconsole,serviceaccountlookup,
servicemanagement,serviceusage,sheets,siteVerification,storage,tagmanager,tasks,
vault,versionhistory,youtube
developer_preview_api_key
A Developer Preview API key that is passed to all API calls for APIs in developer_preview_apis
Default: Blank
device_max_results
When retrieving lists of ChromeOS devices from API,
how many should be retrieved in each API call
@@ -325,13 +340,6 @@ drive_max_results
how many should be retrieved in each API call
Default: 1000
Range: 1 - 1000
drive_v3_beta
Enable/disable use of Drive API v3 beta for Limited Folder Access testing
Default: False
drive_v3_native_names
Enable/disable use of Drive API v3 native column names
in all gam print/show commands related to Google Drive
Default: True
email_batch_size
When archiving, printing, showing, trashing, untrashing, marking as spam Gmail messages.
how many should be processed in each batch
@@ -371,7 +379,7 @@ gmail_cse_inkey_dir
Default: Blank
input_dir
Input directory for files with non-absolute file names.
The default
The default is the current working directory.
Default: .
inter_batch_wait
When processing items in batches, how many seconds should GAM wait between batches
@@ -387,9 +395,6 @@ license_skus
Each item in the list can be a <SKUID> which will be validated or
a <ProductID>/<SKUID> which will not be validated.
Default: Blank
meet_v2_beta
Enable/disable use of Meet API v2 beta for additional Chat Space parameters.
Default: False
member_max_results
When retrieving lists of Google Group members from API,
how many should be retrieved in each API call
@@ -404,7 +409,7 @@ member_max_results_ci_basic
member_max_results_ci_full
When retrieving lists of Cloud Identity Group members from API
with either the basic or full options,
how many should be retrieved in each API call
how many should be retrieved in each API call
Default: 500
Range: 1 - 500
message_batch_size
@@ -577,7 +582,7 @@ timezone
to your local timezone. If you are running GAM on a remote computer or on a
cloud shell, "local" will mean the time at the remote/cloud shell computer,
not your location, Use "+|-hh:mm" to specify the timezone at your location.
Starting with version 7.21.00 you can use a timezone name; the names are case sensitive.
Starting with version 7.21.00 you can use a timezone name; the names are case sensitive.
See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
Default: utc
Range: utc|z|local|(+|-hh:mm)|<ValidTimezoneName>
@@ -937,7 +942,7 @@ Edit gam.cfg to set up additional clients; it should look like this when complet
activity_max_results = 100
admin_email = ''
api_calls_rate_check = false
api_calls_rate_limit = 1000
api_calls_rate_limit = 100
api_calls_tries_limit = 10
auto_batch_min = 0
bail_on_internal_error_tries = 2
@@ -947,55 +952,74 @@ cache_dir = /Users/admin/.gam/gamcache
cache_discovery_only = true
channel_customer_id = ''
charset = utf-8
cmdlog = ''
cmdlog_max_backups = 5
cmdlog_max_kilo_bytes = 1000
chat_max_results = 100
classroom_max_results = 0
client_secrets_json = client_secrets.json
clock_skew_in_seconds = 10
cmdlog = ''
cmdlog_max_backups = 5
cmdlog_max_kilo_bytes = 1000
config_dir = /Users/admin/.gam
contact_max_results = 100
csv_input_column_delimiter = ,
csv_input_no_escape_char = true
csv_input_quote_char = '"'
csv_input_row_drop_filter = ''
csv_input_row_drop_filter_mode = anymatch
csv_input_row_filter = ''
csv_input_row_filter_mode = allmatch
csv_input_row_limit = 0
csv_output_column_delimiter = ,
csv_output_convert_cr_nl = false
csv_output_field_delimiter = ' '
csv_output_header_drop_filter = ''
csv_output_header_filter = ''
csv_output_header_force = ''
csv_output_header_order = ''
csv_output_line_terminator = lf
csv_output_no_escape_char = false
csv_output_quote_char = '"'
csv_output_row_drop_filter =
csv_output_row_drop_filter = ''
csv_output_row_drop_filter_mode = anymatch
csv_output_row_filter = ''
csv_output_row_filter_mode = allmatch
csv_output_row_limit = 0
csv_output_sort_headers = ''
csv_output_subfield_delimiter = '.'
csv_output_timestamp_column = ''
csv_output_users_audit = false
customer_id = my_customer
debug_level = 0
debug_redaction = true
developer_preview_api_key = ''
developer_preview_apis = ''
device_max_results = 200
domain =
domain = ''
drive_dir = /Users/admin/Downloads
drive_max_results = 1000
drive_v3_native_names = true
email_batch_size = 100
email_batch_size = 50
enable_dasa = false
enable_gcloud_reauth = false
enforce_expansive_access = true
event_max_results = 250
extra_args =
extra_args = ''
gmail_cse_incert_dir = ''
gmail_cse_inkey_dir = ''
input_dir = .
inter_batch_wait = 0
license_max_results = 100
license_sku = ''
license_skus = ''
member_max_results = 200
member_max_results_ci_basic = 1000
member_max_results_ci_full = 500
message_batch_size = 50
message_max_results = 1000
message_max_results = 500
mobile_max_results = 100
multiprocess_pool_limit = 0
never_time = Never
no_browser = false
no_cache = false
no_short_urls = true
no_update_check = true
no_verify_ssl = false
num_tbatch_threads = 2
@@ -1009,9 +1033,10 @@ print_agu_domains = ''
print_cros_ous = ''
print_cros_ous_and_children = ''
process_wait_limit = 0
quick_cros_move = False
quick_info_user = False
quick_cros_move = false
quick_info_user = false
reseller_id = ''
retry_api_service_not_available = false
section =
show_api_calls_retry_data = false
show_commands = false
@@ -1026,26 +1051,28 @@ smtp_password = ''
smtp_username = ''
timezone = utc
tls_max_version = ''
tls_min_version = 'TLSv1_2'
tls_min_version = 'TLSv1_3'
todrive_clearfilter = false
todrive_clientaccess = false
todrive_conversion = true
todrive_localcopy = false
todrive_locale = ''
todrive_no_escape_char = true
todrive_nobrowser = false
todrive_noemail = true
todrive_no_escape_char = true
todrive_parent = root
todrive_sheet_timeformat = ''
todrive_sheet_timestamp = false
todrive_timeformat = ''
todrive_timestamp = false
todrive_timezone = ''
todrive_upload_nodata = true
todrive_user = ''
truncate_client_id = false
update_cros_ou_with_id = false
use_chat_admin_access = false
use_course_owner_access = false
use_projectid_as_name = false
user_max_results = 500
user_service_account_access_only = false