mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-24 08:01:36 +00:00
Compare commits
6 Commits
20240717.2
...
20240721.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19304f95e8 | ||
|
|
5b49b8c957 | ||
|
|
f1e599d535 | ||
|
|
752b502399 | ||
|
|
8e3d562830 | ||
|
|
5b6c7a30d7 |
@@ -5,8 +5,10 @@
|
||||
- [Promote a domain to be primary](#promote-a-domain-to-be-primary)
|
||||
- [Delete a domain](#delete-a-domain)
|
||||
- [Display domains](#display-domains)
|
||||
- [Display domains count](#display-domains-count)
|
||||
- [Create and delete domain aliases](#create-and-delete-domain-aliases)
|
||||
- [Display domain aliases](#display-domain-aliases)
|
||||
- [Display domain aliases count](#display-domain-aliases-count)
|
||||
|
||||
## API documentation
|
||||
* https://developers.google.com/admin-sdk/directory/reference/rest/v1/domains
|
||||
@@ -30,15 +32,18 @@ gam delete domain <DomainName>
|
||||
```
|
||||
## Display domains
|
||||
```
|
||||
gam info domain [<DomainName>] [formatjson]
|
||||
gam show domains [formatjson]
|
||||
gam info domain [<DomainName>]
|
||||
[formatjson]
|
||||
gam show domains
|
||||
[formatjson]
|
||||
```
|
||||
For `info`, if `<DomainName>` is omitted, information about the primary domain will be displayed.
|
||||
|
||||
By default, Gam displays the information as an indented list of keys and values.
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
```
|
||||
gam print domains [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]]
|
||||
gam print domains [todrive <ToDriveAttribute>*]
|
||||
[formatjson [quotechar <Character>]]
|
||||
```
|
||||
By default, Gam displays the information as columns of fields.
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
@@ -49,6 +54,13 @@ 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 domains count
|
||||
Display the number of domains.
|
||||
```
|
||||
gam print|show domains
|
||||
showitemcountonly
|
||||
```
|
||||
|
||||
## Create and delete domain aliases
|
||||
```
|
||||
gam create domainalias|aliasdomain <DomainAlias> <DomainName>
|
||||
@@ -56,13 +68,16 @@ gam delete domainalias|aliasdomain <DomainAlias>
|
||||
```
|
||||
## Display domain aliases
|
||||
```
|
||||
gam info domainalias|aliasdomain <DomainAlias> [formatjson]
|
||||
gam show domainaliases|aliasdomains [formatjson] [formatjson [quotechar <Character>]]
|
||||
gam info domainalias|aliasdomain <DomainAlias>
|
||||
[formatjson]
|
||||
gam show domainaliases|aliasdomains
|
||||
[formatjson]
|
||||
```
|
||||
By default, Gam displays the information as an indented list of keys and values.
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
```
|
||||
gam print domainaliases|aliasdomains [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]]
|
||||
gam print domainaliases|aliasdomains [todrive <ToDriveAttribute>*]
|
||||
[formatjson [quotechar <Character>]]
|
||||
```
|
||||
By default, Gam displays the information as columns of fields.
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
@@ -73,3 +88,9 @@ 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 domain aliases count
|
||||
Display the number of domain aliases.
|
||||
```
|
||||
gam print|show domainaliases|aliasdomains
|
||||
showitemcountonly
|
||||
```
|
||||
|
||||
@@ -23,42 +23,42 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
|
||||
- `gamadv-xtd3-6.wx.yz-linux-x86_64-glibc2.19.tar.xz`
|
||||
- `gamadv-xtd3-6.wx.yz-linux-x86_64-legacy.tar.xz`
|
||||
- Download the archive, extract the contents into some directory.
|
||||
- Start a terminal session and cd to the install directory.
|
||||
- Start a terminal session.
|
||||
|
||||
* Executable Archive, Manual, Raspberry Pi/ChromeOS ARM devices
|
||||
- `gamadv-xtd3-6.wx.yz-linux-arm64-glibc2.31.tar.xz`
|
||||
- `gamadv-xtd3-6.wx.yz-linux-arm64-glibc2.27.tar.xz`
|
||||
- `gamadv-xtd3-6.wx.yz-linux-arm64-glibc2.23.tar.xz`
|
||||
- Download the archive, extract the contents into some directory.
|
||||
- Start a terminal session and cd to the install directory.
|
||||
- Start a terminal session.
|
||||
|
||||
* Executable Archive, Manual, Mac OS versions Big Sur, Monterey, Ventura - M1/M2
|
||||
- `gamadv-xtd3-6.wx.yz-macos-arm64.tar.xz`
|
||||
- Download the archive, extract the contents into some directory.
|
||||
- Start a terminal session and cd to the install directory.
|
||||
- Start a terminal session.
|
||||
|
||||
* Executable Archive, Manual, Mac OS, versions Big Sur, Monterey, Ventura - Intel
|
||||
- `gamadv-xtd3-6.wx.yz-macos-x86_64.tar.xz`
|
||||
- Download the archive, extract the contents into some directory.
|
||||
- Start a terminal session and cd to the install directory.
|
||||
- Start a terminal session.
|
||||
|
||||
* Executable Archive, Manual, Windows 64 bit
|
||||
- `gamadv-xtd3-6.wx.yz-windows-x86_64.zip`
|
||||
- Download the archive, extract the contents into some directory.
|
||||
- Start a Command Prompt/PowerShell session and cd to the install directory.
|
||||
- Start a Command Prompt/PowerShell session.
|
||||
|
||||
* Executable Installer, Manual, Windows 64 bit
|
||||
- `gamadv-xtd3-6.wx.yz-windows-x86_64.msi`
|
||||
- Download the installer and run it.
|
||||
- Start a Command Prompt/PowerShell session and cd to the install directory.
|
||||
- Start a Command Prompt/PowerShell session.
|
||||
|
||||
* Winget
|
||||
- `winget install taers232c.GAMADV-XTD3 --location C:\GAMADV-XTD3`
|
||||
- Specify an alternate location if desired
|
||||
- Start a Command Prompt/PowerShell session and cd to the install directory.
|
||||
- Start a Command Prompt/PowerShell session.
|
||||
|
||||
* Source, all platforms
|
||||
- `Source code(zip)`
|
||||
- `Source code(tar.gz)`
|
||||
- Download the archive, extract the contents into some directory.
|
||||
- Start a terminal/Command Prompt/PowerShell session and cd to the install directory.
|
||||
- Start a terminal/Command Prompt/PowerShell session.
|
||||
|
||||
@@ -32,6 +32,7 @@ ENTITY_IS_A_USER_ALIAS_RC = 21
|
||||
ENTITY_IS_A_GROUP_RC = 22
|
||||
ENTITY_IS_A_GROUP_ALIAS_RC = 23
|
||||
ENTITY_IS_AN_UNMANAGED_ACCOUNT_RC = 24
|
||||
ORGUNIT_NOT_EMPTY_RC = 25
|
||||
CHECK_USER_GROUPS_ERROR_RC = 29
|
||||
ORPHANS_COLLECTED_RC = 30
|
||||
# Warnings/Errors
|
||||
@@ -61,4 +62,14 @@ TARGET_DRIVE_SPACE_ERROR_RC = 74
|
||||
USER_REQUIRED_TO_CHANGE_PASSWORD_ERROR_RC = 75
|
||||
USER_SUSPENDED_ERROR_RC = 76
|
||||
NO_CSV_DATA_TO_UPLOAD_RC = 77
|
||||
NO_SA_ACCESS_CONTEXT_MANAGER_EDITOR_ROLE_RC = 78
|
||||
ACCESS_POLICY_ERROR_RC = 79
|
||||
YUBIKEY_CONNECTION_ERROR_RC = 80
|
||||
YUBIKEY_INVALID_KEY_TYPE_RC = 81
|
||||
YUBIKEY_INVALID_SLOT_RC = 82
|
||||
YUBIKEY_INVALID_PIN_RC = 83
|
||||
YUBIKEY_APDU_ERROR_RC = 84
|
||||
YUBIKEY_VALUE_ERROR_RC = 85
|
||||
YUBIKEY_MULTIPLE_CONNECTED_RC = 86
|
||||
YUBIKEY_NOT_FOUND_RC = 87
|
||||
```
|
||||
|
||||
@@ -8,7 +8,33 @@ Automatic update to the latest version on Linux/Mac OS/Google Cloud Shell/Raspbe
|
||||
By default, a folder, `gamadv-xtd3`, is created in the default or specified path and the files are downloaded into that folder.
|
||||
Add the `-s` option to the end of the above commands to suppress creating the `gamadv-xtd3` folder; the files are downloaded directly into the default or specified path.
|
||||
|
||||
See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation
|
||||
See [Downloads-Installs](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads-Installs) for Windows or other options, including manual installation
|
||||
|
||||
### 6.78.00
|
||||
|
||||
Added command to check if an OU contains items; this is useful when tryng to delete an OU
|
||||
as it must not contain any items in order to be deleted.
|
||||
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Organizational-Units#check-organizational-unit-for-contained-items
|
||||
|
||||
### 6.77.18
|
||||
|
||||
Added option `showitemcountonly` to `gam print domainaliases` that causes GAM to display the
|
||||
number of domain aliasess on stdout; no CSV file is written.
|
||||
|
||||
### 6.77.17
|
||||
|
||||
Added option `showitemcountonly` to `gam print domains` that causes GAM to display the
|
||||
number of domains on stdout; no CSV file is written.
|
||||
|
||||
### 6.77.16
|
||||
|
||||
Fixed bug in `gam <UserTypeEntity> print filelist` that caused a trap.
|
||||
|
||||
### 6.77.15
|
||||
|
||||
Updated `gam calendars <CalendarEntity> import event icaluid <iCalUID> json <JSONdata>` to handle API
|
||||
constraints on recurring events.
|
||||
|
||||
### 6.77.14
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ To run all commands properly, GAMADV-XTD3 requires three things:
|
||||
Use these steps if you have never used any version of GAM in your domain. They will create a GAM project
|
||||
and all necessary authentications.
|
||||
|
||||
* Download: [Downloads](Downloads)
|
||||
* Download: [Downloads-Installs](Downloads-Installs)
|
||||
* Configuration: [GAM Configuration](gam.cfg)
|
||||
* Install: [How to Install Advanced GAM](How-to-Install-Advanced-GAM)
|
||||
|
||||
@@ -47,7 +47,7 @@ and all necessary authentications.
|
||||
Use these steps if you have used any version of GAM in your domain. They will update your GAM project
|
||||
and all necessary authentications.
|
||||
|
||||
* Download: [Downloads](Downloads)
|
||||
* Download: [Downloads-Installs](Downloads-Installs)
|
||||
* Configuration: [GAM Configuration](gam.cfg)
|
||||
* Upgrade: [How to Upgrade from Standard GAM](How-to-Upgrade-from-Standard-GAM)
|
||||
|
||||
@@ -56,7 +56,7 @@ Use these steps if you already use GAMADV-X or GAMADV-XTD or GAMADV-XTD3. The up
|
||||
or authentications because new features have been included.
|
||||
|
||||
* Updates: [GAM Updates]
|
||||
* Download: [Downloads](Downloads)
|
||||
* Download: [Downloads-Installs](Downloads-Installs)
|
||||
|
||||
You can install multiple versions of GAM and GAMADV-XTD3 in different parallel directories.
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ substitute that value in the directions.
|
||||
|
||||
Make the directory:
|
||||
```
|
||||
mkdir -p /Users/admin/GAMconfig
|
||||
mkdir -p /Users/admin/GAMConfig
|
||||
```
|
||||
|
||||
Add the following line:
|
||||
@@ -42,14 +42,7 @@ to one of these files based on your shell:
|
||||
~/.profile
|
||||
```
|
||||
|
||||
You need to enable this setting in the environment. The easiest way is probably to close your terminal and open a new session. This will load the environment variables, including the one you just added. Test this by issuing this command:
|
||||
```
|
||||
echo $GAMCFGDIR
|
||||
```
|
||||
|
||||
This should print the name of the directory you used above.
|
||||
|
||||
Alternatively, without starting a new session, load the new variable in this session directly: issue the following command replacing `<Filename>` with the name of the file you edited:
|
||||
Issue the following command replacing `<Filename>` with the name of the file you edited:
|
||||
```
|
||||
source <Filename>
|
||||
```
|
||||
@@ -66,7 +59,11 @@ data in this folder and execute GAM commands from this folder. You should not us
|
||||
/Users/admin/bin/gamadv-xtd3 or /Users/admin/GAMConfig for this purpose.
|
||||
This example assumes that the GAM working directory will be /Users/admin/GAMWork; If you've chosen
|
||||
another directory, substitute that value in the directions.
|
||||
* Make the /Users/admin/GAMWork directory before proceeding.
|
||||
|
||||
Make the directory:
|
||||
```
|
||||
mkdir -p /Users/admin/GAMWork
|
||||
```
|
||||
|
||||
### Set an alias
|
||||
You should set an alias to point to /Users/admin/bin/gamadv-xtd3/gam so you can operate from the /Users/admin/GAMWork directory.
|
||||
@@ -103,9 +100,12 @@ Created: /Users/admin/GAMConfig
|
||||
Created: /Users/admin/GAMConfig/gamcache
|
||||
Config File: /Users/admin/GAMConfig/gam.cfg, Initialized
|
||||
Section: DEFAULT
|
||||
activity_max_results = 100
|
||||
...
|
||||
[long list of all config settings that should match the directories you specified]
|
||||
cache_dir = /Users/admin/GAMConfig/gamcache
|
||||
...
|
||||
config_dir = /Users/admin/GAMConfig
|
||||
...
|
||||
drive_dir = /Users/admin/GAMWork
|
||||
...
|
||||
|
||||
admin@server:/Users/admin$
|
||||
@@ -476,9 +476,12 @@ Default Language: en
|
||||
admin@server:/Users/admin$ gam config customer_id C01234567 domain domain.com timezone local save verify
|
||||
Config File: /Users/admin/GAMConfig/gam.cfg, Saved
|
||||
Section: DEFAULT
|
||||
activity_max_results = 100
|
||||
...
|
||||
[long list of all config settings that should match the data you specified]
|
||||
customer_id = C01234567
|
||||
...
|
||||
domain = domain.com
|
||||
...
|
||||
timezone = local
|
||||
...
|
||||
|
||||
admin@server:/Users/admin$
|
||||
@@ -542,9 +545,12 @@ Created: C:\GAMConfig
|
||||
Created: C:\GAMConfig\gamcache
|
||||
Config File: C:\GAMConfig\gam.cfg, Initialized
|
||||
Section: DEFAULT
|
||||
activity_max_results = 100
|
||||
...
|
||||
[long list of all config settings that should match the directories you specified]
|
||||
cache_dir = C:\GAMConfig\gamcache
|
||||
...
|
||||
config_dir = C:\GAMConfig
|
||||
...
|
||||
drive_dir = C:\GAMWork
|
||||
...
|
||||
|
||||
C:\>
|
||||
@@ -920,9 +926,12 @@ Default Language: en
|
||||
C:\>gam config customer_id C01234567 domain domain.com timezone local save verify
|
||||
Config File: C:\GAMConfig\gam.cfg, Saved
|
||||
Section: DEFAULT
|
||||
activity_max_results = 100
|
||||
...
|
||||
[long list of all config settings that should match the directories you specified]
|
||||
customer_id = C01234567
|
||||
...
|
||||
domain = domain.com
|
||||
...
|
||||
timezone = local
|
||||
...
|
||||
|
||||
C:\>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Updating GAMADV-XTD3
|
||||
Use these steps to update your version of GAMADV-XTD3.
|
||||
|
||||
- [Downloads](Downloads)
|
||||
- [Downloads-Installs](Downloads-Installs)
|
||||
- [Linux and MacOS and Google Cloud Shell](#linux-and-mac-os-and-google-cloud-shell)
|
||||
- [Windows](#windows)
|
||||
- [GAM Configuration](gam.cfg)
|
||||
@@ -13,7 +13,7 @@ Use these steps to update your version of GAMADV-XTD3.
|
||||
This example assumes that GAMADV-XTD3 has been installed in /Users/admin/bin/gamadv-xtd3.
|
||||
If you've installed GAMADV-XTD3 in another directory, substitute that value in the directions when downloading.
|
||||
|
||||
See: [Downloads](Downloads)
|
||||
See: [Downloads-Installs](Downloads-Installs)
|
||||
|
||||
In these examples, your Google Super admin is shown as admin@domain.com; replace with the
|
||||
actual email adddress.
|
||||
@@ -301,7 +301,7 @@ admin@server:/Users/admin/bin/gamadv-xtd3$
|
||||
This example assumes that GAMADV-XTD3 has been installed in C:\GAMADV-XTD3.
|
||||
If you've installed GAMADV-XTD3 in another directory, substitute that value in the directions when downloading.
|
||||
|
||||
See: [Downloads](Downloads)
|
||||
See: [Downloads-Installs](Downloads-Installs)
|
||||
|
||||
In these examples, your Google Super admin is shown as admin@domain.com; replace with the
|
||||
actual email adddress.
|
||||
|
||||
@@ -27,7 +27,7 @@ substitute that value in the directions.
|
||||
|
||||
Make the directory:
|
||||
```
|
||||
mkdir -p /Users/admin/GAMconfig
|
||||
mkdir -p /Users/admin/GAMConfig
|
||||
```
|
||||
|
||||
Add the following line:
|
||||
@@ -47,7 +47,10 @@ Issue the following command replacing `<Filename>` with the name of the file you
|
||||
source <Filename>
|
||||
```
|
||||
|
||||
* Make the /Users/admin/GAMConfig directory before proceeding.
|
||||
You need to make sure the GAM configuration directory actually exists. Test that like this:
|
||||
```
|
||||
ls -l $GAMCFGDIR
|
||||
```
|
||||
|
||||
### Set a working directory
|
||||
|
||||
@@ -56,10 +59,15 @@ data in this folder and execute GAM commands from this folder. You should not us
|
||||
/Users/admin/bin/gamadv-xtd3 or /Users/admin/GAMConfig for this purpose.
|
||||
This example assumes that the GAM working directory will be /Users/admin/GAMWork; If you've chosen
|
||||
another directory, substitute that value in the directions.
|
||||
* Make the /Users/admin/GAMWork directory before proceeding.
|
||||
|
||||
Make the directory:
|
||||
```
|
||||
mkdir -p /Users/admin/GAMWork
|
||||
```
|
||||
|
||||
### Set an alias
|
||||
You should set an alias to point to /Users/admin/bin/gamadv-xtd3/gam so you can operate from the /Users/admin/GAMWork directory.
|
||||
Aliases aren't available in scripts, so you may want to set a symlink instead, see below.
|
||||
|
||||
Add the following line:
|
||||
```
|
||||
@@ -91,6 +99,12 @@ Issue the following command replacing `<Filename>` with the name of the file you
|
||||
source <Filename>
|
||||
```
|
||||
|
||||
### Set a symlink
|
||||
Set a symlink in `/usr/local/bin` (or some other location on $PATH) to point to GAM.
|
||||
```
|
||||
ln -s "/Users/admin/bin/gamadv-xtd3/gam" /usr/local/bin/gam
|
||||
```
|
||||
|
||||
Set environment variable OLDGAMPATH to point to the existing Gam directory; /Users/admin/bin/gam will be used in this example.
|
||||
If your existing Gam is in another directory, substitute that value in the directions.
|
||||
```
|
||||
@@ -113,122 +127,13 @@ Copied: /Users/admin/bin/gam/oauth2.txt, To: /Users/admin/GAMConfig/oauth2.txt
|
||||
Copied: /Users/admin/bin/gam/client_secrets.json, To: /Users/admin/GAMConfig/client_secrets.json
|
||||
Config File: /Users/admin/GAMConfig/gam.cfg, Initialized
|
||||
Section: DEFAULT
|
||||
activity_max_results = 100
|
||||
admin_email = ''
|
||||
api_calls_rate_check = false
|
||||
api_calls_rate_limit = 100
|
||||
api_calls_tries_limit = 10
|
||||
auto_batch_min = 0
|
||||
bail_on_internal_error_tries = 2
|
||||
batch_size = 50
|
||||
cacerts_pem = ''
|
||||
...
|
||||
cache_dir = /Users/admin/GAMConfig/gamcache
|
||||
cache_discovery_only = true
|
||||
channel_customer_id = ''
|
||||
charset = utf-8
|
||||
classroom_max_results = 0
|
||||
client_secrets_json = client_secrets.json ; /Users/admin/GAMConfig/client_secrets.json
|
||||
clock_skew_in_seconds = 10
|
||||
cmdlog = ''
|
||||
cmdlog_max_backups = 5
|
||||
cmdlog_max_kilo_bytes = 1000
|
||||
...
|
||||
config_dir = /Users/admin/GAMConfig
|
||||
contact_max_results = 100
|
||||
csv_input_column_delimiter = ,
|
||||
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_line_terminator = lf
|
||||
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_subfield_delimiter = '.'
|
||||
csv_output_timestamp_column = ''
|
||||
csv_output_users_audit = false
|
||||
customer_id = my_customer
|
||||
debug_level = 0
|
||||
device_max_results = 200
|
||||
domain = ''
|
||||
...
|
||||
drive_dir = /Users/admin/GAMWork
|
||||
drive_max_results = 1000
|
||||
drive_v3_native_names = true
|
||||
email_batch_size = 50
|
||||
enable_dasa = false
|
||||
event_max_results = 250
|
||||
extra_args = ''
|
||||
inter_batch_wait = 0
|
||||
license_max_results = 100
|
||||
license_skus = ''
|
||||
member_max_results = 200
|
||||
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
|
||||
no_update_check = true
|
||||
no_verify_ssl = false
|
||||
num_tbatch_threads = 2
|
||||
num_threads = 5
|
||||
oauth2_txt = oauth2.txt ; /Users/admin/GAMConfig/oauth2.txt
|
||||
oauth2service_json = oauth2service.json ; /Users/admin/GAMConfig/oauth2service.json
|
||||
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
|
||||
reseller_id = ''
|
||||
retry_api_service_not_available = false
|
||||
section = ''
|
||||
show_api_calls_retry_data = false
|
||||
show_commands = false
|
||||
show_convert_cr_nl = false
|
||||
show_counts_min = 1
|
||||
show_gettings = true
|
||||
show_gettings_got_nl = false
|
||||
show_multiprocess_info = false
|
||||
smtp_fqdn = ''
|
||||
smtp_host = ''
|
||||
smtp_password = ''
|
||||
smtp_username = ''
|
||||
timezone = utc
|
||||
tls_max_version = ''
|
||||
tls_min_version = 'TLSv1_2'
|
||||
todrive_clearfilter = false
|
||||
todrive_clientaccess = false
|
||||
todrive_conversion = true
|
||||
todrive_localcopy = false
|
||||
todrive_locale = ''
|
||||
todrive_nobrowser = false
|
||||
todrive_noemail = 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_projectid_as_name = false
|
||||
user_max_results = 500
|
||||
user_service_account_access_only = false
|
||||
...
|
||||
|
||||
admin@server:/Users/admin$
|
||||
```
|
||||
@@ -346,7 +251,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
|
||||
GAMADV-XTD3 6.77.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.78.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.4 64-bit final
|
||||
MacOS Sonoma 14.5 x86_64
|
||||
@@ -1018,7 +923,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
|
||||
GAMADV-XTD3 6.77.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.78.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.4 64-bit final
|
||||
Windows-10-10.0.17134 AMD64
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
- [Print organizational units](#print-organizational-units)
|
||||
- [Display organizational unit counts](#display-organizational-unit-counts)
|
||||
- [Display indented organizational unit tree](#display-indented-organizational-unit-tree)
|
||||
- [Check organizational unit for contained items](#check-organizational-unit-for-contained-items)
|
||||
- [Special case handling for large number of organizational units](#special-case-handling-for-large-number-of-organizational-units)
|
||||
|
||||
## API documentation
|
||||
@@ -270,6 +271,44 @@ gam show orgtree [fromparent <OrgUnitItem>] [batchsuborgs [<Boolean>]]
|
||||
By default, Gam displays the organizational unit tree starting at /.
|
||||
* `fromparent <OrgUnitItem>` - Display the organizational unit tree starting at `<OrgUnitItem>`.
|
||||
|
||||
## Check organizational unit for contained items
|
||||
An organizational unit can be deleted only when it contains no items:
|
||||
* Chrome Browsers
|
||||
* ChromeOS Devices
|
||||
* Shared Drives
|
||||
* Sub Org Units
|
||||
* Users
|
||||
|
||||
This command counts those items and displays a CSV file with the item counts.
|
||||
* All counts are zero - A return code of 0 is returned and the `empty` column is `True`
|
||||
* Some count is greater than 0 - A return code of 25 is returned and the `empty` column is `False`
|
||||
|
||||
Only items directly within the OU are counted, items in sub-OUs are not counted.
|
||||
```
|
||||
<OrgUnitCheckName> ::=
|
||||
browsers|
|
||||
devices|
|
||||
shareddrives|
|
||||
subous|
|
||||
users
|
||||
<OrgUnitCheckNameList> ::= "<OrgUnitCheckName>(,<OrgUnitCheckName>)*"
|
||||
|
||||
gam check org|ou <OrgUnitItem> [todrive <ToDriveAttribute>*]
|
||||
[<OrgUnitCheckName>*|(fields <OrgUnitCheckNameList>)]
|
||||
[formatjson [quotechar <Character>]]
|
||||
```
|
||||
By default, GAM checks each of the five items; you can select specfic fields
|
||||
with `<OrgUnitCheckName>*` or `fields <OrgUnitCheckNameList>`.
|
||||
|
||||
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.
|
||||
|
||||
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
|
||||
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
|
||||
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.
|
||||
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
|
||||
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
|
||||
|
||||
## Special case handling for large number of organizational units
|
||||
|
||||
By default, the `print orgs` and `show orgtree` commands issue a single API call to get the
|
||||
|
||||
@@ -509,7 +509,7 @@ Find all the organizers and file organizers on the Golgafrincham shared drive in
|
||||
```
|
||||
|
||||
By default, all Shared Drives specified are displayed; use the following option to select a subset of those Shared Drives.
|
||||
* `<PermissionMatch>* [<PermissionMatchAction>] pmselect` - Use permission matching to select Shared Drives
|
||||
* `<PermissionMatch>* [<PermissionMatchAction>] pmselect` - Use permission matching to select Shared Drives; all ACLs are displayed for the selected Shared Drives
|
||||
|
||||
By default, all ACLS are displayed; use the following option to select a subset of the ACLS to display.
|
||||
* `<PermissionMatch>* [<PermissionMatchAction>]` - Use permission matching to display a subset of the ACLs for each Shared Drive; this only applies when `pmselect` is not specified
|
||||
@@ -548,7 +548,7 @@ By default, all Shared Drives are displayed; use the following options to select
|
||||
* `teamdriveadminquery|query <QueryTeamDrive>` - Use a query to select Shared Drives
|
||||
* `matchname <RegularExpression>` - Retrieve Shared Drives with names that match a pattern.
|
||||
* `orgunit|org|ou <OrgUnitPath>` - Only Shared Drives in the specified Org Unit are selected
|
||||
* `<PermissionMatch>* [<PermissionMatchAction>] pmselect` - Use permission matching to select Shared Drives
|
||||
* `<PermissionMatch>* [<PermissionMatchAction>] pmselect` - Use permission matching to select Shared Drives; all ACLs are displayed for the selected Shared Drives
|
||||
|
||||
By default, Shared Drives with no permissions are not displayed; use the `shownopermissionsdrives` to control whether
|
||||
Shared Drives with no permissions are displayed.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Print the current version of Gam with details
|
||||
```
|
||||
gam version
|
||||
GAMADV-XTD3 6.77.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.78.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.4 64-bit final
|
||||
MacOS Sonoma 14.5 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
|
||||
```
|
||||
gam version timeoffset
|
||||
GAMADV-XTD3 6.77.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.78.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.4 64-bit final
|
||||
MacOS Sonoma 14.5 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
|
||||
GAMADV-XTD3 6.77.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.78.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.4 64-bit final
|
||||
MacOS Sonoma 14.5 x86_64
|
||||
@@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64
|
||||
Path: /Users/Admin/bin/gamadv-xtd3
|
||||
Version Check:
|
||||
Current: 5.35.08
|
||||
Latest: 6.77.14
|
||||
Latest: 6.78.00
|
||||
echo $?
|
||||
1
|
||||
```
|
||||
@@ -72,7 +72,7 @@ echo $?
|
||||
Print the current version number without details
|
||||
```
|
||||
gam version simple
|
||||
6.77.14
|
||||
6.78.00
|
||||
```
|
||||
In Linux/MacOS you can do:
|
||||
```
|
||||
@@ -82,7 +82,7 @@ echo $VER
|
||||
Print the current version of Gam and address of this Wiki
|
||||
```
|
||||
gam help
|
||||
GAM 6.77.14 - https://github.com/taers232c/GAMADV-XTD3
|
||||
GAM 6.78.00 - https://github.com/taers232c/GAMADV-XTD3
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.4 64-bit final
|
||||
MacOS Sonoma 14.5 x86_64
|
||||
|
||||
@@ -3277,15 +3277,22 @@ gam info domain [<DomainName>]
|
||||
[formatjson]
|
||||
gam print domains [todrive <ToDriveAttribute>*]
|
||||
[formatjson [quotechar <Character>]]
|
||||
gam show domains [formatjson]
|
||||
[showitemcountonly]
|
||||
gam show domains
|
||||
[formatjson]
|
||||
[showitemcountonly]
|
||||
|
||||
gam create|add domainalias|aliasdomain <DomainAlias> <DomainName>
|
||||
gam delete domainalias|aliasdomain <DomainAlias>
|
||||
|
||||
gam info domainalias|aliasdomain <DomainAlias> [formatjson]
|
||||
gam info domainalias|aliasdomain <DomainAlias>
|
||||
[formatjson]
|
||||
gam print domainaliases|aliasdomains [todrive <ToDriveAttribute>*]
|
||||
[formatjson [quotechar <Character>]]
|
||||
gam show domainaliases|aliasdomains [formatjson]
|
||||
[showitemcountonly]
|
||||
gam show domainaliases|aliasdomains
|
||||
[formatjson]
|
||||
[showitemcountonly]
|
||||
|
||||
# Domain - Contacts and Global Address List
|
||||
|
||||
@@ -4210,6 +4217,18 @@ gam print orgs|ous [todrive <ToDriveAttribute>*]
|
||||
[showitemcountonly]
|
||||
gam show orgtree [fromparent <OrgUnitItem>] [batchsuborgs [<Boolean>]]
|
||||
|
||||
<OrgUnitCheckName> ::=
|
||||
browsers|
|
||||
devices|
|
||||
shareddrives|
|
||||
subous|
|
||||
users
|
||||
<OrgUnitCheckNameList> ::= "<OrgUnitCheckName>(,<OrgUnitCheckName>)*"
|
||||
|
||||
gam check org|ou <OrgUnitItem> [todrive <ToDriveAttribute>*]
|
||||
[<OrgUnitCheckName>*|(fields <OrgUnitCheckNameList>)]
|
||||
[formatjson [quotechar <Character>]]
|
||||
|
||||
# Printers
|
||||
|
||||
<PrinterAttribute> ::=
|
||||
|
||||
@@ -2,6 +2,32 @@
|
||||
|
||||
Merged GAM-Team version
|
||||
|
||||
6.78.00
|
||||
|
||||
Added command to check if an OU contains items; this is useful when tryng to delete an OU
|
||||
as it must not contain any items in order to be deleted.
|
||||
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Organizational-Units#check-organizational-unit-for-contained-items
|
||||
|
||||
6.77.18
|
||||
|
||||
Added option `showitemcountonly` to `gam print domainaliases` that causes GAM to display the
|
||||
number of domain aliasess on stdout; no CSV file is written.
|
||||
|
||||
6.77.17
|
||||
|
||||
Added option `showitemcountonly` to `gam print domains` that causes GAM to display the
|
||||
number of domains on stdout; no CSV file is written.
|
||||
|
||||
6.77.16
|
||||
|
||||
Fixed bug in `gam <UserTypeEntity> print filelist` that caused a trap.
|
||||
|
||||
6.77.15
|
||||
|
||||
Updated `gam calendars <CalendarEntity> import event icaluid <iCalUID> json <JSONdata>` to handle API
|
||||
constraints on recurring events.
|
||||
|
||||
6.77.14
|
||||
|
||||
Fixed bug in `gam calendars <CalendarEntity> import event icaluid <iCalUID> json <JSONdata>` that caused an error.
|
||||
|
||||
@@ -332,6 +332,7 @@ ENTITY_IS_A_USER_ALIAS_RC = 21
|
||||
ENTITY_IS_A_GROUP_RC = 22
|
||||
ENTITY_IS_A_GROUP_ALIAS_RC = 23
|
||||
ENTITY_IS_AN_UNMANAGED_ACCOUNT_RC = 24
|
||||
ORGUNIT_NOT_EMPTY_RC = 25
|
||||
CHECK_USER_GROUPS_ERROR_RC = 29
|
||||
ORPHANS_COLLECTED_RC = 30
|
||||
# Warnings/Errors
|
||||
@@ -8890,14 +8891,6 @@ def getTodriveOnly(csvPF):
|
||||
else:
|
||||
unknownArgumentExit()
|
||||
|
||||
def getTodriveFJQCOnly(csvPF, FJQC, addTitle=False, noExit=False):
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
csvPF.GetTodriveParameters()
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, addTitle, noExit)
|
||||
|
||||
DEFAULT_SKIP_OBJECTS = {'kind', 'etag', 'etags', '@type'}
|
||||
|
||||
# Clean a JSON object
|
||||
@@ -15763,18 +15756,33 @@ def _printDomain(domain, csvPF):
|
||||
|
||||
DOMAIN_ALIAS_SORT_TITLES = ['domainAliasName', 'parentDomainName', 'creationTime', 'verified']
|
||||
|
||||
# gam print domainaliases [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]]
|
||||
# gam show domainaliases [formatjson]
|
||||
# gam print domainaliases [todrive <ToDriveAttribute>*]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
# [showitemcountonly]
|
||||
# gam show domainaliases
|
||||
# [formatjson]
|
||||
# [showitemcountonly]
|
||||
def doPrintShowDomainAliases():
|
||||
cd = buildGAPIObject(API.DIRECTORY)
|
||||
csvPF = CSVPrintFile(['domainAliasName'], DOMAIN_ALIAS_SORT_TITLES) if Act.csvFormat() else None
|
||||
FJQC = FormatJSONQuoteChar(csvPF)
|
||||
getTodriveFJQCOnly(csvPF, FJQC, True)
|
||||
showItemCountOnly = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
csvPF.GetTodriveParameters()
|
||||
elif myarg == 'showitemcountonly':
|
||||
showItemCountOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||
try:
|
||||
domainAliases = callGAPIitems(cd.domainAliases(), 'list', 'domainAliases',
|
||||
throwReasons=[GAPI.BAD_REQUEST, GAPI.NOT_FOUND, GAPI.FORBIDDEN],
|
||||
customer=GC.Values[GC.CUSTOMER_ID])
|
||||
count = len(domainAliases)
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{count}\n')
|
||||
return
|
||||
i = 0
|
||||
for domainAlias in domainAliases:
|
||||
i += 1
|
||||
@@ -16090,18 +16098,33 @@ def doInfoDomain():
|
||||
|
||||
DOMAIN_SORT_TITLES = ['domainName', 'parentDomainName', 'creationTime', 'type', 'verified']
|
||||
|
||||
# gam print domains [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]]
|
||||
# gam show domains [formatjson]
|
||||
# gam print domains [todrive <ToDriveAttribute>*]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
# [showitemcountonly]
|
||||
# gam show domains
|
||||
# [formatjson]
|
||||
# [showitemcountonly]
|
||||
def doPrintShowDomains():
|
||||
cd = buildGAPIObject(API.DIRECTORY)
|
||||
csvPF = CSVPrintFile(['domainName'], DOMAIN_SORT_TITLES) if Act.csvFormat() else None
|
||||
FJQC = FormatJSONQuoteChar(csvPF)
|
||||
getTodriveFJQCOnly(csvPF, FJQC, True)
|
||||
showItemCountOnly = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
csvPF.GetTodriveParameters()
|
||||
elif myarg == 'showitemcountonly':
|
||||
showItemCountOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||
try:
|
||||
domains = callGAPIitems(cd.domains(), 'list', 'domains',
|
||||
throwReasons=[GAPI.BAD_REQUEST, GAPI.NOT_FOUND, GAPI.FORBIDDEN],
|
||||
customer=GC.Values[GC.CUSTOMER_ID])
|
||||
count = len(domains)
|
||||
if showItemCountOnly:
|
||||
writeStdout(f'{count}\n')
|
||||
return
|
||||
i = 0
|
||||
for domain in domains:
|
||||
i += 1
|
||||
@@ -17462,7 +17485,11 @@ def _getOrgUnits(cd, orgUnitPath, fieldsList, listType, showParent, batchSubOrgs
|
||||
else:
|
||||
fields = ','.join(set(fieldsList))
|
||||
listfields = f'organizationUnits({fields})'
|
||||
printGettingAllAccountEntities(Ent.ORGANIZATIONAL_UNIT)
|
||||
if listType == 'all' and orgUnitPath == '/':
|
||||
printGettingAllAccountEntities(Ent.ORGANIZATIONAL_UNIT)
|
||||
else:
|
||||
printGettingAllEntityItemsForWhom(Ent.CHILD_ORGANIZATIONAL_UNIT, orgUnitPath,
|
||||
qualifier=' (Direct Children)' if listType == 'children' else '', entityType=Ent.ORGANIZATIONAL_UNIT)
|
||||
if listType == 'children':
|
||||
batchSubOrgs = False
|
||||
try:
|
||||
@@ -17500,7 +17527,10 @@ def _getOrgUnits(cd, orgUnitPath, fieldsList, listType, showParent, batchSubOrgs
|
||||
except (GAPI.invalidOrgunit, GAPI.orgunitNotFound, GAPI.backendError,
|
||||
GAPI.badRequest, GAPI.invalidCustomerId, GAPI.loginRequired):
|
||||
pass
|
||||
printGotAccountEntities(len(orgUnits))
|
||||
if listType == 'all' and orgUnitPath == '/':
|
||||
printGotAccountEntities(len(orgUnits))
|
||||
else:
|
||||
printGotEntityItemsForWhom(len(orgUnits))
|
||||
if childSelector is not None:
|
||||
for orgUnit in orgUnits:
|
||||
orgUnit[ORG_UNIT_SELECTOR_FIELD] = childSelector if orgUnit['orgUnitPath'] != orgUnitPath else parentSelector
|
||||
@@ -17733,6 +17763,157 @@ def doShowOrgTree():
|
||||
for org in sorted(orgTree):
|
||||
printOrgUnit(org, orgTree)
|
||||
|
||||
ORG_ITEMS_FIELD_MAP = {
|
||||
'browsers': 'browsers',
|
||||
'devices': 'devices',
|
||||
'shareddrives': 'sharedDrives',
|
||||
'subous': 'subOus',
|
||||
'users': 'users',
|
||||
}
|
||||
|
||||
# gam check org|ou <OrgUnitItem> [todrive <ToDriveAttribute>*]
|
||||
# [<OrgUnitCheckName>*|(fields <OrgUnitCheckNameList>)]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
def doCheckOrgUnit():
|
||||
cd = buildGAPIObject(API.DIRECTORY)
|
||||
csvPF = CSVPrintFile(['orgUnitPath', 'orgUnitId', 'empty'])
|
||||
FJQC = FormatJSONQuoteChar(csvPF)
|
||||
orgUnitPath = None
|
||||
fieldsList = []
|
||||
titlesList = []
|
||||
status, orgUnitPath, orgUnitId = checkOrgUnitPathExists(cd, getOrgUnitItem())
|
||||
orgUnitPathLower = orgUnitPath.lower()
|
||||
if not status:
|
||||
entityDoesNotExistExit(Ent.ORGANIZATIONAL_UNIT, orgUnitPath)
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
csvPF.GetTodriveParameters()
|
||||
elif myarg in ORG_ITEMS_FIELD_MAP:
|
||||
fieldsList.append(myarg)
|
||||
elif myarg == 'fields':
|
||||
for field in _getFieldsList():
|
||||
if field in ORG_ITEMS_FIELD_MAP:
|
||||
fieldsList.append(field)
|
||||
else:
|
||||
invalidChoiceExit(field, list(ORG_ITEMS_FIELD_MAP), True)
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||
if orgUnitPath is None:
|
||||
missingArgumentExit('orgunit <OrgUnitItem>')
|
||||
if not fieldsList:
|
||||
fieldsList = ORG_ITEMS_FIELD_MAP.keys()
|
||||
orgUnitItemCounts = {}
|
||||
for field in sorted(fieldsList):
|
||||
title = ORG_ITEMS_FIELD_MAP[field]
|
||||
orgUnitItemCounts[title] = 0
|
||||
if not FJQC.formatJSON:
|
||||
titlesList.append(title)
|
||||
if 'browsers' in fieldsList:
|
||||
cbcm = buildGAPIObject(API.CBCM)
|
||||
customerId = _getCustomerIdNoC()
|
||||
printGettingAllEntityItemsForWhom(Ent.CHROME_BROWSER, orgUnitPath, entityType=Ent.ORGANIZATIONAL_UNIT)
|
||||
pageMessage = getPageMessage()
|
||||
try:
|
||||
feed = yieldGAPIpages(cbcm.chromebrowsers(), 'list', 'browsers',
|
||||
pageMessage=pageMessage, messageAttribute='deviceId',
|
||||
throwReasons=[GAPI.INVALID_INPUT, GAPI.BAD_REQUEST, GAPI.INVALID_ORGUNIT, GAPI.FORBIDDEN],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
customer=customerId, orgUnitPath=orgUnitPath, projection='BASIC',
|
||||
fields='nextPageToken,browsers(deviceId)')
|
||||
for browsers in feed:
|
||||
orgUnitItemCounts['browsers'] += len(browsers)
|
||||
except (GAPI.invalidInput, GAPI.forbidden) as e:
|
||||
entityActionFailedWarning([Ent.CHROME_BROWSER, None], str(e))
|
||||
except GAPI.invalidOrgunit as e:
|
||||
entityActionFailedExit([Ent.CHROME_BROWSER, None], str(e))
|
||||
except (GAPI.badRequest, GAPI.resourceNotFound):
|
||||
accessErrorExit(None)
|
||||
if 'devices' in fieldsList:
|
||||
printGettingAllEntityItemsForWhom(Ent.CROS_DEVICE, orgUnitPath, entityType=Ent.ORGANIZATIONAL_UNIT)
|
||||
pageMessage = getPageMessageForWhom()
|
||||
pageToken = None
|
||||
totalItems = 0
|
||||
tokenRetries = 0
|
||||
while True:
|
||||
try:
|
||||
feed = callGAPI(cd.chromeosdevices(), 'list',
|
||||
throwReasons=[GAPI.INVALID_INPUT, GAPI.INVALID_ORGUNIT,
|
||||
GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.FORBIDDEN],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
pageToken=pageToken, customerId=GC.Values[GC.CUSTOMER_ID],
|
||||
orgUnitPath=orgUnitPath, fields='nextPageToken,chromeosdevices(deviceId)', maxResults=GC.Values[GC.DEVICE_MAX_RESULTS])
|
||||
tokenRetries = 0
|
||||
pageToken, totalItems = _processGAPIpagesResult(feed, 'chromeosdevices', None, totalItems, pageMessage, None, Ent.CROS_DEVICE)
|
||||
if feed:
|
||||
orgUnitItemCounts['devices'] += len(feed.get('chromeosdevices', []))
|
||||
del feed
|
||||
if not pageToken:
|
||||
_finalizeGAPIpagesResult(pageMessage)
|
||||
printGotAccountEntities(totalItems)
|
||||
break
|
||||
except GAPI.invalidInput as e:
|
||||
message = str(e)
|
||||
# Invalid Input: xyz - Check for invalid pageToken!!
|
||||
# 0123456789012345
|
||||
if message[15:] == pageToken:
|
||||
tokenRetries += 1
|
||||
if tokenRetries <= 2:
|
||||
writeStderr(f'{WARNING_PREFIX}{Msg.LIST_CHROMEOS_INVALID_INPUT_PAGE_TOKEN_RETRY}')
|
||||
time.sleep(tokenRetries*5)
|
||||
continue
|
||||
entityActionFailedWarning([Ent.CROS_DEVICE, None], message)
|
||||
break
|
||||
entityActionFailedWarning([Ent.CROS_DEVICE, None], message)
|
||||
break
|
||||
except GAPI.invalidOrgunit as e:
|
||||
entityActionFailedExit([Ent.CROS_DEVICE, None], str(e))
|
||||
except (GAPI.badRequest, GAPI.resourceNotFound, GAPI.forbidden):
|
||||
accessErrorExit(cd)
|
||||
if 'shareddrives' in fieldsList:
|
||||
ci = buildGAPIObject(API.CLOUDIDENTITY_ORGUNITS_BETA)
|
||||
printGettingAllEntityItemsForWhom(Ent.SHAREDDRIVE, orgUnitPath, entityType=Ent.ORGANIZATIONAL_UNIT)
|
||||
sds = callGAPIpages(ci.orgUnits().memberships(), 'list', 'orgMemberships',
|
||||
pageMessage=getPageMessageForWhom(),
|
||||
parent=f'orgUnits/{orgUnitId[3:]}',
|
||||
customer=_getCustomersCustomerIdWithC(),
|
||||
filter="type == 'shared_drive'")
|
||||
orgUnitItemCounts['sharedDrives'] = len(sds)
|
||||
if 'subous' in fieldsList:
|
||||
orgUnitItemCounts['subOus'] = len(_getOrgUnits(cd, orgUnitPath, ['orgUnitPath'], 'children', False, False, None, None))
|
||||
if 'users' in fieldsList:
|
||||
printGettingAllEntityItemsForWhom(Ent.USER, orgUnitPath, entityType=Ent.ORGANIZATIONAL_UNIT)
|
||||
pageMessage = getPageMessageForWhom()
|
||||
try:
|
||||
feed = yieldGAPIpages(cd.users(), 'list', 'users',
|
||||
pageMessage=pageMessage,
|
||||
throwReasons=[GAPI.INVALID_ORGUNIT, GAPI.ORGUNIT_NOT_FOUND,
|
||||
GAPI.INVALID_INPUT, GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.FORBIDDEN],
|
||||
customer=GC.Values[GC.CUSTOMER_ID], query=orgUnitPathQuery(orgUnitPath, None),
|
||||
fields='nextPageToken,users(orgUnitPath)', maxResults=GC.Values[GC.USER_MAX_RESULTS])
|
||||
for users in feed:
|
||||
for user in users:
|
||||
if orgUnitPathLower == user.get('orgUnitPath', '').lower():
|
||||
orgUnitItemCounts['users'] += 1
|
||||
except (GAPI.invalidOrgunit, GAPI.orgunitNotFound, GAPI.invalidInput, GAPI.badRequest, GAPI.backendError,
|
||||
GAPI.invalidCustomerId, GAPI.loginRequired, GAPI.resourceNotFound, GAPI.forbidden):
|
||||
checkEntityDNEorAccessErrorExit(cd, Ent.ORGANIZATIONAL_UNIT, orgUnitPath)
|
||||
empty = True
|
||||
for count in orgUnitItemCounts.values():
|
||||
if count > 0:
|
||||
empty = False
|
||||
break
|
||||
baseRow = {'orgUnitPath': orgUnitPath, 'orgUnitId': orgUnitId, 'empty': empty}
|
||||
row = flattenJSON(orgUnitItemCounts, baseRow.copy())
|
||||
if not FJQC.formatJSON:
|
||||
csvPF.WriteRowTitles(row)
|
||||
elif csvPF.CheckRowTitles(row):
|
||||
baseRow['JSON'] = json.dumps(cleanJSON(orgUnitItemCounts), ensure_ascii=False, sort_keys=True)
|
||||
csvPF.WriteRowNoFilter(baseRow)
|
||||
csvPF.writeCSVfile(f'OrgUnit {orgUnitPath} Item Counts')
|
||||
if not empty and GM.Globals[GM.SYSEXITRC] == 0:
|
||||
setSysExitRC(ORGUNIT_NOT_EMPTY_RC)
|
||||
|
||||
ALIAS_TARGET_TYPES = ['user', 'group', 'target']
|
||||
|
||||
# gam create aliases|nicknames <EmailAddressEntity> user|group|target <UniqueID>|<EmailAddress>
|
||||
@@ -25035,10 +25216,10 @@ def doPrintShowBrowsers():
|
||||
else:
|
||||
entityActionFailedWarning([Ent.CHROME_BROWSER, None], str(e))
|
||||
return
|
||||
except GAPI.invalidOrgunit as e:
|
||||
except (GAPI.invalidOrgunit, GAPI.forbidden) as e:
|
||||
entityActionFailedWarning([Ent.CHROME_BROWSER, None], str(e))
|
||||
return
|
||||
except (GAPI.badRequest, GAPI.resourceNotFound, GAPI.forbidden):
|
||||
except (GAPI.badRequest, GAPI.resourceNotFound):
|
||||
accessErrorExit(None)
|
||||
else:
|
||||
sortRows = True
|
||||
@@ -36918,9 +37099,13 @@ def _getCalendarEventAttribute(myarg, body, parameters, function):
|
||||
parameters['attendees'].append(addAttendee)
|
||||
elif myarg == 'json':
|
||||
jsonData = getJSON(EVENT_JSON_CLEAR_FIELDS)
|
||||
if function in {'insert', 'import'}:
|
||||
if function == 'insert':
|
||||
body.update(jsonData)
|
||||
clearJSONfields(body, EVENT_JSON_INSERT_CLEAR_FIELDS)
|
||||
elif function == 'import':
|
||||
if 'id' in jsonData:
|
||||
jsonData['iCalUID'] = jsonData.pop('id')
|
||||
body.update(jsonData)
|
||||
elif function == 'update':
|
||||
if 'event' in jsonData and 'attendees' in jsonData['event']:
|
||||
parameters['attendees'].extend(jsonData['event'].pop('attendees'))
|
||||
@@ -43787,18 +43972,21 @@ def doPrintUsers(entityList=None):
|
||||
projection=schemaParms['projection'], customFieldMask=schemaParms['customFieldMask'],
|
||||
maxResults=maxResults, **kwargs)
|
||||
for users in feed:
|
||||
if showItemCountOnly:
|
||||
itemCount += len(users)
|
||||
continue
|
||||
if orgUnitPath is None:
|
||||
if not printOptions['countOnly']:
|
||||
if showItemCountOnly:
|
||||
itemCount += len(users)
|
||||
elif not printOptions['countOnly']:
|
||||
for user in users:
|
||||
_printUser(user, 0, 0)
|
||||
else:
|
||||
for user in users:
|
||||
_updateDomainCounts(user['primaryEmail'])
|
||||
else:
|
||||
if not printOptions['countOnly']:
|
||||
if showItemCountOnly:
|
||||
for user in users:
|
||||
if orgUnitPathLower == user.get('orgUnitPath', '').lower():
|
||||
itemCount += 1
|
||||
elif not printOptions['countOnly']:
|
||||
for user in users:
|
||||
if orgUnitPathLower == user.get('orgUnitPath', '').lower():
|
||||
_printUser(user, 0, 0)
|
||||
@@ -54409,7 +54597,7 @@ def printFileList(users):
|
||||
simpleLists = ['permissionIds', 'spaces']
|
||||
skipObjects = set()
|
||||
fileIdEntity = {}
|
||||
selectSubQuery = ''
|
||||
getSharedDriveACLsCountMsg = selectSubQuery = ''
|
||||
delimiter = GC.Values[GC.CSV_OUTPUT_FIELD_DELIMITER]
|
||||
DLP = DriveListParameters({'allowChoose': True, 'allowCorpora': True, 'allowQuery': True, 'mimeTypeInQuery': False})
|
||||
DFF = DriveFileFields()
|
||||
@@ -63834,7 +64022,9 @@ def doPrintShowOrgunitSharedDrives():
|
||||
if csvPF and FJQC.formatJSON:
|
||||
csvPF.SetJSONTitles(['name', 'JSON'])
|
||||
_, orgUnitId = getOrgUnitId(None, orgUnitPath)
|
||||
printGettingAllEntityItemsForWhom(Ent.SHAREDDRIVE, orgUnitPath, entityType=Ent.ORGANIZATIONAL_UNIT)
|
||||
sds = callGAPIpages(ci.orgUnits().memberships(), 'list', 'orgMemberships',
|
||||
pageMessage=getPageMessageForWhom(),
|
||||
parent=f'orgUnits/{orgUnitId[3:]}',
|
||||
customer=_getCustomersCustomerIdWithC(),
|
||||
filter="type == 'shared_drive'")
|
||||
@@ -73647,6 +73837,7 @@ MAIN_COMMANDS_WITH_OBJECTS = {
|
||||
{Cmd.ARG_SVCACCT: doCheckUpdateSvcAcct,
|
||||
Cmd.ARG_USERINVITATION: doCheckCIUserInvitations,
|
||||
Cmd.ARG_ISINVITABLE: doCheckCIUserInvitations,
|
||||
Cmd.ARG_ORG: doCheckOrgUnit,
|
||||
}
|
||||
),
|
||||
'clear':
|
||||
|
||||
@@ -94,6 +94,7 @@ class GamEntity():
|
||||
CHAT_MESSAGE_ID = 'chmi'
|
||||
CHAT_SPACE = 'chsp'
|
||||
CHAT_THREAD = 'chth'
|
||||
CHILD_ORGANIZATIONAL_UNIT = 'corg'
|
||||
CHROME_APP = 'capp'
|
||||
CHROME_APP_DEVICE = 'capd'
|
||||
CHROME_BROWSER = 'chbr'
|
||||
@@ -435,6 +436,7 @@ class GamEntity():
|
||||
CHAT_MEMBER_USER: ['Chat User Members', 'Chat User Member'],
|
||||
CHAT_SPACE: ['Chat Spaces', 'Chat Space'],
|
||||
CHAT_THREAD: ['Chat Threads', 'Chat Thread'],
|
||||
CHILD_ORGANIZATIONAL_UNIT: ['Child Organizational Units', 'Child Organizational Unit'],
|
||||
CHROME_APP: ['Chrome Applications', 'Chrome Application'],
|
||||
CHROME_APP_DEVICE: ['Chrome Application Devices', 'Chrome Application Device'],
|
||||
CHROME_BROWSER: ['Chrome Browsers', 'Chrome Browser'],
|
||||
|
||||
Reference in New Issue
Block a user