mirror of
https://github.com/GAM-team/GAM.git
synced 2026-07-03 12:21:35 +00:00
Added options showvalidcolumn and addcsvdata to `gam print use
This commit is contained in:
@@ -89,15 +89,6 @@ If you run a Google Workspace Education SKU, verify that the super admin you'll
|
|||||||
* Choose "All users are 18 or older"
|
* Choose "All users are 18 or older"
|
||||||
* Click "SAVE"
|
* Click "SAVE"
|
||||||
|
|
||||||
Verify whether the super admin you'll be using is in an OU where reauthentication is required.
|
|
||||||
* Access the admin console and go to Security -> Overview
|
|
||||||
* Scroll down and open Google Cloud session control section
|
|
||||||
* Select the OU containing the super admin
|
|
||||||
* If Require reauthentication is selected and Exempt Trusted apps is not checked, you'll have to do `gam oauth create` at whatever frequency is specified
|
|
||||||
* If that sounds unappealing, check Exempt Trusted apps
|
|
||||||
* Click "OVERRIDE"
|
|
||||||
* Follow the steps below to mark GAM as a trusted app
|
|
||||||
|
|
||||||
Based on your domain policies, you may have to mark GAM as a trusted app. These steps are performed after a project is created.
|
Based on your domain policies, you may have to mark GAM as a trusted app. These steps are performed after a project is created.
|
||||||
* Access the admin console and go to Security -> Access and data control -> API controls
|
* Access the admin console and go to Security -> Access and data control -> API controls
|
||||||
* Check Trust internal, domain-owned apps
|
* Check Trust internal, domain-owned apps
|
||||||
@@ -114,6 +105,15 @@ Based on your domain policies, you may have to mark GAM as a trusted app. These
|
|||||||
* Click Next/Continue
|
* Click Next/Continue
|
||||||
* Click Finish
|
* Click Finish
|
||||||
|
|
||||||
|
Verify whether the super admin you'll be using is in an OU where reauthentication is required.
|
||||||
|
* Access the admin console and go to Security -> Overview
|
||||||
|
* Scroll down and open Google Cloud session control section
|
||||||
|
* Select the OU containing the super admin
|
||||||
|
* If Require reauthentication is selected and Exempt Trusted apps is not checked, you'll have to do `gam oauth create` at whatever frequency is specified
|
||||||
|
* If that sounds unappealing, check Exempt Trusted apps
|
||||||
|
* Click "OVERRIDE"
|
||||||
|
* Follow the steps below to mark GAM as a trusted app
|
||||||
|
|
||||||
## Headless computers and Cloud Shells
|
## Headless computers and Cloud Shells
|
||||||
With many thanks to Jay, `gam oauth create` now uses a new client access authentication flow
|
With many thanks to Jay, `gam oauth create` now uses a new client access authentication flow
|
||||||
as required by Google for headless computers/cloud shells; this is required as of February 28, 2022.
|
as required by Google for headless computers/cloud shells; this is required as of February 28, 2022.
|
||||||
|
|||||||
@@ -10,6 +10,18 @@ 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
|
See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation
|
||||||
|
|
||||||
|
### 6.70.04
|
||||||
|
|
||||||
|
Added option `showvalidcolumn` to `gam print users` that can be used to identify whether
|
||||||
|
users are defined in the domain. Typically, you would read CSV file of email addresses
|
||||||
|
to verify as domain members.
|
||||||
|
|
||||||
|
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users#verify-domain-membership
|
||||||
|
|
||||||
|
Added option `addcsvdata <FieldName> <String>` to `gam print users` that adds
|
||||||
|
additional columns of data to the CSV file output. Typically, you would read CSV file of email addresses
|
||||||
|
to generate a CSV file of results and copy data from the input CSV to the outout CSV.
|
||||||
|
|
||||||
### 6.70.03
|
### 6.70.03
|
||||||
|
|
||||||
Renamed license product DuetAI to Gemini
|
Renamed license product DuetAI to Gemini
|
||||||
|
|||||||
@@ -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$ rm -f /Users/admin/GAMConfig/oauth2.txt
|
||||||
admin@server:/Users/admin/bin/gamadv-xtd3$ ./gam version
|
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
|
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
|
||||||
GAMADV-XTD3 6.70.03 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.70.04 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.2 64-bit final
|
Python 3.12.2 64-bit final
|
||||||
MacOS Sonoma 14.2.1 x86_64
|
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>del C:\GAMConfig\oauth2.txt
|
||||||
C:\GAMADV-XTD3>gam version
|
C:\GAMADV-XTD3>gam version
|
||||||
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
||||||
GAMADV-XTD3 6.70.03 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.70.04 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.2 64-bit final
|
Python 3.12.2 64-bit final
|
||||||
Windows-10-10.0.17134 AMD64
|
Windows-10-10.0.17134 AMD64
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
- [Print domain counts for users specified by `<UserTypeEntity>`](#print-domain-counts-for-users-specified-by-usertypeentity)
|
- [Print domain counts for users specified by `<UserTypeEntity>`](#print-domain-counts-for-users-specified-by-usertypeentity)
|
||||||
- [Print user list](#print-user-list)
|
- [Print user list](#print-user-list)
|
||||||
- [Display user counts](#display-user-counts)
|
- [Display user counts](#display-user-counts)
|
||||||
|
- [Verify domain membership]($verify-domain-membership)
|
||||||
|
|
||||||
## API documentation
|
## API documentation
|
||||||
* https://developers.google.com/admin-sdk/directory/reference/rest/v1/users
|
* https://developers.google.com/admin-sdk/directory/reference/rest/v1/users
|
||||||
@@ -981,14 +982,16 @@ gam print users [todrive <ToDriveAttribute>*]
|
|||||||
[limittoou <OrgUnitItem>] [deleted_only|only_deleted])
|
[limittoou <OrgUnitItem>] [deleted_only|only_deleted])
|
||||||
[orderby <UserOrderByFieldName> [ascending|descending]]
|
[orderby <UserOrderByFieldName> [ascending|descending]]
|
||||||
[groups|groupsincolumns]
|
[groups|groupsincolumns]
|
||||||
[license|licenses|licence|licences]
|
[license|licenses|licence|licences|licensebyuser|licensesbyuser|licencebyuser|licencesbyuser]
|
||||||
[onelicenseperrow|onelicenceperrow]
|
[onelicenseperrow|onelicenceperrow]
|
||||||
|
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||||
[emailpart|emailparts|username]
|
[emailpart|emailparts|username]
|
||||||
[userview] [allfields|basic|full|(<UserFieldName>*|fields <UserFieldNameList>)]
|
[userview] [allfields|basic|full|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||||
|
[showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||||
```
|
```
|
||||||
|
|
||||||
By default, users in all domains in the account are selected; these options allow selection of subsets of users:
|
By default, users in all domains in the account are selected; these options allow selection of subsets of users:
|
||||||
@@ -1008,11 +1011,13 @@ gam print users [todrive <ToDriveAttribute>*] select <UserTypeEntity>
|
|||||||
[onelicenseperrow|onelicenceperrow]
|
[onelicenseperrow|onelicenceperrow]
|
||||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||||
[emailpart|emailparts|username][schemas|custom all|<SchemaNameList>]
|
[emailpart|emailparts|username]
|
||||||
[userview] [allfields|basic|full|(<UserFieldName>*|fields <UserFieldNameList>)]
|
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||||
|
[showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||||
|
|
||||||
gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
||||||
[orderby <UserOrderByFieldName> [ascending|descending]]
|
[orderby <UserOrderByFieldName> [ascending|descending]]
|
||||||
[groups|groupsincolumns]
|
[groups|groupsincolumns]
|
||||||
@@ -1021,10 +1026,11 @@ gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
|||||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||||
[emailpart|emailparts|username]
|
[emailpart|emailparts|username]
|
||||||
[userview] [allfields|basic|full|(<UserFieldName>*|fields <UserFieldNameList>)]
|
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||||
|
[showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||||
```
|
```
|
||||||
|
|
||||||
By default, Gam gets no group membership information for each user. The `groups` and `groupsincolumns`
|
By default, Gam gets no group membership information for each user. The `groups` and `groupsincolumns`
|
||||||
@@ -1079,6 +1085,17 @@ In the output, primaryEmail is the always the first column; these options contro
|
|||||||
* `<UserFieldName>*|fields <UserFieldNameList>` - The columns appear in the order that the fields are specified.
|
* `<UserFieldName>*|fields <UserFieldNameList>` - The columns appear in the order that the fields are specified.
|
||||||
* `scalarsfirst [true]` - When columns are sorted by name, scalar fields appear before repeating fields.
|
* `scalarsfirst [true]` - When columns are sorted by name, scalar fields appear before repeating fields.
|
||||||
|
|
||||||
|
By default, if `<UserTypeEntity>` includes an email address the is not a user member of the domain,
|
||||||
|
an error message is generated.
|
||||||
|
```
|
||||||
|
User: testuserxxx@domain.com, Does not exist
|
||||||
|
```
|
||||||
|
|
||||||
|
Using option `showvalidcolumn`, a new column `Found` indicates domain membership; no errors are generated
|
||||||
|
|
||||||
|
Add additional columns of data from the command line to the output
|
||||||
|
* `addcsvdata <FieldName> <String>`
|
||||||
|
|
||||||
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format:
|
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format:
|
||||||
* `formatjson` - Display the fields in JSON format.
|
* `formatjson` - Display the fields in JSON format.
|
||||||
|
|
||||||
@@ -1249,3 +1266,34 @@ count=$(gam print users query "orgUnitPath='/Students/Middle School'" showitemco
|
|||||||
Windows PowerShell
|
Windows PowerShell
|
||||||
count = & gam print users query "orgUnitPath='/Students/Middle School'" showitemcountonly
|
count = & gam print users query "orgUnitPath='/Students/Middle School'" showitemcountonly
|
||||||
```
|
```
|
||||||
|
## Verify domain membership
|
||||||
|
You have a CSV file of email addresses and want to verify of the addresses are valid users in your domain.
|
||||||
|
```
|
||||||
|
# Users.csv
|
||||||
|
$ more Users.csv
|
||||||
|
primaryEmail,name
|
||||||
|
testuser1@domain.com,Test User 1
|
||||||
|
testuserxxx@domain.com,Test User XXX
|
||||||
|
testuser2@domain.com,Test User 2
|
||||||
|
|
||||||
|
# Without showvalidcolumn, non-domain users generate an error
|
||||||
|
$ gam redirect csv - multiprocess csv Users.csv gam user "~primaryEmail" print users fields primaryemail,id addcsvdata name "~name"
|
||||||
|
2024-02-23T11:29:00.407-08:00,0/3,Using 3 processes...
|
||||||
|
2024-02-23T11:29:00.410-08:00,0,Processing item 3/3
|
||||||
|
User: testuserxxx@domain.com, Does not exist
|
||||||
|
2024-02-23T11:29:06.511-08:00,0/3,Processing complete
|
||||||
|
primaryEmail,id,name
|
||||||
|
testuser1@domain.com,118080758787650801331,Test User 1
|
||||||
|
testuser2@domain.com,107344800159717682514,Test User 2
|
||||||
|
|
||||||
|
# Using showvalidcolumn, a new column `Valid` indicates domain membership; no errors are generated
|
||||||
|
$ gam redirect csv - multiprocess csv Users.csv gam user "~primaryEmail" print users fields primaryemail,id addcsvdata name "~name" showvalidcolumn
|
||||||
|
2024-02-23T11:29:22.287-08:00,0/3,Using 3 processes...
|
||||||
|
2024-02-23T11:29:22.292-08:00,0,Processing item 3/3
|
||||||
|
2024-02-23T11:29:23.366-08:00,0/3,Processing complete
|
||||||
|
primaryEmail,id,Valid,name
|
||||||
|
testuser1@domain.com,118080758787650801331,True,Test User 1
|
||||||
|
testuserxxx@domain.com,,False,Test User XXX
|
||||||
|
testuser2@domain.com,107344800159717682514,True,Test User 2
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
Print the current version of Gam with details
|
Print the current version of Gam with details
|
||||||
```
|
```
|
||||||
gam version
|
gam version
|
||||||
GAMADV-XTD3 6.70.03 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.70.04 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.2 64-bit final
|
Python 3.12.2 64-bit final
|
||||||
MacOS Sonoma 14.2.1 x86_64
|
MacOS Sonoma 14.2.1 x86_64
|
||||||
@@ -15,7 +15,7 @@ Time: 2023-06-02T21:10:00-07:00
|
|||||||
Print the current version of Gam with details and time offset information
|
Print the current version of Gam with details and time offset information
|
||||||
```
|
```
|
||||||
gam version timeoffset
|
gam version timeoffset
|
||||||
GAMADV-XTD3 6.70.03 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.70.04 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.2 64-bit final
|
Python 3.12.2 64-bit final
|
||||||
MacOS Sonoma 14.2.1 x86_64
|
MacOS Sonoma 14.2.1 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
|
Print the current version of Gam with extended details and SSL information
|
||||||
```
|
```
|
||||||
gam version extended
|
gam version extended
|
||||||
GAMADV-XTD3 6.70.03 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.70.04 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.2 64-bit final
|
Python 3.12.2 64-bit final
|
||||||
MacOS Sonoma 14.2.1 x86_64
|
MacOS Sonoma 14.2.1 x86_64
|
||||||
@@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64
|
|||||||
Path: /Users/Admin/bin/gamadv-xtd3
|
Path: /Users/Admin/bin/gamadv-xtd3
|
||||||
Version Check:
|
Version Check:
|
||||||
Current: 5.35.08
|
Current: 5.35.08
|
||||||
Latest: 6.70.03
|
Latest: 6.70.04
|
||||||
echo $?
|
echo $?
|
||||||
1
|
1
|
||||||
```
|
```
|
||||||
@@ -72,7 +72,7 @@ echo $?
|
|||||||
Print the current version number without details
|
Print the current version number without details
|
||||||
```
|
```
|
||||||
gam version simple
|
gam version simple
|
||||||
6.70.03
|
6.70.04
|
||||||
```
|
```
|
||||||
In Linux/MacOS you can do:
|
In Linux/MacOS you can do:
|
||||||
```
|
```
|
||||||
@@ -82,7 +82,7 @@ echo $VER
|
|||||||
Print the current version of Gam and address of this Wiki
|
Print the current version of Gam and address of this Wiki
|
||||||
```
|
```
|
||||||
gam help
|
gam help
|
||||||
GAM 6.70.03 - https://github.com/taers232c/GAMADV-XTD3
|
GAM 6.70.04 - https://github.com/taers232c/GAMADV-XTD3
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.2 64-bit final
|
Python 3.12.2 64-bit final
|
||||||
MacOS Sonoma 14.2.1 x86_64
|
MacOS Sonoma 14.2.1 x86_64
|
||||||
|
|||||||
@@ -5413,10 +5413,11 @@ gam print users [todrive <ToDriveAttribute>*]
|
|||||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||||
[emailpart|emailparts|username]
|
[emailpart|emailparts|username]
|
||||||
[userview] [basic|full|allfields | <UserFieldName>* | fields <UserFieldNameList>]
|
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||||
|
[showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||||
[showitemcountonly]
|
[showitemcountonly]
|
||||||
|
|
||||||
Print fields for specified users.
|
Print fields for specified users.
|
||||||
@@ -5429,10 +5430,11 @@ gam print users [todrive <ToDriveAttribute>*] select <UserTypeEntity>
|
|||||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||||
[emailpart|emailparts|username]
|
[emailpart|emailparts|username]
|
||||||
[userview] [basic|full|allfields | <UserFieldName>* | fields <UserFieldNameList>]
|
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||||
|
[showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||||
[showitemcountonly]
|
[showitemcountonly]
|
||||||
|
|
||||||
gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
||||||
@@ -5443,10 +5445,11 @@ gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
|||||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||||
[emailpart|emailparts|username]
|
[emailpart|emailparts|username]
|
||||||
[userview] [basic|full|allfields | <UserFieldName>* | fields <UserFieldNameList>]
|
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||||
|
[showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||||
[showitemcountonly]
|
[showitemcountonly]
|
||||||
|
|
||||||
The first column will always be primaryEmail; the remaining field names will be sorted if allfields, basic, full or sortheaders is specified;
|
The first column will always be primaryEmail; the remaining field names will be sorted if allfields, basic, full or sortheaders is specified;
|
||||||
|
|||||||
@@ -2,6 +2,18 @@
|
|||||||
|
|
||||||
Merged GAM-Team version
|
Merged GAM-Team version
|
||||||
|
|
||||||
|
6.70.04
|
||||||
|
|
||||||
|
Added option `showvalidcolumn` to `gam print users` that can be used to identify whether
|
||||||
|
users are defined in the domain. Typically, you would read CSV file of email addresses
|
||||||
|
to verify as domain members.
|
||||||
|
|
||||||
|
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users#verify-domain-membership
|
||||||
|
|
||||||
|
Added option `addcsvdata <FieldName> <String>` to `gam print users` that adds
|
||||||
|
additional columns of data to the CSV file output. Typically, you would read CSV file of email addresses
|
||||||
|
to generate a CSV file of results and copy data from the input CSV to the outout CSV.
|
||||||
|
|
||||||
6.70.03
|
6.70.03
|
||||||
|
|
||||||
Renamed license product DuetAI to Gemini
|
Renamed license product DuetAI to Gemini
|
||||||
|
|||||||
@@ -42672,6 +42672,7 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
|
|||||||
# [delimiter <Character>] [sortheaders] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
# [delimiter <Character>] [sortheaders] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||||
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||||
# [showitemcountonly]
|
# [showitemcountonly]
|
||||||
|
# [showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||||
#
|
#
|
||||||
# gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
# gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
||||||
# [groups|groupsincolumns]
|
# [groups|groupsincolumns]
|
||||||
@@ -42683,6 +42684,7 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
|
|||||||
# [delimiter <Character>] [sortheaders] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
# [delimiter <Character>] [sortheaders] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||||
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||||
# [showitemcountonly]
|
# [showitemcountonly]
|
||||||
|
# [showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||||
#
|
#
|
||||||
# gam print users [todrive <ToDriveAttribute>*]
|
# gam print users [todrive <ToDriveAttribute>*]
|
||||||
# ([domain <DomainName>] [(query <QueryUser>)|(queries <QueryUserList>)]
|
# ([domain <DomainName>] [(query <QueryUser>)|(queries <QueryUserList>)]
|
||||||
@@ -42690,6 +42692,7 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
|
|||||||
# [formatjson [quotechar <Character>]] [countonly]
|
# [formatjson [quotechar <Character>]] [countonly]
|
||||||
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||||
# [showitemcountonly]
|
# [showitemcountonly]
|
||||||
|
# [showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||||
#
|
#
|
||||||
# gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
# gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
||||||
# [formatjson [quotechar <Character>]] [countonly]
|
# [formatjson [quotechar <Character>]] [countonly]
|
||||||
@@ -42697,16 +42700,23 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
|
|||||||
# [showitemcountonly]
|
# [showitemcountonly]
|
||||||
def doPrintUsers(entityList=None):
|
def doPrintUsers(entityList=None):
|
||||||
def _writeUserEntity(userEntity):
|
def _writeUserEntity(userEntity):
|
||||||
|
if addCSVData:
|
||||||
|
userEntity.update(addCSVData)
|
||||||
row = flattenJSON(userEntity, skipObjects=USER_SKIP_OBJECTS, timeObjects=USER_TIME_OBJECTS)
|
row = flattenJSON(userEntity, skipObjects=USER_SKIP_OBJECTS, timeObjects=USER_TIME_OBJECTS)
|
||||||
if not FJQC.formatJSON:
|
if not FJQC.formatJSON:
|
||||||
csvPF.WriteRowTitles(row)
|
csvPF.WriteRowTitles(row)
|
||||||
elif csvPF.CheckRowTitles(row):
|
elif csvPF.CheckRowTitles(row):
|
||||||
csvPF.WriteRowNoFilter({'primaryEmail': userEntity['primaryEmail'],
|
row = {'primaryEmail': userEntity['primaryEmail']}
|
||||||
'JSON': json.dumps(cleanJSON(userEntity, skipObjects=USER_SKIP_OBJECTS, timeObjects=USER_TIME_OBJECTS),
|
if showValidColumn:
|
||||||
ensure_ascii=False, sort_keys=True)})
|
row[showValidColumn] = userEntity[showValidColumn]
|
||||||
|
row['JSON'] = json.dumps(cleanJSON(userEntity, skipObjects=USER_SKIP_OBJECTS, timeObjects=USER_TIME_OBJECTS),
|
||||||
|
ensure_ascii=False, sort_keys=True)
|
||||||
|
csvPF.WriteRowNoFilter(row)
|
||||||
|
|
||||||
def _printUser(userEntity, i, count):
|
def _printUser(userEntity, i, count):
|
||||||
if isSuspended is None or isSuspended == userEntity.get('suspended', isSuspended):
|
if isSuspended is None or isSuspended == userEntity.get('suspended', isSuspended):
|
||||||
|
if showValidColumn:
|
||||||
|
userEntity[showValidColumn] = True
|
||||||
userEmail = userEntity['primaryEmail']
|
userEmail = userEntity['primaryEmail']
|
||||||
if printOptions['emailParts']:
|
if printOptions['emailParts']:
|
||||||
if userEmail.find('@') != -1:
|
if userEmail.find('@') != -1:
|
||||||
@@ -42785,7 +42795,10 @@ def doPrintUsers(entityList=None):
|
|||||||
else:
|
else:
|
||||||
http_status, reason, message = checkGAPIError(exception)
|
http_status, reason, message = checkGAPIError(exception)
|
||||||
if reason in GAPI.USER_GET_THROW_REASONS:
|
if reason in GAPI.USER_GET_THROW_REASONS:
|
||||||
entityUnknownWarning(Ent.USER, ri[RI_ITEM], int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
if not showValidColumn:
|
||||||
|
entityUnknownWarning(Ent.USER, ri[RI_ITEM], int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||||
|
else:
|
||||||
|
_writeUserEntity({'primaryEmail': ri[RI_ITEM], showValidColumn: False})
|
||||||
elif (reason == GAPI.INVALID_INPUT) and customFieldMask:
|
elif (reason == GAPI.INVALID_INPUT) and customFieldMask:
|
||||||
entityActionFailedWarning([Ent.USER, ri[RI_ITEM]], invalidUserSchema(customFieldMask), int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
entityActionFailedWarning([Ent.USER, ri[RI_ITEM]], invalidUserSchema(customFieldMask), int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||||
elif reason not in GAPI.DEFAULT_RETRY_REASONS:
|
elif reason not in GAPI.DEFAULT_RETRY_REASONS:
|
||||||
@@ -42799,7 +42812,10 @@ def doPrintUsers(entityList=None):
|
|||||||
userKey=ri[RI_ITEM], projection=projection, customFieldMask=customFieldMask, viewType=viewType, fields=fields)
|
userKey=ri[RI_ITEM], projection=projection, customFieldMask=customFieldMask, viewType=viewType, fields=fields)
|
||||||
_printUser(user, int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
_printUser(user, int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||||
except (GAPI.userNotFound, GAPI.resourceNotFound):
|
except (GAPI.userNotFound, GAPI.resourceNotFound):
|
||||||
entityUnknownWarning(Ent.USER, ri[RI_ITEM], int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
if not showValidColumn:
|
||||||
|
entityUnknownWarning(Ent.USER, ri[RI_ITEM], int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||||
|
else:
|
||||||
|
_writeUserEntity({'primaryEmail': ri[RI_ITEM], showValidColumn: False})
|
||||||
except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden,
|
except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden,
|
||||||
GAPI.badRequest, GAPI.backendError, GAPI.systemError, GAPI.rateLimitExceeded) as e:
|
GAPI.badRequest, GAPI.backendError, GAPI.systemError, GAPI.rateLimitExceeded) as e:
|
||||||
entityActionFailedWarning([Ent.USER, ri[RI_ITEM]], str(e), int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
entityActionFailedWarning([Ent.USER, ri[RI_ITEM]], str(e), int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||||
@@ -42836,7 +42852,9 @@ def doPrintUsers(entityList=None):
|
|||||||
aliasMatchPattern = isSuspended = orgUnitPath = orgUnitPathLower = orderBy = sortOrder = None
|
aliasMatchPattern = isSuspended = orgUnitPath = orgUnitPathLower = orderBy = sortOrder = None
|
||||||
viewType = 'admin_view'
|
viewType = 'admin_view'
|
||||||
delimiter = GC.Values[GC.CSV_OUTPUT_FIELD_DELIMITER]
|
delimiter = GC.Values[GC.CSV_OUTPUT_FIELD_DELIMITER]
|
||||||
|
showValidColumn = ''
|
||||||
showItemCountOnly = False
|
showItemCountOnly = False
|
||||||
|
addCSVData = {}
|
||||||
while Cmd.ArgumentsRemaining():
|
while Cmd.ArgumentsRemaining():
|
||||||
myarg = getArgument()
|
myarg = getArgument()
|
||||||
if myarg == 'todrive':
|
if myarg == 'todrive':
|
||||||
@@ -42913,6 +42931,11 @@ def doPrintUsers(entityList=None):
|
|||||||
quotePlusPhoneNumbers = True
|
quotePlusPhoneNumbers = True
|
||||||
elif myarg == 'showitemcountonly':
|
elif myarg == 'showitemcountonly':
|
||||||
showItemCountOnly = True
|
showItemCountOnly = True
|
||||||
|
elif myarg == 'showvalidcolumn':
|
||||||
|
showValidColumn = 'Valid'
|
||||||
|
elif myarg == 'addcsvdata':
|
||||||
|
k = getString(Cmd.OB_STRING)
|
||||||
|
addCSVData[k] = getString(Cmd.OB_STRING, minLen=0)
|
||||||
else:
|
else:
|
||||||
FJQC.GetFormatJSONQuoteChar(myarg, False)
|
FJQC.GetFormatJSONQuoteChar(myarg, False)
|
||||||
_, _, entityList = getEntityArgument(entityList)
|
_, _, entityList = getEntityArgument(entityList)
|
||||||
@@ -42926,8 +42949,16 @@ def doPrintUsers(entityList=None):
|
|||||||
else:
|
else:
|
||||||
if FJQC.formatJSON:
|
if FJQC.formatJSON:
|
||||||
printOptions['sortHeaders'] = False
|
printOptions['sortHeaders'] = False
|
||||||
csvPF.SetJSONTitles(['primaryEmail', 'JSON'])
|
titles = ['primaryEmail']
|
||||||
|
if showValidColumn:
|
||||||
|
titles.append(showValidColumn)
|
||||||
|
titles.append('JSON')
|
||||||
|
csvPF.SetJSONTitles(titles)
|
||||||
else:
|
else:
|
||||||
|
if showValidColumn:
|
||||||
|
csvPF.AddTitles([showValidColumn])
|
||||||
|
if addCSVData:
|
||||||
|
csvPF.AddTitles(sorted(addCSVData.keys()))
|
||||||
if printOptions['getGroupFeed']:
|
if printOptions['getGroupFeed']:
|
||||||
if not printOptions['groupsInColumns']:
|
if not printOptions['groupsInColumns']:
|
||||||
csvPF.AddTitles(['GroupsCount', 'Groups'])
|
csvPF.AddTitles(['GroupsCount', 'Groups'])
|
||||||
@@ -43013,7 +43044,7 @@ def doPrintUsers(entityList=None):
|
|||||||
# If no individual fields were specified (allfields, basic, full) or individual fields other than primaryEmail were specified, look up each user
|
# 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:
|
if isSuspended is not None:
|
||||||
fieldsList.append('suspended')
|
fieldsList.append('suspended')
|
||||||
if projectionSet or len(set(fieldsList)) > 1:
|
if projectionSet or len(set(fieldsList)) > 1 or showValidColumn:
|
||||||
jcount = len(entityList)
|
jcount = len(entityList)
|
||||||
fields = getFieldsFromFieldsList(fieldsList)
|
fields = getFieldsFromFieldsList(fieldsList)
|
||||||
if GC.Values[GC.BATCH_SIZE] > 1 and jcount > 1:
|
if GC.Values[GC.BATCH_SIZE] > 1 and jcount > 1:
|
||||||
@@ -43045,7 +43076,10 @@ def doPrintUsers(entityList=None):
|
|||||||
userKey=userEmail, projection=projection, customFieldMask=customFieldMask, viewType=viewType, fields=fields)
|
userKey=userEmail, projection=projection, customFieldMask=customFieldMask, viewType=viewType, fields=fields)
|
||||||
_printUser(user, j, jcount)
|
_printUser(user, j, jcount)
|
||||||
except (GAPI.userNotFound, GAPI.resourceNotFound):
|
except (GAPI.userNotFound, GAPI.resourceNotFound):
|
||||||
entityUnknownWarning(Ent.USER, userEmail, j, jcount)
|
if not showValidColumn:
|
||||||
|
entityUnknownWarning(Ent.USER, userEmail, j, jcount)
|
||||||
|
else:
|
||||||
|
_writeUserEntity({'primaryEmail': userEmail, showValidColumn: False})
|
||||||
except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden,
|
except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden,
|
||||||
GAPI.badRequest, GAPI.backendError, GAPI.systemError, GAPI.rateLimitExceeded) as e:
|
GAPI.badRequest, GAPI.backendError, GAPI.systemError, GAPI.rateLimitExceeded) as e:
|
||||||
entityActionFailedWarning([Ent.USER, userEmail], str(e), j, jcount)
|
entityActionFailedWarning([Ent.USER, userEmail], str(e), j, jcount)
|
||||||
|
|||||||
Reference in New Issue
Block a user