mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-28 01:41:36 +00:00
Added option showitemcountonly to various commands
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
- [Print a header row and fields for selected CrOS devices](#print-a-header-row-and-fields-for-selected-cros-devices)
|
||||
- [Print a header row and fields for specified CrOS devices](#print-a-header-row-and-fields-for-specified-cros-devices)
|
||||
- [Display Examples](#display-examples)
|
||||
- [Display CrOS device count](#display-cros-device-count)
|
||||
- [Display CrOS device counts](#display-cros-device-counts)
|
||||
- [Print ChromeOS device activity](#print-chromeos-device-activity)
|
||||
- [Print a header row and activity for selected CrOS devices](#print-a-header-row-and-activity-for-selected-cros-devices)
|
||||
- [Print a header row and activity for specified CrOS devices](#print-a-header-row-and-activity-for-specified-cros-devices)
|
||||
@@ -683,10 +683,17 @@ Print information about CrOS devices synced between 45 days ago and 30 days ago:
|
||||
gam print cros query "sync:#querytime1#..#querytime2#" querytime1 -45d querytime2 -30d
|
||||
```
|
||||
|
||||
## Display CrOS device count
|
||||
## Display CrOS device counts
|
||||
Display the number of CrOS devices in an entity.
|
||||
```
|
||||
gam <CrOSTypeEntity> show count
|
||||
gam <CrOSTypeEntity> print cros showitemcountonly
|
||||
gam print cros select <CrOSTypeEntity> showitemcountonly
|
||||
gam print cros
|
||||
[(query <QueryCrOS>)|(queries <QueryCrOSList>) [querytime<String> <Time>]
|
||||
[(limittoou|cros_ou <OrgUnitItem>)|(cros_ou_and_children <OrgUnitItem>)|
|
||||
(cros_ous <OrgUnitList>)|(cros_ous_and_children <OrgUnitList>)]]
|
||||
showitemcountonly
|
||||
```
|
||||
|
||||
## Print ChromeOS device activity
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
- [Manage course aliases](#manage-course-aliases)
|
||||
- [Manage course topics](#manage-course-topics)
|
||||
- [Display courses](#display-courses)
|
||||
- [Display course counts](#display-course-counts)
|
||||
- [Display course announcements](#display-course-announcements)
|
||||
- [Display course materials](#display-course-materials)
|
||||
- [Display course topics](#display-course-topics)
|
||||
@@ -432,6 +433,15 @@ When using the `formatjson` option, double quotes are used extensively in the da
|
||||
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.
|
||||
|
||||
## Display course counts
|
||||
Display the number of courses.
|
||||
```
|
||||
gam print courses
|
||||
(course|class <CourseEntity>)*|([teacher <UserItem>] [student <UserItem>] [states <CourseStateList>])
|
||||
[owneremailmatchpattern <RegularExpression>]
|
||||
showitemcountonly
|
||||
```
|
||||
|
||||
## Display course announcements
|
||||
```
|
||||
gam print course-announcements [todrive <ToDriveAttribute>*]
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
- [Legacy manage membership](#legacy-manage-membership)
|
||||
- [Bulk membership changes](#bulk-membership-changes)
|
||||
- [Display course membership](#display-course-membership)
|
||||
- [Display course membership counts](#display-course-membership-counts)
|
||||
|
||||
## API documentation
|
||||
* https://developers.google.com/classroom/reference/rest/
|
||||
@@ -131,3 +132,12 @@ the quote character itself, the column delimiter (comma by default) and new-line
|
||||
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.
|
||||
|
||||
## Display course membership counts
|
||||
Display the number of course participants.
|
||||
```
|
||||
gam print course-participants
|
||||
(course|class <CourseID>)*|([teacher <UserItem>] [student <UserItem>]) [states <CourseStateList>]
|
||||
[show all|students|teachers]
|
||||
showitemcountonly
|
||||
```
|
||||
|
||||
@@ -9,11 +9,13 @@
|
||||
- [Synchronize devices](#synchronize-devices)
|
||||
- [Display devices](#display-devices)
|
||||
- [Print devices](#print-devices)
|
||||
- [Display device counts](#display-device-counts)
|
||||
- [Approve or block device users](#approve-or-block-device-users)
|
||||
- [Delete device users](#delete-device-users)
|
||||
- [Wipe device users](#wipe-device-users)
|
||||
- [Perform device user actions](#perform-device-user-actions)
|
||||
- [Display device users](#display-device-users)
|
||||
- [Display device user counts](#display-device-user-counts)
|
||||
- [Print device users](#print-device-users)
|
||||
- [Display device user client state](#display-device-user-client-state)
|
||||
- [Update device user client state](#update-device-user-client-state)
|
||||
@@ -225,6 +227,15 @@ When using the `formatjson` option, double quotes are used extensively in the da
|
||||
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.
|
||||
|
||||
## Display device counts
|
||||
Display the number of devices.
|
||||
```
|
||||
gam print devices
|
||||
[(query <QueryDevice>)|(queries <QueryDeviceList>) (querytime<String> <Time>)*]
|
||||
[all|company|personal|nocompanydevices|nopersonaldevices]
|
||||
showitemcountonly
|
||||
```
|
||||
|
||||
## Approve or block device users
|
||||
Approve or block user profiles on a device.
|
||||
```
|
||||
@@ -285,6 +296,15 @@ When using the `formatjson` option, double quotes are used extensively in the da
|
||||
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.
|
||||
|
||||
## Display device user counts
|
||||
Display the number of device users.
|
||||
```
|
||||
gam print deviceusers [todrive <ToDriveAttribute>*]
|
||||
[select <DeviceID>]
|
||||
[(query <QueryDevice>)|(queries <QueryDeviceList>) (querytime<String> <Time>)*]
|
||||
showitemcountonly
|
||||
```
|
||||
|
||||
## Display device user client state
|
||||
```
|
||||
gam info deviceuserstate <DeviceUserEntity> [clientid <String>]
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
- [Manage groups](#manage-groups)
|
||||
- [Display information about individual groups](#display-information-about-individual-groups)
|
||||
- [Display information about multiple groups](#display-information-about-multiple-groups)
|
||||
- [Display group counts](#display-group-counts)
|
||||
|
||||
## API documentation
|
||||
* https://developers.google.com/admin-sdk/directory/reference/rest/v1/groups
|
||||
@@ -376,3 +377,14 @@ gam print cigroups query "'cloudidentity.googleapis.com/groups.dynamic' in label
|
||||
```
|
||||
gam print cigroups query "'cloudidentity.googleapis.com/groups.security' in labels"
|
||||
```
|
||||
|
||||
## Display group counts
|
||||
Display the number of groups.
|
||||
```
|
||||
gam print cigroups
|
||||
[(cimember|showownedby <UserItem>)|(select <GroupEntity>)|(query <String>)]
|
||||
[emailmatchpattern [not] <RegularExpression>] [namematchpattern [not] <RegularExpression>]
|
||||
[descriptionmatchpattern [not] <RegularExpression>]
|
||||
showitemcountonly
|
||||
```
|
||||
|
||||
|
||||
@@ -11,6 +11,23 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
|
||||
|
||||
See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation
|
||||
|
||||
### 6.67.17
|
||||
|
||||
Added option `showitemcountonly` to various commands that causes GAM to display the
|
||||
item count on stdout; no CSV file is written.
|
||||
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Groups#display-group-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Classroom-Courses#display-course-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Classroom-Membership#display-course-membership-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/ChromeOS-Devices#display-cros-device-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Devices#display-device-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Devices#display-device-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Groups#display-group-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Mobile-Devices#display-mobile-device-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Organizational-Units#display-organizational-unit-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Resources#display-resource-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users#display-user-counts
|
||||
|
||||
### 6.67.16
|
||||
|
||||
By default, `gam print group-members membernames` displays `Unknown` for members whose names can not be determined.
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
- [Display information about selected groups](#display-information-about-selected-groups)
|
||||
- [Display a group and its parents](#Display-a-group-and-its-parents)
|
||||
- [Examples](#Examples)
|
||||
- [Display group counts](#display-group-counts)
|
||||
|
||||
## API documentation
|
||||
* https://developers.google.com/admin-sdk/directory/reference/rest/v1/groups
|
||||
@@ -563,3 +564,14 @@ Group,Name,ParentsCount,Parents,ParentsName
|
||||
testgroup2@domain.com,Test - Group 2,2,testgroup1@domain.com|testgroup@domain.com,Test Group1|Test Group Org
|
||||
testgroup2@domain.com,Test - Group 2,1,testgroup@domain.net,Test Group Net
|
||||
```
|
||||
## Display group counts
|
||||
Display the number of groups.
|
||||
```
|
||||
gam print groups
|
||||
[([domain|domains <DomainNameEntity>] ([member|showownedby <EmailItem>]|[(query <QueryGroup>)|(queries <QueryGroupList>)]))|
|
||||
(select <GroupEntity>)]
|
||||
[emailmatchpattern [not] <RegularExpression>] [namematchpattern [not] <RegularExpression>]
|
||||
[descriptionmatchpattern [not] <RegularExpression>] (matchsetting [not] <GroupAttribute>)*
|
||||
[admincreatedmatch <Boolean>]
|
||||
showitemcountonly
|
||||
```
|
||||
|
||||
@@ -334,7 +334,7 @@ writes the credentials into the file oauth2.txt.
|
||||
admin@server:/Users/admin/bin/gamadv-xtd3$ rm -f /Users/admin/GAMConfig/oauth2.txt
|
||||
admin@server:/Users/admin/bin/gamadv-xtd3$ ./gam version
|
||||
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
|
||||
GAMADV-XTD3 6.67.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.67.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.1 64-bit final
|
||||
MacOS Sonoma 14.2.1 x86_64
|
||||
@@ -1002,7 +1002,7 @@ writes the credentials into the file oauth2.txt.
|
||||
C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt
|
||||
C:\GAMADV-XTD3>gam version
|
||||
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
||||
GAMADV-XTD3 6.67.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.67.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.1 64-bit final
|
||||
Windows-10-10.0.17134 AMD64
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
- [Manage mobile devices](#manage-mobile-devices)
|
||||
- [Display mobile devices](#display-mobile-devices)
|
||||
- [Print mobile devices](#print-mobile-devices)
|
||||
- [Display mobile device counts](#display-mobile-device-counts)
|
||||
|
||||
## API documentation
|
||||
* https://developers.google.com/admin-sdk/directory/reference/rest/v1/mobiledevices
|
||||
@@ -150,3 +151,10 @@ When using the `formatjson` option, double quotes are used extensively in the da
|
||||
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.
|
||||
|
||||
## Display mobile device counts
|
||||
Display the number of mobile devices.
|
||||
```
|
||||
gam print mobile
|
||||
[(query <QueryMobile>)|(queries <QueryMobileList>) (querytime<String> <Time>)*]
|
||||
showitemcountonly
|
||||
```
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
- [Synchronize ChromeOS devices with an organizational unit](#synchronize-chromeos-devices-with-an-organizational-unit)
|
||||
- [Display organizational units](#display-organizational-units)
|
||||
- [Print organizational units](#print-organizational-units)
|
||||
- [Display orgamizational unit counts](#display-organizational-unit-counts)
|
||||
- [Display indented organizational unit tree](#display-indented-organizational-unit-tree)
|
||||
- [Special case handling for large number of organizational units](#special-case-handling-for-large-number-of-organizational-units)
|
||||
|
||||
@@ -237,6 +238,14 @@ Get file count summaries by OU; top level selector is ou, sub level selectors ar
|
||||
gam redirect csv ./TopLevelOUs.csv print ous showparent toplevelonly parentselector ou childselector ou_and_children fields orgunitpath
|
||||
gam redirect csv ./FileCounts.csv multiprocess csv ./TopLevelOUs.csv gam "~orgUnitSelector" "~orgUnitPath" print filecounts excludetrashed summary only summaryuser "~orgUnitPath"
|
||||
```
|
||||
## Display organizational unit counts
|
||||
Display the number of organizational units.
|
||||
```
|
||||
gam print orgs|ous
|
||||
[fromparent <OrgUnitItem>] [showparent [Boolean>]] [toplevelonly]
|
||||
showitemcountonly
|
||||
```
|
||||
|
||||
## Display indented organizational unit tree
|
||||
```
|
||||
gam show orgtree [fromparent <OrgUnitItem>] [batchsuborgs [<Boolean>]]
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
- [Display features](#display-features)
|
||||
- [Manage resources](#manage-resources)
|
||||
- [Display resources](#display-resources)
|
||||
- [Display resource counts](#display-resource-counts)
|
||||
- [Manage resource calendar ACLs](#manage-resource-calendar-acls)
|
||||
- [Display resource calendar ACLs](#display-resource-calendar-acls)
|
||||
|
||||
@@ -245,6 +246,14 @@ Print all resources and their owners.
|
||||
gam config csv_output_row_filter "role:regex:owner" redirect csv Resource.csv print resources acls
|
||||
```
|
||||
|
||||
## Display resource counts
|
||||
Display the number of mobile devices.
|
||||
```
|
||||
gam print resources
|
||||
[query <String>]
|
||||
showitemcountonly
|
||||
```
|
||||
|
||||
## Manage resource calendar ACLs
|
||||
These commands operate on a single resource calendar.
|
||||
```
|
||||
|
||||
@@ -172,6 +172,7 @@
|
||||
(gdoc|ghtml <UserGoogleDoc>)|
|
||||
(gcsdoc|gcshtml <StorageBucketObjectName>)|
|
||||
(emlfile <FileName> [charset <Charset>]))
|
||||
```
|
||||
## Message queries with dates
|
||||
```
|
||||
query <QueryGmail> [querytime<String> <Date>]*
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
- [Print domain counts for users in a specific domain and/or selected by a query](#print-domain-counts-for-users-in-a-specific-domain-and-or-selected-by-a-query)
|
||||
- [Print domain counts for users specified by `<UserTypeEntity>`](#print-domain-counts-for-users-specified-by-usertypeentity)
|
||||
- [Print user list](#print-user-list)
|
||||
- [Display user count](#display-user-count)
|
||||
- [Display user counts](#display-user-counts)
|
||||
|
||||
## API documentation
|
||||
* https://developers.google.com/admin-sdk/directory/reference/rest/v1/users
|
||||
@@ -1206,9 +1206,15 @@ $ more UsersList.csv
|
||||
["testuser1@domain.org", "testuser2@domain.org", "testuser3@domain.org", "testuser4@domain.org"]
|
||||
```
|
||||
|
||||
## Display user count
|
||||
## Display user counts
|
||||
Display the number of users in an entity.
|
||||
```
|
||||
gam <UserTypeEntity> show count
|
||||
gam <UserTypeEntity> print users showitemcountonly
|
||||
gam print users select <UserTypeEntity> showitemcountonly
|
||||
gam print users
|
||||
([domain|domains <DomainNameEntity>] [(query <QueryUser>)|(queries <QueryUserList>)]
|
||||
[limittoou <OrgUnitItem>] [deleted_only|only_deleted])|[select <UserTypeEntity>]
|
||||
[issuspended <Boolean>]
|
||||
showitemcountonly
|
||||
```
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Print the current version of Gam with details
|
||||
```
|
||||
gam version
|
||||
GAMADV-XTD3 6.67.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.67.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.1 64-bit final
|
||||
MacOS Sonoma 14.2.1 x86_64
|
||||
@@ -16,7 +16,7 @@ Time: 2023-06-02T21:10:00-07:00
|
||||
Print the current version of Gam with details and time offset information
|
||||
```
|
||||
gam version timeoffset
|
||||
GAMADV-XTD3 6.67.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.67.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.1 64-bit final
|
||||
MacOS Sonoma 14.2.1 x86_64
|
||||
@@ -28,7 +28,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
|
||||
GAMADV-XTD3 6.67.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.67.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.1 64-bit final
|
||||
MacOS Sonoma 14.2.1 x86_64
|
||||
@@ -65,7 +65,7 @@ MacOS High Sierra 10.13.6 x86_64
|
||||
Path: /Users/Admin/bin/gamadv-xtd3
|
||||
Version Check:
|
||||
Current: 5.35.08
|
||||
Latest: 6.67.16
|
||||
Latest: 6.67.17
|
||||
echo $?
|
||||
1
|
||||
```
|
||||
@@ -73,7 +73,7 @@ echo $?
|
||||
Print the current version number without details
|
||||
```
|
||||
gam version simple
|
||||
6.67.16
|
||||
6.67.17
|
||||
```
|
||||
In Linux/MacOS you can do:
|
||||
```
|
||||
@@ -83,7 +83,7 @@ echo $VER
|
||||
Print the current version of Gam and address of this Wiki
|
||||
```
|
||||
gam help
|
||||
GAM 6.67.16 - https://github.com/taers232c/GAMADV-XTD3
|
||||
GAM 6.67.17 - https://github.com/taers232c/GAMADV-XTD3
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.1 64-bit final
|
||||
MacOS Sonoma 14.2.1 x86_64
|
||||
|
||||
@@ -2295,6 +2295,7 @@ gam print cros [todrive <ToDriveAttribute>*]
|
||||
[timerangeorder ascending|descending] [showdvrsfp]
|
||||
[sortheaders]
|
||||
[formatjson [quotechar <Character>]]
|
||||
[showitemcountonly]
|
||||
|
||||
Print fields for specified CrOS devices.
|
||||
|
||||
@@ -2307,6 +2308,7 @@ gam print cros [todrive <ToDriveAttribute>*] select <CrOSTypeEntity>
|
||||
[timerangeorder ascending|descending] [showdvrsfp]
|
||||
[sortheaders]
|
||||
[formatjson [quotechar <Character>]]
|
||||
[showitemcountonly]
|
||||
|
||||
gam <CrOSTypeEntity> print cros [todrive <ToDriveAttribute>*]
|
||||
[orderby <CrOSOrderByFieldName> [ascending|descending]]
|
||||
@@ -2317,6 +2319,7 @@ gam <CrOSTypeEntity> print cros [todrive <ToDriveAttribute>*]
|
||||
[timerangeorder ascending|descending] [showdvrsfp]
|
||||
[sortheaders]
|
||||
[formatjson [quotechar <Character>]]
|
||||
[showitemcountonly]
|
||||
|
||||
The first column will always be deviceId; the remaining field names will be sorted if allfields, basic, full or sortheaders is specified;
|
||||
otherwise, the remaining field names will appear in the order specified.
|
||||
@@ -2901,13 +2904,16 @@ gam print courses [todrive <ToDriveAttribute>*]
|
||||
[owneremail] [owneremailmatchpattern <RegularExpression>]
|
||||
[alias|aliases|aliasesincolumns [delimiter <Character>]]
|
||||
[show all|students|teachers] [countsonly]
|
||||
[timefilter creationtime|updatetime] [start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>]
|
||||
[fields <CourseFieldNameList>] [skipfields <CourseFieldNameList>]
|
||||
[formatjson [quotechar <Character>]]
|
||||
[timefilter creationtime|updatetime] [start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>]
|
||||
[showitemcountonly]
|
||||
|
||||
gam print course-participants [todrive <ToDriveAttribute>*]
|
||||
(course|class <CourseEntity>)*|([teacher <UserItem>] [student <UserItem>] [states <CourseStateList>])
|
||||
[show all|students|teachers]
|
||||
[formatjson [quotechar <Character>]]
|
||||
[showitemcountonly]
|
||||
|
||||
<CourseAnnouncementFieldName> ::=
|
||||
alternatelink|
|
||||
@@ -3616,6 +3622,7 @@ gam print groups [todrive <ToDriveAttribute>*]
|
||||
[memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
|
||||
[convertcrnl] [delimiter <Character>] [sortheaders]
|
||||
[formatjson [quotechar <Character>]]
|
||||
[showitemcountonly]
|
||||
|
||||
gam print grouptree <GroupEntity> [todrive <ToDriveAttribute>*]
|
||||
[showparentsaslist [<Boolean>]] [delimiter <Character>]
|
||||
@@ -3736,6 +3743,7 @@ gam print cigroups [todrive <ToDriveAttribute>*]
|
||||
[memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
|
||||
[convertcrnl] [delimiter <Character>]
|
||||
[formatjson [quotechar <Character>]]
|
||||
[showitemcountonly]
|
||||
|
||||
<CIGroupMembersFieldName> ::=
|
||||
createtime
|
||||
@@ -3860,6 +3868,7 @@ gam print devices [todrive <ToDriveAttribute>*]
|
||||
[all|company|personal|nocompanydevices|nopersonaldevices]
|
||||
[nodeviceusers]
|
||||
[formatjson [quotechar <Character>]]
|
||||
[showitemcountonly]
|
||||
|
||||
<DeviceUserAction> ::=
|
||||
approve|
|
||||
@@ -3883,6 +3892,7 @@ gam print deviceusers [todrive <ToDriveAttribute>*]
|
||||
<DeviceUserFieldName>* [fields <DeviceUserFieldNameList>]
|
||||
[orderby <DeviceOrderByFieldName> [ascending|descending]]
|
||||
[formatjson [quotechar <Character>]]
|
||||
[showitemcountonly]
|
||||
|
||||
gam info deviceuserstate <DeviceUserEntity> [clientid <String>]
|
||||
gam update deviceuserstate <DeviceUserEntity> [clientid <String>]
|
||||
@@ -4025,6 +4035,7 @@ gam print mobile [todrive <ToDriveAttribute>*]
|
||||
[basic|full|allfields] <MobileFieldName>* [fields <MobileFieldNameList>]
|
||||
[delimiter <Character>] [appslimit <Number>] [oneappperrow] [listlimit <Number>]
|
||||
[formatjson [quotechar <Character>]]
|
||||
[showitemcountonly]
|
||||
|
||||
# Organizational Units
|
||||
|
||||
@@ -4067,6 +4078,7 @@ gam print orgs|ous [todrive <ToDriveAttribute>*]
|
||||
[allfields|<OrgUnitFieldName>*|(fields <OrgUnitFieldNameList>)] [convertcrnl] [batchsuborgs [<Boolean>]]
|
||||
[mincroscount <Number>] [maxcroscount <Number>]
|
||||
[minusercount <Number>] [maxusercount <Number>]
|
||||
[showitemcountonly]
|
||||
gam show orgtree [fromparent <OrgUnitItem>] [batchsuborgs [<Boolean>]]
|
||||
|
||||
# Printers
|
||||
@@ -4360,6 +4372,7 @@ gam print resources [todrive <ToDriveAttribute>*] [allfields|<ResourceFieldName>
|
||||
[query <String>]
|
||||
[acls] [noselfowner] [calendar] [convertcrnl]
|
||||
[formatjson [quotechar <Character>]]
|
||||
[showitemcountonly]
|
||||
|
||||
<CalendarACLRole> ::= editor|freebusy|freebusyreader|owner|reader|writer|none
|
||||
<CalendarACLScope> ::= <EmailAddress>|user:<EmailAdress>|group:<EmailAddress>|domain:<DomainName>|domain|default
|
||||
@@ -5342,6 +5355,7 @@ gam print users [todrive <ToDriveAttribute>*]
|
||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
[showitemcountonly]
|
||||
|
||||
Print fields for specified users.
|
||||
|
||||
@@ -5356,6 +5370,7 @@ gam print users [todrive <ToDriveAttribute>*] select <UserTypeEntity>
|
||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
[showitemcountonly]
|
||||
|
||||
gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
||||
[orderby <UserOrderByFieldName> [ascending|descending]]
|
||||
@@ -5368,6 +5383,7 @@ gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
[showitemcountonly]
|
||||
|
||||
The first column will always be primaryEmail; the remaining field names will be sorted if allfields, basic, full or sortheaders is specified;
|
||||
otherwise, the remaining field names will appear in the order specified.
|
||||
|
||||
@@ -2,6 +2,23 @@
|
||||
|
||||
Merged GAM-Team version
|
||||
|
||||
6.67.17
|
||||
|
||||
Added option `showitemcountonly` to various commands that causes GAM to display the
|
||||
item count on stdout; no CSV file is written.
|
||||
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Groups#display-group-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Classroom-Courses#display-course-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Classroom-Membership#display-course-membership-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/ChromeOS-Devices#display-cros-device-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Devices#display-device-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Devices#display-device-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Groups#display-group-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Mobile-Devices#display-mobile-device-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Organizational-Units#display-organizational-unit-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Resources#display-resource-counts
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users#display-user-counts
|
||||
|
||||
6.67.16
|
||||
|
||||
By default, `gam print group-members membernames` displays `Unknown` for members whose names can not be determined.
|
||||
|
||||
@@ -17148,6 +17148,7 @@ def getOrgUnitIdToPathMap(cd=None):
|
||||
# [allfields|<OrgUnitFieldName>*|(fields <OrgUnitFieldNameList>)] [convertcrnl] [batchsuborgs [<Boolean>]]
|
||||
# [mincroscount <Number>] [maxcroscount <Number>]
|
||||
# [minusercount <Number>] [maxusercount <Number>]
|
||||
# [showitemcountonly]
|
||||
def doPrintOrgs():
|
||||
cd = buildGAPIObject(API.DIRECTORY)
|
||||
convertCRNL = GC.Values[GC.CSV_OUTPUT_CONVERT_CR_NL]
|
||||
@@ -17160,6 +17161,7 @@ def doPrintOrgs():
|
||||
minCrOSCounts = maxCrOSCounts = minUserCounts = maxUserCounts = -1
|
||||
crosCounts = {}
|
||||
userCounts = {}
|
||||
showItemCountOnly = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if myarg == 'todrive':
|
||||
@@ -17203,6 +17205,8 @@ def doPrintOrgs():
|
||||
invalidChoiceExit(field, list(ORG_ARGUMENT_TO_FIELD_MAP), True)
|
||||
elif myarg in {'convertcrnl', 'converttextnl'}:
|
||||
convertCRNL = True
|
||||
elif myarg == 'showitemcountonly':
|
||||
showItemCountOnly = True
|
||||
else:
|
||||
unknownArgumentExit()
|
||||
if childSelector:
|
||||
@@ -17216,6 +17220,9 @@ def doPrintOrgs():
|
||||
for field in PRINT_ORGS_DEFAULT_FIELDS:
|
||||
csvPF.AddField(field, ORG_ARGUMENT_TO_FIELD_MAP, fieldsList)
|
||||
orgUnits = _getOrgUnits(cd, orgUnitPath, fieldsList, listType, showParent, batchSubOrgs, childSelector, parentSelector)
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{0 if orgUnits is None else (len(orgUnits))}\n')
|
||||
return
|
||||
if orgUnits is None:
|
||||
return
|
||||
if showUserCounts:
|
||||
@@ -23463,6 +23470,7 @@ CROS_INDEXED_TITLES = ['activeTimeRanges', 'recentUsers', 'deviceFiles',
|
||||
# [(query <QueryCrOS>)|(queries <QueryCrOSList>) [querytime<String> <Time>]
|
||||
# [(limittoou|cros_ou <OrgUnitItem>)|(cros_ou_and_children <OrgUnitItem>)|
|
||||
# (cros_ous <OrgUnitList>)|(cros_ous_and_children <OrgUnitList>)]]
|
||||
# [showitemcountonly]
|
||||
# gam print cros [todrive <ToDriveAttribute>*] select <CrOSTypeEntity>
|
||||
# gam <CrOSTypeEntity> print cros [todrive <ToDriveAttribute>*]
|
||||
# [orderby <CrOSOrderByFieldName> [ascending|descending]]
|
||||
@@ -23473,6 +23481,7 @@ CROS_INDEXED_TITLES = ['activeTimeRanges', 'recentUsers', 'deviceFiles',
|
||||
# [timerangeorder ascending|descending] [showdvrsfp]
|
||||
# [sortheaders]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
# [showitemcountonly]
|
||||
def doPrintCrOSDevices(entityList=None):
|
||||
def _printCrOS(cros):
|
||||
checkTPMVulnerability(cros)
|
||||
@@ -23607,6 +23616,7 @@ def doPrintCrOSDevices(entityList=None):
|
||||
selectionAllowed = False
|
||||
allFields = noLists = oneRow = showDVRstorageFreePercentage = sortHeaders = False
|
||||
activeTimeRangesOrder = 'ASCENDING'
|
||||
showItemCountOnly = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if myarg == 'todrive':
|
||||
@@ -23676,6 +23686,8 @@ def doPrintCrOSDevices(entityList=None):
|
||||
invalidChoiceExit(field, CROS_LIST_FIELDS_CHOICE_MAP, True)
|
||||
elif myarg == 'showdvrsfp':
|
||||
showDVRstorageFreePercentage = True
|
||||
elif myarg == 'showitemcountonly':
|
||||
showItemCountOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, False)
|
||||
if selectedLists:
|
||||
@@ -23716,8 +23728,9 @@ def doPrintCrOSDevices(entityList=None):
|
||||
tokenRetries = 0
|
||||
pageToken, totalItems = _processGAPIpagesResult(feed, 'chromeosdevices', None, totalItems, pageMessage, None, Ent.CROS_DEVICE)
|
||||
if feed:
|
||||
for cros in feed.get('chromeosdevices', []):
|
||||
_printCrOS(cros)
|
||||
if not showItemCountOnly:
|
||||
for cros in feed.get('chromeosdevices', []):
|
||||
_printCrOS(cros)
|
||||
del feed
|
||||
if not pageToken:
|
||||
_finalizeGAPIpagesResult(pageMessage)
|
||||
@@ -23742,7 +23755,13 @@ def doPrintCrOSDevices(entityList=None):
|
||||
return
|
||||
except (GAPI.badRequest, GAPI.resourceNotFound, GAPI.forbidden):
|
||||
accessErrorExit(cd)
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{totalItems}\n')
|
||||
return
|
||||
else:
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{len(entityList)}\n')
|
||||
return
|
||||
sortRows = True
|
||||
if allFields or len(set(fieldsList)) > 1:
|
||||
jcount = len(entityList)
|
||||
@@ -25202,7 +25221,7 @@ def _getChatMemberEmail(cd, member):
|
||||
if 'member' in member:
|
||||
if member['member']['type'] == 'HUMAN':
|
||||
_, memberUid = member['member']['name'].split('/')
|
||||
member['member']['email'], status = convertUIDtoEmailAddressWithType(f'uid:{memberUid}', cd, emailTypes=['user'])
|
||||
member['member']['email'], _ = convertUIDtoEmailAddressWithType(f'uid:{memberUid}', cd, emailTypes=['user'])
|
||||
elif 'groupMember' in member:
|
||||
_, memberUid = member['groupMember']['name'].split('/')
|
||||
member['groupMember']['email'], _ = convertUIDtoEmailAddressWithType(f'uid:{memberUid}', cd, emailTypes=['group'])
|
||||
@@ -27348,6 +27367,7 @@ DEVICE_ORDERBY_CHOICE_MAP = {
|
||||
# [all|company|personal|nocompanydevices|nopersonaldevices]
|
||||
# [nodeviceusers]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
# [showitemcountonly]
|
||||
def doPrintCIDevices():
|
||||
ci = buildGAPICIDeviceServiceObject()
|
||||
customer = _getCustomersCustomerIdNoC()
|
||||
@@ -27361,6 +27381,7 @@ def doPrintCIDevices():
|
||||
queries = [None]
|
||||
view, entityType = DEVICE_VIEW_CHOICE_MAP['all']
|
||||
getDeviceUsers = True
|
||||
showItemCountOnly = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
@@ -27381,11 +27402,14 @@ def doPrintCIDevices():
|
||||
pass
|
||||
elif myarg == 'sortheaders':
|
||||
pass
|
||||
elif myarg == 'showitemcountonly':
|
||||
showItemCountOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||
fields = getItemFieldsFromFieldsList('devices', fieldsList)
|
||||
userFields = getItemFieldsFromFieldsList('deviceUsers', userFieldsList)
|
||||
substituteQueryTimes(queries, queryTimes)
|
||||
itemCount = 0
|
||||
for query in queries:
|
||||
printGettingAllAccountEntities(entityType, query)
|
||||
pageMessage = getPageMessage()
|
||||
@@ -27396,6 +27420,9 @@ def doPrintCIDevices():
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
customer=customer, filter=query,
|
||||
orderBy=OBY.orderBy, view=view, fields=fields, pageSize=100)
|
||||
if showItemCountOnly:
|
||||
itemCount += len(devices)
|
||||
continue
|
||||
except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||
entityActionFailedWarning([entityType, None], str(e))
|
||||
continue
|
||||
@@ -27430,6 +27457,9 @@ def doPrintCIDevices():
|
||||
csvPF.WriteRowNoFilter({'name': device['name'],
|
||||
'JSON': json.dumps(cleanJSON(device, timeObjects=DEVICE_TIME_OBJECTS),
|
||||
ensure_ascii=False, sort_keys=True)})
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{itemCount}\n')
|
||||
return
|
||||
csvPF.writeCSVfile('Devices')
|
||||
|
||||
DEVICE_USER_ACTION_CHOICES = {'approve', 'block', 'cancelwipe', 'wipe'}
|
||||
@@ -27533,6 +27563,7 @@ def doInfoCIDeviceUser():
|
||||
# <DeviceUserFieldName>* [fields <DevieUserFieldNameList>]
|
||||
# [orderby <DeviceOrderByFieldName> [ascending|descending]]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
# [showitemcountonly]
|
||||
def doPrintCIDeviceUsers():
|
||||
ci = buildGAPICIDeviceServiceObject()
|
||||
customer = _getCustomersCustomerIdNoC()
|
||||
@@ -27543,6 +27574,7 @@ def doPrintCIDeviceUsers():
|
||||
queryTimes = {}
|
||||
queries = [None]
|
||||
parent = 'devices/-'
|
||||
showItemCountOnly = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
@@ -27561,10 +27593,13 @@ def doPrintCIDeviceUsers():
|
||||
pass
|
||||
elif myarg == 'sortheaders':
|
||||
pass
|
||||
elif myarg == 'showitemcountonly':
|
||||
showItemCountOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||
userFields = getItemFieldsFromFieldsList('deviceUsers', userFieldsList)
|
||||
substituteQueryTimes(queries, queryTimes)
|
||||
itemCount = 0
|
||||
for query in queries:
|
||||
printGettingAllAccountEntities(Ent.DEVICE_USER, query)
|
||||
pageMessage = getPageMessage()
|
||||
@@ -27575,6 +27610,9 @@ def doPrintCIDeviceUsers():
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
customer=customer, filter=query,
|
||||
orderBy=OBY.orderBy, parent=parent, fields=userFields, pageSize=20)
|
||||
if showItemCountOnly:
|
||||
itemCount += len(deviceUsers)
|
||||
continue
|
||||
for deviceUser in deviceUsers:
|
||||
row = flattenJSON(deviceUser, timeObjects=DEVICE_TIME_OBJECTS)
|
||||
if not FJQC.formatJSON:
|
||||
@@ -27586,6 +27624,9 @@ def doPrintCIDeviceUsers():
|
||||
except (GAPI.invalid, GAPI.permissionDenied) as e:
|
||||
entityActionFailedWarning([Ent.DEVICE_USER, None], str(e))
|
||||
break
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{itemCount}\n')
|
||||
return
|
||||
csvPF.writeCSVfile('Device Users')
|
||||
|
||||
DEVICE_USER_COMPLIANCE_STATE_CHOICE_MAP = {
|
||||
@@ -29319,6 +29360,7 @@ MOBILE_ORDERBY_CHOICE_MAP = {
|
||||
# [basic|full|allfields] <MobileFieldName>* [fields <MobileFieldNameList>]
|
||||
# [delimiter <Character>] [appslimit <Number>] [oneappperrow] [listlimit <Number>]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
# [showitemcountonly]
|
||||
def doPrintMobileDevices():
|
||||
def _appDetails(app):
|
||||
appDetails = []
|
||||
@@ -29389,6 +29431,7 @@ def doPrintMobileDevices():
|
||||
delimiter = GC.Values[GC.CSV_OUTPUT_FIELD_DELIMITER]
|
||||
listLimit = 1
|
||||
appsLimit = -1
|
||||
showItemCountOnly = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if myarg == 'todrive':
|
||||
@@ -29409,6 +29452,8 @@ def doPrintMobileDevices():
|
||||
oneAppPerRow = True
|
||||
elif _getMobileFieldsArguments(myarg, parameters):
|
||||
pass
|
||||
elif myarg == 'showitemcountonly':
|
||||
showItemCountOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||
if not FJQC.formatJSON:
|
||||
@@ -29417,6 +29462,7 @@ def doPrintMobileDevices():
|
||||
parameters['projection'] = 'FULL'
|
||||
fields = getItemFieldsFromFieldsList('mobiledevices', parameters['fieldsList'])
|
||||
substituteQueryTimes(queries, queryTimes)
|
||||
itemCount = 0
|
||||
for query in queries:
|
||||
printGettingAllAccountEntities(Ent.MOBILE_DEVICE, query)
|
||||
pageMessage = getPageMessage()
|
||||
@@ -29428,8 +29474,11 @@ def doPrintMobileDevices():
|
||||
customerId=GC.Values[GC.CUSTOMER_ID], query=query, projection=parameters['projection'],
|
||||
orderBy=orderBy, sortOrder=sortOrder, fields=fields, maxResults=GC.Values[GC.MOBILE_MAX_RESULTS])
|
||||
for mobiles in feed:
|
||||
totalItems += len(mobiles)
|
||||
if showItemCountOnly:
|
||||
itemCount += len(mobiles)
|
||||
continue
|
||||
for mobile in mobiles:
|
||||
totalItems += 1
|
||||
_printMobile(mobile)
|
||||
printGotAccountEntities(totalItems)
|
||||
except GAPI.invalidInput:
|
||||
@@ -29437,6 +29486,9 @@ def doPrintMobileDevices():
|
||||
return
|
||||
except (GAPI.badRequest, GAPI.resourceNotFound, GAPI.forbidden):
|
||||
accessErrorExit(cd)
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{itemCount}\n')
|
||||
return
|
||||
csvPF.writeCSVfile('Mobile')
|
||||
|
||||
GROUP_DISCOVER_CHOICES = {
|
||||
@@ -31352,8 +31404,10 @@ PRINT_GROUPS_JSON_TITLES = ['email', 'JSON']
|
||||
# [memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
|
||||
# [convertcrnl] [delimiter <Character>] [sortheaders]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
# [showitemcountonly]
|
||||
def doPrintGroups():
|
||||
def _printGroupRow(groupEntity, groupSettings, groupMembers):
|
||||
nonlocal itemCount
|
||||
row = {}
|
||||
if matchSettings:
|
||||
if not isinstance(groupSettings, dict):
|
||||
@@ -31366,6 +31420,9 @@ def doPrintGroups():
|
||||
return
|
||||
if showOwnedBy and not checkGroupShowOwnedBy(showOwnedBy, groupMembers):
|
||||
return
|
||||
if showItemCountOnly:
|
||||
itemCount += 1
|
||||
return
|
||||
if deprecatedAttributesSet and isinstance(groupSettings, dict):
|
||||
deprecatedKeys = []
|
||||
for key in groupSettings:
|
||||
@@ -31533,6 +31590,7 @@ def doPrintGroups():
|
||||
matchSettings = {}
|
||||
deprecatedAttributesSet = set()
|
||||
ciGroups = {}
|
||||
showItemCountOnly = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if myarg == 'todrive':
|
||||
@@ -31613,6 +31671,8 @@ def doPrintGroups():
|
||||
pass
|
||||
elif myarg == 'includederivedmembership':
|
||||
memberOptions[MEMBEROPTION_INCLUDEDERIVEDMEMBERSHIP] = True
|
||||
elif myarg == 'showitemcountonly':
|
||||
showItemCountOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, False)
|
||||
if not typesSet:
|
||||
@@ -31751,6 +31811,7 @@ def doPrintGroups():
|
||||
gsbatch = gs.new_batch_http_request(callback=_callbackProcessGroupSettings)
|
||||
gsbcount = 0
|
||||
groupData = {}
|
||||
itemCount = 0
|
||||
i = 0
|
||||
count = len(entityList)
|
||||
for groupEntity in entityList:
|
||||
@@ -31793,6 +31854,9 @@ def doPrintGroups():
|
||||
if getSettings and gsbcount > 0:
|
||||
gsbatch.execute()
|
||||
_writeCompleteRows()
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{itemCount}\n')
|
||||
return
|
||||
if sortHeaders:
|
||||
sortTitles = ['email']+GROUP_INFO_PRINT_ORDER+['aliases', 'nonEditableAliases']
|
||||
if getSettings:
|
||||
@@ -33413,12 +33477,17 @@ PRINT_CIGROUPS_JSON_TITLES = ['email', 'JSON']
|
||||
# [memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
|
||||
# [convertcrnl] [delimiter <Character>]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
# [showitemcountonly]
|
||||
def doPrintCIGroups():
|
||||
def _printGroupRow(groupEntity, groupMembers):
|
||||
nonlocal itemCount
|
||||
for member in groupMembers:
|
||||
getCIGroupMemberRoleFixType(member)
|
||||
if showOwnedBy and not checkCIGroupShowOwnedBy(showOwnedBy, groupMembers):
|
||||
return
|
||||
if showItemCountOnly:
|
||||
itemCount += 1
|
||||
return
|
||||
if not keepName:
|
||||
groupEntity.pop('name', None)
|
||||
row = {}
|
||||
@@ -33458,6 +33527,7 @@ def doPrintCIGroups():
|
||||
memberOptions = initMemberOptions()
|
||||
entitySelection = groupMembers = memberQuery = query = showOwnedBy = None
|
||||
matchPatterns = {}
|
||||
showItemCountOnly = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if myarg == 'todrive':
|
||||
@@ -33508,6 +33578,8 @@ def doPrintCIGroups():
|
||||
pass
|
||||
elif myarg == 'memberrestrictions':
|
||||
memberRestrictions = True
|
||||
elif myarg == 'showitemcountonly':
|
||||
showItemCountOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, False)
|
||||
if not typesSet:
|
||||
@@ -33601,6 +33673,7 @@ def doPrintCIGroups():
|
||||
GAPI.forbidden, GAPI.badRequest, GAPI.invalid,
|
||||
GAPI.systemError, GAPI.permissionDenied, GAPI.serviceNotAvailable) as e:
|
||||
entityActionFailedWarning([Ent.CLOUD_IDENTITY_GROUP, groupEmail], str(e), i, count)
|
||||
itemCount = 0
|
||||
i = 0
|
||||
count = len(entityList)
|
||||
for groupEntity in entityList:
|
||||
@@ -33644,6 +33717,9 @@ def doPrintCIGroups():
|
||||
GAPI.systemError, GAPI.permissionDenied, GAPI.serviceNotAvailable) as e:
|
||||
entityActionFailedWarning([Ent.CLOUD_IDENTITY_GROUP, groupEmail], str(e), i, count)
|
||||
_printGroupRow(groupEntity, groupMembers)
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{itemCount}\n')
|
||||
return
|
||||
if sortHeaders:
|
||||
sortTitles = ['email']+CIGROUP_PRINT_ORDER
|
||||
if rolesSet:
|
||||
@@ -35214,6 +35290,7 @@ RESOURCE_FIELDS_CHOICE_MAP = {
|
||||
# [allfields|<ResourceFieldName>*|(fields <ResourceFieldNameList>)]
|
||||
# [query <String>]
|
||||
# [acls] [noselfowner] [calendar] [convertcrnl] [formatjson [quotechar <Character>]]
|
||||
# [showitemcountonly]
|
||||
def doPrintShowResourceCalendars():
|
||||
cd = buildGAPIObject(API.DIRECTORY)
|
||||
convertCRNL = GC.Values[GC.CSV_OUTPUT_CONVERT_CR_NL]
|
||||
@@ -35222,6 +35299,7 @@ def doPrintShowResourceCalendars():
|
||||
fieldsList = []
|
||||
csvPF = CSVPrintFile() if Act.csvFormat() else None
|
||||
FJQC = FormatJSONQuoteChar(csvPF)
|
||||
showItemCountOnly = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
@@ -35254,6 +35332,8 @@ def doPrintShowResourceCalendars():
|
||||
invalidChoiceExit(field, RESOURCE_FIELDS_CHOICE_MAP, True)
|
||||
elif myarg in {'convertcrnl', 'converttextnl'}:
|
||||
convertCRNL = True
|
||||
elif myarg == 'showitemcountonly':
|
||||
showItemCountOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, False)
|
||||
if not fieldsList:
|
||||
@@ -35286,8 +35366,11 @@ def doPrintShowResourceCalendars():
|
||||
except GAPI.invalidInput as e:
|
||||
entityActionFailedWarning([Ent.RESOURCE_CALENDAR, ''], str(e))
|
||||
return
|
||||
i = 0
|
||||
count = len(resources)
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{count}\n')
|
||||
return
|
||||
i = 0
|
||||
for resource in resources:
|
||||
i += 1
|
||||
if getCalSettings or getCalPermissions:
|
||||
@@ -42487,6 +42570,7 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
|
||||
# [userview] [basic|full|allfields | <UserFieldName>* | fields <UserFieldNameList>]
|
||||
# [delimiter <Character>] [sortheaders] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
# [showitemcountonly]
|
||||
#
|
||||
# gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
||||
# [groups|groupsincolumns]
|
||||
@@ -42497,16 +42581,19 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
|
||||
# [userview] [basic|full|allfields | <UserFieldName>* | fields <UserFieldNameList>]
|
||||
# [delimiter <Character>] [sortheaders] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
# [showitemcountonly]
|
||||
#
|
||||
# gam print users [todrive <ToDriveAttribute>*]
|
||||
# ([domain <DomainName>] [(query <QueryUser>)|(queries <QueryUserList>)]
|
||||
# [limittoou <OrgUnitItem>] [deleted_only|only_deleted])|[select <UserTypeEntity>]
|
||||
# [formatjson [quotechar <Character>]] [countonly]
|
||||
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
# [showitemcountonly]
|
||||
#
|
||||
# gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
||||
# [formatjson [quotechar <Character>]] [countonly]
|
||||
# [issuspended <Boolean>]
|
||||
# [showitemcountonly]
|
||||
def doPrintUsers(entityList=None):
|
||||
def _printUser(userEntity, i, count):
|
||||
if isSuspended is None or isSuspended == userEntity.get('suspended', isSuspended):
|
||||
@@ -42632,6 +42719,7 @@ def doPrintUsers(entityList=None):
|
||||
aliasMatchPattern = isSuspended = orgUnitPath = orgUnitPathLower = orderBy = sortOrder = None
|
||||
viewType = 'admin_view'
|
||||
delimiter = GC.Values[GC.CSV_OUTPUT_FIELD_DELIMITER]
|
||||
showItemCountOnly = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if myarg == 'todrive':
|
||||
@@ -42704,6 +42792,8 @@ def doPrintUsers(entityList=None):
|
||||
maxResults = getInteger(minVal=1, maxVal=500)
|
||||
elif myarg == 'quoteplusphonenumbers':
|
||||
quotePlusPhoneNumbers = True
|
||||
elif myarg == 'showitemcountonly':
|
||||
showItemCountOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, False)
|
||||
_, _, entityList = getEntityArgument(entityList)
|
||||
@@ -42739,6 +42829,7 @@ def doPrintUsers(entityList=None):
|
||||
if orgUnitPath is not None and fieldsList:
|
||||
fieldsList.append('orgUnitPath')
|
||||
fields = getItemFieldsFromFieldsList('users', fieldsList)
|
||||
itemCount = 0
|
||||
for kwargsQuery in makeUserGroupDomainQueryFilters(kwargsDict):
|
||||
kwargs = kwargsQuery[0]
|
||||
query = kwargsQuery[1]
|
||||
@@ -42754,6 +42845,9 @@ def doPrintUsers(entityList=None):
|
||||
showDeleted=showDeleted, orderBy=orderBy, sortOrder=sortOrder, viewType=viewType,
|
||||
projection=projection, customFieldMask=customFieldMask, maxResults=maxResults, **kwargs)
|
||||
for users in feed:
|
||||
if showItemCountOnly:
|
||||
itemCount += len(users)
|
||||
continue
|
||||
if orgUnitPath is None:
|
||||
if not printOptions['countOnly']:
|
||||
for user in users:
|
||||
@@ -42785,7 +42879,13 @@ def doPrintUsers(entityList=None):
|
||||
continue
|
||||
except (GAPI.badRequest, GAPI.resourceNotFound, GAPI.forbidden):
|
||||
accessErrorExit(cd)
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{itemCount}\n')
|
||||
return
|
||||
else:
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{len(entityList)}\n')
|
||||
return
|
||||
sortRows = True
|
||||
# If no individual fields were specified (allfields, basic, full) or individual fields other than primaryEmail were specified, look up each user
|
||||
if isSuspended is not None:
|
||||
@@ -45057,6 +45157,7 @@ def _getCoursesInfo(croom, courseSelectionParameters, courseShowProperties, getO
|
||||
# [show none|all|students|teachers] [countsonly]
|
||||
# [fields <CourseFieldNameList>] [skipfields <CourseFieldNameList>] [formatjson [quotechar <Character>]]
|
||||
# [timefilter creationtime|updatetime] [start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>]
|
||||
# [showitemcountonly]
|
||||
def doPrintCourses():
|
||||
def _saveParticipants(course, participants, role, rtitles):
|
||||
jcount = len(participants)
|
||||
@@ -45097,6 +45198,7 @@ def doPrintCourses():
|
||||
courseShowProperties = _initCourseShowProperties()
|
||||
ownerEmails = {}
|
||||
delimiter = GC.Values[GC.CSV_OUTPUT_FIELD_DELIMITER]
|
||||
showItemCountOnly = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if myarg == 'todrive':
|
||||
@@ -45109,6 +45211,8 @@ def doPrintCourses():
|
||||
delimiter = getCharacter()
|
||||
elif _getCourseShowProperties(myarg, courseShowProperties):
|
||||
pass
|
||||
elif myarg == 'showitemcountonly':
|
||||
showItemCountOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||
applyCourseItemFilter = _setApplyCourseItemFilter(courseItemFilter, None)
|
||||
@@ -45117,6 +45221,8 @@ def doPrintCourses():
|
||||
courseShowProperties['fields'].append(courseItemFilter['timefilter'])
|
||||
coursesInfo = _getCoursesInfo(croom, courseSelectionParameters, courseShowProperties)
|
||||
if coursesInfo is None:
|
||||
if showItemCountOnly:
|
||||
writeStdout('0\n')
|
||||
return
|
||||
if courseShowProperties['aliases']:
|
||||
if FJQC.formatJSON:
|
||||
@@ -45142,6 +45248,7 @@ def doPrintCourses():
|
||||
studentsFields = 'nextPageToken,students(profile)'
|
||||
else:
|
||||
teachersFields = studentsFields = None
|
||||
itemCount = 0
|
||||
count = len(coursesInfo)
|
||||
i = 0
|
||||
for course in coursesInfo:
|
||||
@@ -45156,6 +45263,9 @@ def doPrintCourses():
|
||||
[Ent.COURSE, courseId, Ent.OWNER_ID, course['ownerId']], i, count)
|
||||
if courseShowProperties['ownerEmailMatchPattern'] and not courseShowProperties['ownerEmailMatchPattern'].match(course['ownerEmail']):
|
||||
continue
|
||||
if showItemCountOnly:
|
||||
itemCount += 1
|
||||
continue
|
||||
aliases, teachers, students = _getCourseAliasesMembers(croom, courseId, courseShowProperties, teachersFields, studentsFields, True, i, count)
|
||||
if courseShowProperties['aliases']:
|
||||
if not courseShowProperties['aliasesInColumns']:
|
||||
@@ -45187,6 +45297,9 @@ def doPrintCourses():
|
||||
else:
|
||||
row['JSON-students'] = json.dumps(len(students))
|
||||
csvPF.WriteRowNoFilter(row)
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{itemCount}\n')
|
||||
return
|
||||
if not FJQC.formatJSON:
|
||||
if courseShowProperties['aliases']:
|
||||
csvPF.AddTitles('Aliases')
|
||||
@@ -45853,6 +45966,7 @@ COURSE_PARTICIPANTS_SORT_TITLES = ['courseId', 'courseName', 'userRole', 'userId
|
||||
# gam print course-participants [todrive <ToDriveAttribute>*]
|
||||
# (course|class <CourseEntity>)*|([teacher <UserItem>] [student <UserItem>] [states <CourseStateList>])
|
||||
# [show all|students|teachers] [formatjson [quotechar <Character>]]
|
||||
# [showitemcountonly]
|
||||
def doPrintCourseParticipants():
|
||||
croom = buildGAPIObject(API.CLASSROOM)
|
||||
csvPF = CSVPrintFile(['courseId', 'courseName'])
|
||||
@@ -45860,6 +45974,7 @@ def doPrintCourseParticipants():
|
||||
courseSelectionParameters = _initCourseSelectionParameters()
|
||||
courseShowProperties = _initCourseShowProperties(['name'])
|
||||
courseShowProperties['members'] = 'all'
|
||||
showItemCountOnly = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if myarg == 'todrive':
|
||||
@@ -45868,10 +45983,14 @@ def doPrintCourseParticipants():
|
||||
pass
|
||||
elif myarg == 'show':
|
||||
courseShowProperties['members'] = getChoice(COURSE_MEMBER_ARGUMENTS)
|
||||
elif myarg == 'showitemcountonly':
|
||||
showItemCountOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, False)
|
||||
coursesInfo = _getCoursesInfo(croom, courseSelectionParameters, courseShowProperties)
|
||||
if coursesInfo is None:
|
||||
if showItemCountOnly:
|
||||
writeStdout('0\n')
|
||||
return
|
||||
if courseShowProperties['members'] != 'none':
|
||||
if courseShowProperties['members'] != 'students':
|
||||
@@ -45884,12 +46003,19 @@ def doPrintCourseParticipants():
|
||||
studentsFields = 'nextPageToken,students(userId,profile)'
|
||||
else:
|
||||
teachersFields = studentsFields = None
|
||||
i = 0
|
||||
itemCount = 0
|
||||
count = len(coursesInfo)
|
||||
i = 0
|
||||
for course in coursesInfo:
|
||||
i += 1
|
||||
courseId = course['id']
|
||||
_, teachers, students = _getCourseAliasesMembers(croom, courseId, courseShowProperties, teachersFields, studentsFields, True, i, count)
|
||||
if showItemCountOnly:
|
||||
if courseShowProperties['members'] != 'students':
|
||||
itemCount += len(teachers)
|
||||
if courseShowProperties['members'] != 'teachers':
|
||||
itemCount += len(students)
|
||||
continue
|
||||
if not FJQC.formatJSON:
|
||||
if courseShowProperties['members'] != 'none':
|
||||
if courseShowProperties['members'] != 'students':
|
||||
@@ -45906,6 +46032,9 @@ def doPrintCourseParticipants():
|
||||
if courseShowProperties['members'] != 'teachers':
|
||||
row['JSON-students'] = json.dumps(list(students))
|
||||
csvPF.WriteRowNoFilter(row)
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{itemCount}\n')
|
||||
return
|
||||
if not FJQC.formatJSON:
|
||||
csvPF.SetSortTitles(COURSE_PARTICIPANTS_SORT_TITLES)
|
||||
csvPF.writeCSVfile('Course Participants')
|
||||
|
||||
Reference in New Issue
Block a user