Updated `gam report <ActivityApplicationName>` to display `id:<actor.profileId>` in the `emailAddress` column
when `actor.email` is empty. This typically occurs when the actor is not in your workspace.
Updated `gam <UserTypeEntity> copy drivefile` to ignore ACLs referencing deleted user/groups.
We currently only have 13 JID accounts available for testing but after Linux arm64 changes needed 14 runners.
I'm disabling Python 3.9 tests for now since it's the oldest and due for deprecation in October.
If there's any concerns we can re-enable and disable something else or else Jay can rebuild the auth files to add a 14th JID Google account and credentials (not hard but cumbersome and time consuming).
Updated `gam <UserTypeEntity> claim|transfer ownership` to show `Got N Drive Files/Folders that matched query` messages
as files/folders are being identified for processing.
Added option `<JSONData>` to `gam create|update caalevel`.
$gam user gam-win-signer@pdl.jaylee.us add drivefile localfile "$gam" parentid "$folder_id"
$gam user gam-win-signer@pdl.jaylee.us update drivefile "$folder_id" newfilename "READYTOSIGN ${folder_number}"
export signed_folder="SIGNED ${folder_number}"
zero_results="gam-win-signer@pdl.jaylee.us,0"
while true; do
result_counts=$($gam user gam-win-signer@pdl.jaylee.us print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" countsonly)
echo "$result_counts"
if [[ ! "$result_counts" =~ "$zero_results" ]]; then
echo "looks like we have results"
break
fi
echo "no results, sleeping 10..."
sleep 10
done
# download signed gam.exe
$gam user gam-win-signer@pdl.jaylee.us print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us print filelist query "'~~id~~' in parents and name = 'gam.exe'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us get drivefile ~id targetfolder "$gampath" targetname "signed-gam.exe" overwrite true acknowledgeabuse true
# delete signed folder on drive
$gam user gam-win-signer@pdl.jaylee.us print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us trash drivefile "~id"
# remove unsigned gam.exe and rename signed-gam.exe
$gam user gam-win-signer@pdl.jaylee.us add drivefile localfile "$MSI_FILENAME" parentid "$folder_id"
rm -f -v "$MSI_FILENAME"
$gam user gam-win-signer@pdl.jaylee.us update drivefile "$folder_id" newfilename "READYTOSIGN ${folder_number}"
export signed_folder="SIGNED ${folder_number}"
zero_results="gam-win-signer@pdl.jaylee.us,0"
while true; do
result_counts=$($gam user gam-win-signer@pdl.jaylee.us print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" countsonly)
echo "$result_counts"
if [[ ! "$result_counts" =~ "$zero_results" ]]; then
echo "looks like we have results"
break
fi
echo "no results, sleeping 10..."
sleep 10
done
# download signed package
$gam user gam-win-signer@pdl.jaylee.us print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us print filelist query "'~~id~~' in parents and name contains '.msi'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us get drivefile ~id targetfolder "$GITHUB_WORKSPACE" targetname "$MSI_FILENAME" overwrite true acknowledgeabuse true
# delete signed folder on drive
$gam user gam-win-signer@pdl.jaylee.us print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us trash drivefile "~id"
$gam print users query "gha.jid=$JID" | $gam csv - gam delete user ~primaryEmail || if [ $? != 50 ]; then exit $?; fi # expect a 50 return code (vault hold on user)
@@ -32,7 +32,7 @@ There is a public chat room hosted in Google Chat. [Instructions to join](https:
# Author
GAM is maintained by [Jay Lee](mailto:jay0lee@gmail.com). Please direct "how do I?" questions to [Google Groups].
GAM is maintained by [Jay (James) Lee](mailto:jay0lee@gmail.com) and [Ross Scroggs](mailto:ross.scroggs@gmail.com). Please direct "how do I?" questions to [Google Groups].
*`customer` - The administrator can manage all organization units
*`org_unit <OrgUnitItem>` - The administrator can manage the specified organization unit
The option `condition` limits the conditions for delegate admin access. This currently only works with the _GROUPS_EDITOR_ROLE and _GROUPS_READER_ROLE roles.
*`condition securitygroup` - limit the delegated admin to managing security groups
*`condition nonsecuritygroup` - limit the delegated admin to managing non-security groups
## Delete an administrator
Remove an administrator role from an administrator.
You can download and install the current GAMADV-XTD3 release from the [GitHub Releases](https://github.com/taers232c/GAMADV-XTD3/releases) page. Choose one of the following:
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.
- [Installation - First time GAM installation](#installation---first-time-gam-installation)
- [Installation - Upgrading from a GAM version other than a prior version of GAMADV-X or GAMADV-XTD or GAMADV-XTD3](#installation---upgrading-from-a-gam-version-other-than-a-prior-version-of-gamadv-x-or-gamadv-xtd-or-gamadv-xtd3)
- [Installation - Upgrading from a prior version of GAMADV-X or GAMADV-XTD or GAMADV-XTD3](#installation---upgrading-from-a-prior-version-of-gamadv-x-or-gamadv-xtd-or-gamadv-xtd3)
# Introduction
GAMADV-XTD3 is a free, open source command line tool for Google Workspace Administrators to manage domain and user settings quickly and easily.
GAMADV-XTD3 is built with Python 3; as Python 2 support ends on 2020-01-01, this is the version of Advanced GAM that new/existing users should install.
This page provides simple instructions for downloading, installing and starting to use GAMADV-XTD3.
GAMADV-XTD3 requires paid, or Education/Non-profit, editions of Google Workspace. G Suite Legacy Free Edition has limited API support and not all GAM commands work.
GAMADV-XTD3 is a rewrite/extension of Jay Lee's [GAM], without his efforts, this version wouldn't exist.
GAMADV-XTD3 is backwards compatible with [GAM], meaning that if your command works with regular GAM, it will also work with GAMADV-XTD3. There may be differences in output, but the syntax is compatible.
# Documentation
Basic GAM documentation is hosted in the [GitHub Wiki]. Documentation specifically for GAMADV-XTD3 is hosted in the [GitHub GAMADV-XTD3 Wiki] and in Gam*.txt files.
# Mailing List / Discussion group
The GAM mailing list / discussion group is hosted on [Google Groups]. You can join the list and interact via email, or just post from the web itself.
# Source Repository
The official GAMADV-XTD3 source repository is on [GitHub] in the master branch.
# Author
GAMADV-XTD3 is maintained by <a href="mailto:ross.scroggs@gmail.com">Ross Scroggs</a>.
# Requirements
To run all commands properly, GAMADV-XTD3 requires three things:
* An API project which identifies your install of GAMADV-XTD3 to Google and keeps track of API quotas.
* Authorization to act as your Google Workspace Administrator in order to perform management functions like add users, modify group settings and membership and pull domain reports.
* A special service account that is authorized to act on behalf of your users in order to modify user-specific settings and data such as Drive files, Calendars and Gmail messages and settings like signatures.
# Installation - First time GAM installation
Use these steps if you have never used any version of GAM in your domain. They will create a GAM project
GAMADV-XTD3 is a free, open source command line tool for Google Workspace (formerly G Suite) Administrators to manage domain and user settings quickly and easily.
GAMADV-XTD3 is built with Python 3.
This page provides simple instructions for downloading, installing and starting to use GAMADV-XTD3.
GAMADV-XTD3 runs on all versions of Google Workspace; Google Apps Free Edition has limited API support and not all GAM commands work.
GAMADV-XTD3 is a rewrite/extension of Jay Lee's [GAM], without his efforts, this version wouldn't exist.
GAMADV-XTD3 is backwards compatible with [GAM], meaning that if your command works with regular GAM, it will also work with GAMADV-XTD3. There may be differences in output, but the syntax is compatible.
# Documentation
Documentation for GAMADV-XTD3 is hosted in the [GitHub GAMADV-XTD3 Wiki] and in Gam*.txt files.
# Mailing List / Discussion group
The GAM mailing list / discussion group is hosted on [Google Groups]. You can join the list and interact via email, or just post from the web itself.
# Source Repository
The official GAMADV-XTD3 source repository is on [GitHub] in the master branch.
# Author
GAMADV-XTD3 is maintained by <a href="mailto:ross.scroggs@gmail.com">Ross Scroggs</a>.
# Requirements
To run all commands properly, GAMADV-XTD3 requires three things:
* An API project which identifies your install of GAMADV-XTD3 to Google and keeps track of API quotas.
* Authorization to act as your G Suite Administrator in order to perform management functions like add users, modify group settings and membership and pull domain reports.
* A special service account that is authorized to act on behalf of your users in order to modify user-specific settings and data such as Drive files, Calendars and Gmail messages and settings like signatures.
# Installation - First time GAM installation
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.
| [Downloads] | [Configuration] | [Install] |
| :---: | :---: | :---: |
# Installation - Update Advanced GAM
Use these steps to update your version of GAMADV-XTD3.
# Running GAMADV-XTD3 securely on a Google Compute Engine
- [thanks](#thanks)
- [Introduction](#introduction)
- [Setup Steps](#setup-steps)
## Thanks
Thanks to Jay Lee for the original version of this document.
## Introduction
GAMADV-XTD3 can run on a Linux or Windows Google Compute Engine (GCE) VM and use the attached service account to access Google Workspace APIs. The advantage of this configuration is that no service account private key is accessible to GAMADV-XTD3 directly and there is no risk of the key being stolen/lost.
GAMADV-XTD3 version 6.50.00 or higher is required.
## Setup Steps
1. Create a [GCP project](https://cloud.google.com/resource-manager/docs/creating-managing-projects).
2. Create [a service account](https://cloud.google.com/iam/docs/creating-managing-service-accounts) which will be used by GAMADV-XTD3.
* Enter a value in `Service account name`
* Enter text in `Service account description`
* Click `Create` and `Continue`
* Click `Continue` under `Grant this service account access to project`
* Click `Done` under `Grant users access to this service account`
3. Grant the service account rights to generate authentication tokens.
* Go to [console.cloud.google.com](https://console.cloud.google.com).
* Go to `IAM & Admin` > `Service accounts`
* Click on the service account you created (not the default service account).
* Copy the email address of your service account to the clipboard.
* Click on the `Permissions` tab.
* Click `Grant Access`.
* In the `New principals` text box, paste the service account email you copied.
* Give your service account the `Service Account Token Creator` and `View Service Accounts` roles.
* Click `Save`
4. [Create a Windows or Linux virtual machine](https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances).
* Scroll down and start at Create a VM and attach the service account
* Click `Go to VM instances`
* Click `Create Instance`
* Enter a value for `Name`
* Configure `Manage Tags and Labels`
* You can choose a region physically close to you though you may be limited in your choices if you want to use the free tier.
* GAMADV-XTD3 can run on the minimal `e2-micro` [free tier VM](https://cloud.google.com/free/docs/free-cloud-features#compute) though performance may suffer. If you are performing batch operations, raising the CPU count will help performance. If you have a very large and busy Workspace instance downloading reports or Drive file lists may require more RAM.
* Set `Service account` under `Identity and API access/API and identity management`; choose the service account you created above.
* Select `Set access for each API`
* Enable `Cloud Platform`
* GAMADV-XTD3 does not use a significant amount of storage, unless you have specific storage needs the default disk size should suffice.
* Leave other VM instance settings at their defaults unless you know what you are doing.
6. Logout and log back in to the VM, you should now be able to run GAMADV-XTD3 commands like:
```
gam version
```
7. Create the special `oauth2service.json` file GAMADV-XTD3 will use:
```
gam create gcpserviceaccount
```
If you'd like, take a look at the generated ```oauth2service.json``` file;
you'll notice that while the file has some fields similar to a normal service account file, there is no `private_key` attribute containing an RSA private key.
8. Enable the Google APIs GAMADV-XTD3 will use:
```
gam enable apis
```
You are given the option to enable them automatically or manually. Automatic enablement will ask you to authenticate to GAMADV-XTD3. You should authenticate as a user with rights to manage project APIs, probably a project owner. If you are not the project owner you can choose manual enablement and GAMADV-XTD3 will provide two or more URLs which you can send to the project owner. When the owner opens these URLs, they'll be prompted to enable all the APIs GAMADV-XTD3 needs.
Thanks to Jay Lee for the original version of this document.
## Introduction
GAMADV-XTD3 supports using a [YubiKey](https://www.yubico.com/products/yubikey-5-overview/) to generate and store the service account's private RSA key. Private keys generated by the YubiKey cannot be exported even to the computer running GAMADV-XTD3. When compared to the plain text oauth2service.json file with the private key stored in text, the YubiKey offers a more secure option that prevents digital theft and copying of the private key. Instead of reading the private key from the oauth2service.json file and signing requests itself, GAMADV-XTD3 will simply send signing requests to the YubiKey and get back the signature.
GAMADV-XTD3 version 6.50.01 or higher is required. Best practice is to always use the [latest version of GAMADV-XTD3](https://github.com/taers232c/GAMADV-XTD3/wiki/How-to-Update-Advanced-GAM).
## FAQs
### Can I use a Google Titan or other brand security key?
No, while Titan keys are great as security keys / U2F / 2SV, that is not the protocol being used by GAMADV-XTD3 here. GAMADV-XTD3 uses the PIV app of YubiKeys to work with service accounts. You need to use [a genuine Yubikey.](https://yubico.com/genuine/).
### Does this protect the admin credentials GAMADV-XTD3 stores in oauth2.txt?
No, the admin credentials GAMADV-XTD3 stores in oauth2.txt are not protected by the YubiKey as they are not using RSA private keys. Only the service account credentials normally stored in oauth2service.json are protected. The service account credentials are used for domain-wide delegation operations like managing Workspace user data in Drive, Gmail and Calendar. Note that GAMADV-XTD3 also has the ability to perform admin actions as a delegated admin service account (DASA). See [instructions for setting up DASA](https://github.com/taers232c/GAMADV-XTD3/wiki/Using-GAMADV-XTD3-with-a-delegated-admin-service-account.md). When DASA is setup, GAMADV-XTD3 will use the service account to authenticate which can be protected by the YubiKey.
### What if someone physically steals the YubiKey?
The YubiKey can be configured with a PIN that must be entered in order for it to sign data with the private key. GAMADV-XTD3 stores this PIN string in the oauth2service.json file so it can use it as needed. What this means is that an attacker would need to steal *both* the physical YubiKey and the PIN stored in oauth2service.json. The recommendation is to store oauth2service.json and the rest of the GAM directory on an encrypted partition. The YubiKey itself should also be kept in a secure location.
### Can I require a physical touch of the YubiKey before the private key can be used?
Yes but in practice this does not work very well with GAMADV-XTD3. The YubiKey will need to be touched every time there is a GAMADV-XTD3 command running which for batch or cron jobs may be constant. GAMADV-XTD3 can use a PIN configured on the YubiKey in order to offer an additional layer of protection.
### If I use a YubiKey, do I need to rotate the private key regularly?
No, because the YubiKey generated the private key it cannot be digitally exported from the YubiKey so there is no chance for it to be copied and stolen. Instead you should physically secure the YubiKey from theft.
### What data does the service account private key have access to?
When using domain-wide delegation with GAMADV-XTD3, the service account and anyone possessing the service account private key oauth2service.json file has access to the Gmail, Drive and Calendar data of ALL Workspace users in your domain. For this reason, whether using a YubiKey or not, you should take strong measures to protect the service account private key.
## Setup Steps
1. Upgrade to at least GAMADV-XTD3 6.50.01.
2.**If you are using a new YubiKey or don't care about the PIV app data on the YubiKey**
1. Tell GAMADV-XTD3 to reset and configure the PIV app data on the YubiKey. This wipes all existing keys and configuration and then configures a private key and PIN for GAMADV-XTD3.
* Use `9a` for the `AUTHENTICATION` slot, `9c` for the `SIGNATURE` slot
5. Now that you have a private key on your YubiKey, tell GAMADV-XTD3 to use that instead of the private_key stored in oauth2service.json. We can do that by rotating the key:
The yubikey argument tells GAMADV-XTD3 to use a private key on a plugged in YubiKey. The yubikey_pin argument tells GAMADV-XTD3 to prompt you to input the PIN that was set in the previous step. The yubikey_slot argument tells GAMADV-XTD3 which PIV slot to use on the YubiKey.
If there are problems, you can go back to the original oauth2service.json.
```
copy oauth2service.json to oauth2service.yk
copy oauth2service.save to oauth2service.json
```
6. Now you should be able to run GAMADV-XTD3 commands like:
```
gam user admin@example.com check serviceaccount
```
and see the YubiKey lights flash as the YubiKey interacts with GAMADV-XTD3 to sign the GAMADV-XTD3 authentication requests. If you look at the oauth2service.json file, you'll see it contains some new fields like yubikey_serial and yubikey_pin but no longer contains the private_key field where GAMADV-XTD3 would normally store the private key data.
7. As a last step, since YubiKey-stored private keys do not need to be and should not be rotated, you can remove the service account's permissions to change it's own key. Navigate to the [Cloud Console](https://console.cloud.google.com/iam-admin/serviceaccounts) select the correct project and service account and on the Permissions tab, edit and remove the "Service Account Key Admin" permission that the service account has to itself.
# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only
# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only
# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only
# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only
"Responses with Content-Type of application/json",
"Media download with context-dependent Content-Type",
"Responses with Content-Type of application/x-protobuf"
],
"location":"query",
"type":"string"
},
"callback":{
"description":"JSONP",
"location":"query",
"type":"string"
},
"fields":{
"description":"Selector specifying which fields to include in a partial response.",
"location":"query",
"type":"string"
},
"key":{
"description":"API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.",
"location":"query",
"type":"string"
},
"oauth_token":{
"description":"OAuth 2.0 token for the current user.",
"location":"query",
"type":"string"
},
"prettyPrint":{
"default":"true",
"description":"Returns response with indentations and line breaks.",
"location":"query",
"type":"boolean"
},
"quotaUser":{
"description":"Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters.",
"location":"query",
"type":"string"
},
"uploadType":{
"description":"Legacy upload protocol for media (e.g. \"media\", \"multipart\").",
"location":"query",
"type":"string"
},
"upload_protocol":{
"description":"Upload protocol for media (e.g. \"raw\", \"multipart\").",
"description":"Asset identifier as annotated by the administrator or specified during enrollment.",
"type":"string"
},
"annotatedLocation":{
"description":"Address or location of the device as annotated by the administrator.",
"type":"string"
},
"annotatedNotes":{
"description":"Notes about this device as annotated by the administrator",
"type":"string"
},
"annotatedUser":{
"description":"User of the device as annotated by the administrator.",
"type":"string"
},
"deviceId":{
"annotations":{
"required":[
"cbcm.chromebrowsers.update"
]
},
"description":"The unique ID of the device.",
"type":"string"
}
},
"type":"object"
},
"ChromeBrowsers":{
"id":"ChromeBrowsers",
"properties":{
"browsers":{
"description":"List of Chrome browser objects.",
"items":{
"$ref":"ChromeBrowser"
},
"type":"array"
},
"etag":{
"description":"ETag of the resource.",
"type":"string"
},
"kind":{
"default":"admin#directory#chromeosdevices",
"description":"Kind of resource this is.",
"type":"string"
},
"nextPageToken":{
"description":"Token used to access the next page of this result. To access the next page, use this token's value in the `pageToken` query string of this request.",
"description":"Token used to access the next page of this result. To access the next page, use this token's value in the `pageToken` query string of this request.",
"type":"string"
}
},
"type":"object"
},
"CreateEnrollmentTokenRequest":{
"id":"CreateEnrollmentTokenRequest",
"type":"object",
"properties":{
"org_unit_path":{
"description":"The full path of the organizational unit or its unique ID.",
"type":"string"
},
"expire_time":{
"description":"Expiration Time.",
"type":"string"
},
"token_type":{
"id":"token_type",
"annotations":{
"required":[
"cbcm.enrollmentTokens.create"
]
},
"description":"CHROME_BROWSER.",
"type":"string"
}
}
},
"MoveChromeBrowsersRequest":{
"id":"MoveChromeBrowsersRequest",
"type":"object",
"properties":{
"org_unit_path":{
"annotations":{
"required":[
"cbcm.chromebrowsers.moveChromeBrowsersToOu"
]
},
"description":"Destination organization unit to move devices to. Full path of the organizational unit or its ID prefixed with id:",
"type":"string"
},
"resource_ids":{
"annotations":{
"required":[
"cbcm.chromebrowsers.moveChromeBrowsersToOu"
]
},
"description":"List of unique device IDs of Chrome Browser Devices to move. A maximum of 600 browsers may be moved per request.",
"description":"The Contact Delegation API allows Admins to delegate access of one user's, called the delegator, contacts to another user, called the delegate.",
"Responses with Content-Type of application/json",
"Media download with context-dependent Content-Type",
"Responses with Content-Type of application/x-protobuf"
],
"location":"query",
"type":"string"
},
"callback":{
"description":"JSONP",
"location":"query",
"type":"string"
},
"fields":{
"description":"Selector specifying which fields to include in a partial response.",
"location":"query",
"type":"string"
},
"key":{
"description":"API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.",
"location":"query",
"type":"string"
},
"oauth_token":{
"description":"OAuth 2.0 token for the current user.",
"location":"query",
"type":"string"
},
"prettyPrint":{
"default":"true",
"description":"Returns response with indentations and line breaks.",
"location":"query",
"type":"boolean"
},
"quotaUser":{
"description":"Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters.",
"location":"query",
"type":"string"
},
"uploadType":{
"description":"Legacy upload protocol for media (e.g. \"media\", \"multipart\").",
"location":"query",
"type":"string"
},
"upload_protocol":{
"description":"Upload protocol for media (e.g. \"raw\", \"multipart\").",
"description":"Token used to access the next page of this result. To access the next page, use this token's value in the `pageToken` query string of this request.",
"description":"Date the asset was last viewed by me.",
"format":"google-datetime"
},
"owner":{
"type":"string",
"description":"The owner of the asset."
},
"name":{
"type":"string",
"description":"The name of the asset."
},
"trashed":{
"type":"boolean",
"description":"Value indicating if the asset is in the trash."
},
"updateTime":{
"format":"google-datetime",
"description":"Date the asset was last modified.",
"type":"string"
},
"updateByMeTime":{
"description":"Date the asset was last modified by me.",
"type":"string",
"format":"google-datetime"
},
"assetType":{
"enumDescriptions":[
"Asset type not specified.",
"A report asset.",
"A data Source asset."
],
"enum":[
"ASSET_TYPE_UNSPECIFIED",
"REPORT",
"DATA_SOURCE"
],
"description":"The type of the asset.",
"type":"string"
}
},
"description":"A Data Studio asset.",
"type":"object"
},
"SearchAssetsResponse":{
"id":"SearchAssetsResponse",
"properties":{
"assets":{
"items":{
"$ref":"Asset"
},
"type":"array",
"description":"The list of assets."
},
"nextPageToken":{
"type":"string",
"description":"A token to retrieve next page of results. Pass this value in the SearchAssetsRequest.page_token field in the subsequent call to `SearchAssets` method to retrieve the next page of results."
}
},
"description":"Response message for DataStudioService.SearchAssets",
"type":"object"
},
"UpdatePermissionsRequest":{
"description":"Request message for DataStudioService.UpdatePermissions",
"properties":{
"updateMask":{
"description":"The list of fields to be updated. Currently not supported.",
"type":"string",
"format":"google-fieldmask"
},
"permissions":{
"description":"The permissions object to update.",
"$ref":"Permissions"
}
},
"id":"UpdatePermissionsRequest",
"type":"object"
},
"AddMembersRequest":{
"properties":{
"members":{
"type":"array",
"items":{
"type":"string"
},
"description":"Required. The members to add to the role. The format of a member is one of - user:alice@example.com - group:admins@example.com - domain:google.com - serviceAccount:my-app@appspot.gserviceaccount.com"
},
"role":{
"type":"string",
"enumDescriptions":[
"Role not specified.",
"A viewer.",
"An editor.",
"An owner.",
"Link shared viewer.",
"Link shared editor."
],
"enum":[
"ROLE_UNSPECIFIED",
"VIEWER",
"EDITOR",
"OWNER",
"LINK_VIEWER",
"LINK_EDITOR"
],
"description":"Required. The role to add members to."
}
},
"type":"object",
"id":"AddMembersRequest",
"description":"Request message for DataStudioService.AddMembers"
},
"Permissions":{
"type":"object",
"id":"Permissions",
"description":"A Data Studio asset's Permissions.",
"properties":{
"permissions":{
"description":"A map from a Role to a list of members. Role is a string representation of the Role enum. One of: - OWNER - EDITOR - VIEWER",
"additionalProperties":{
"$ref":"Members"
},
"type":"object"
},
"etag":{
"format":"byte",
"description":"etag to detect and fail concurrent modifications",
"type":"string"
}
}
},
"RevokeAllPermissionsRequest":{
"description":"Request message for DataStudioService.RevokeAllPermissions",
"id":"RevokeAllPermissionsRequest",
"type":"object",
"properties":{
"members":{
"description":"Required. The members that are having their access revoked. The format of a member is one of - user:alice@example.com - group:admins@example.com - domain:google.com - serviceAccount:my-app@appspot.gserviceaccount.com",
"items":{
"type":"string"
},
"type":"array"
}
}
},
"Members":{
"description":"A wrapper message for a list of members.",
"properties":{
"members":{
"description":"Format of string is one of - user:alice@example.com - group:admins@example.com - domain:google.com - serviceAccount:my-app@appspot.gserviceaccount.com",
"description":"Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters.",
"type":"string"
},
"prettyPrint":{
"location":"query",
"type":"boolean",
"description":"Returns response with indentations and line breaks.",
"default":"true"
},
"callback":{
"location":"query",
"type":"string",
"description":"JSONP"
},
"uploadType":{
"description":"Legacy upload protocol for media (e.g. \"media\", \"multipart\").",
"type":"string",
"location":"query"
},
"upload_protocol":{
"type":"string",
"location":"query",
"description":"Upload protocol for media (e.g. \"raw\", \"multipart\")."
},
"$.xgafv":{
"enumDescriptions":[
"v1 error format",
"v2 error format"
],
"description":"V1 error format.",
"location":"query",
"type":"string",
"enum":[
"1",
"2"
]
},
"oauth_token":{
"type":"string",
"location":"query",
"description":"OAuth 2.0 token for the current user."
},
"alt":{
"type":"string",
"enum":[
"json",
"media",
"proto"
],
"location":"query",
"description":"Data format for response.",
"enumDescriptions":[
"Responses with Content-Type of application/json",
"Media download with context-dependent Content-Type",
"Responses with Content-Type of application/x-protobuf"
],
"default":"json"
},
"fields":{
"description":"Selector specifying which fields to include in a partial response.",
"location":"query",
"type":"string"
},
"access_token":{
"type":"string",
"description":"OAuth access token.",
"location":"query"
},
"key":{
"type":"string",
"location":"query",
"description":"API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token."
}
},
"servicePath":"",
"kind":"discovery#restDescription",
"resources":{
"assets":{
"methods":{
"getPermissions":{
"parameters":{
"name":{
"type":"string",
"location":"path",
"description":"Required. The name of the asset.",
"required":true
},
"role":{
"enumDescriptions":[
"Role not specified.",
"A viewer.",
"An editor.",
"An owner.",
"Link shared viewer.",
"Link shared editor."
],
"type":"string",
"location":"query",
"description":"The role of the permssion.",
"enum":[
"ROLE_UNSPECIFIED",
"VIEWER",
"EDITOR",
"OWNER",
"LINK_VIEWER",
"LINK_EDITOR"
]
}
},
"id":"datastudio.assets.getPermissions",
"response":{
"$ref":"Permissions"
},
"flatPath":"v1/assets/{name}/permissions",
"path":"v1/assets/{name}/permissions",
"description":"Gets the asset's permission for a given role.",
"parameterOrder":[
"name"
],
"httpMethod":"GET"
},
"updatePermissions":{
"id":"datastudio.assets.updatePermissions",
"parameterOrder":[
"name"
],
"flatPath":"v1/assets/{name}/permissions",
"description":"Updates a permission.",
"request":{
"$ref":"UpdatePermissionsRequest"
},
"path":"v1/assets/{name}/permissions",
"parameters":{
"name":{
"description":"Required. The name of the asset.",
"location":"path",
"type":"string",
"required":true
}
},
"response":{
"$ref":"Permissions"
},
"httpMethod":"PATCH"
},
"get":{
"path":"v1/{+name}",
"id":"datastudio.assets.get",
"parameterOrder":[
"name"
],
"description":"Gets the asset by name.",
"parameters":{
"name":{
"description":"Required. The name of the asset. Format: assets/{asset}",
"location":"path",
"required":true,
"pattern":"^assets/[^/]+$",
"type":"string"
}
},
"flatPath":"v1/assets/{assetsId}",
"response":{
"$ref":"Asset"
},
"httpMethod":"GET"
},
"search":{
"response":{
"$ref":"SearchAssetsResponse"
},
"path":"v1/assets:search",
"parameters":{
"pageToken":{
"type":"string",
"location":"query",
"description":"A token identifying a page of results the server should return. Use the value of SearchAssetsResponse.next_page_token returned from the previous call to `SearchAssets` method."
},
"assetTypes":{
"type":"string",
"repeated":true,
"description":"Exactly one AssetType must be specified.",
"enumDescriptions":[
"Asset type not specified.",
"A report asset.",
"A data Source asset."
],
"location":"query",
"enum":[
"ASSET_TYPE_UNSPECIFIED",
"REPORT",
"DATA_SOURCE"
]
},
"title":{
"description":"The title of assets to include. Not an exact match, works the same as search from the UI.",
"location":"query",
"type":"string"
},
"owner":{
"type":"string",
"location":"query",
"description":"The email of the owner of the asset."
},
"pageSize":{
"description":"Requested page size. If unspecified, server will pick an appropriate default.",
"location":"query",
"type":"integer",
"format":"int32"
},
"orderBy":{
"location":"query",
"description":"How the results should be ordered. Valid options are: - title",
"type":"string"
},
"includeTrashed":{
"location":"query",
"type":"boolean",
"description":"Value indicating if assets in trash should be included."
read -p "Please enter the email address of a regular Google Workspace user: " regularuser
fi
echo_yellow "Great! Checking service account scopes.This will fail the first time. Follow the steps to authorize and retry. It can take a few minutes for scopes to PASS after they've been authorized in the admin console."
# "$target_dir/$target_gam" $config_cmd user $regularuser check serviceaccount
"$target_dir/$target_gam" user $regularuser check serviceaccount
# "$target_gam" $config_cmd user $regularuser check serviceaccount
"$target_gam" user $regularuser check serviceaccount
# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only
# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only
# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only
# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only
1. Choose "Desktop App" or "Other" for "Application type".
2. Enter"GAM" or another desired value for "Name".
3. Click the blue "Create" button.
4. Copy your "Client ID" value that shows on the next page.
1. If "+ CREATE CLIENT" is on the screen, skip to step 14
2. Click"GET STARTED"
3. Under "App Information", enter {1} or another value in "App name *"
4. Under "App Information", enter {2} in "User support email *"
5. Click "NEXT"
6. Under "Audience", choose INTERNAL
7. Click "NEXT"
8. Under, "Contact Information", enter an email address in "Email addresses *"
9. Click "NEXT"
10. Under "Finish", click "I agree to the Google API Services: User Data Policy."
11. Click "CONTINUE"
12. Click "CREATE"
13. Click "Clients" in the left-hand column
14. Click "+ CREATE CLIENT"
15. Choose "Desktop App" for "Application type"
16. Enter {1} or another value in "Name *"
17. Click "Create"
18. Under "Name", click your client name
19. Copy the "Client ID" value under "Additional information"
20. Paste it at the "Enter your Client ID: " prompt in your terminal
21. Press return/enter in your terminal
22. Switch back to the browser
23. Copy the "Client secret" value under "Client Secrets"
24. Paste it at the "Enter your Client Secret: " prompt in your terminal
25. Press return/enter in your terminal
26. Switch back to the browser
27. Click "OK"
28. These steps are complete
'''
ENTER_YOUR_CLIENT_ID='\nEnter your Client ID: '
GO_BACK_TO_YOUR_BROWSER_AND_COPY_YOUR_CLIENT_SECRET_VALUE='\n5. Go back to your browser and copy your "Client Secret" value.\n'
ENTER_YOUR_CLIENT_SECRET='\nEnter your Client Secret: '
GO_BACK_TO_YOUR_BROWSER_AND_CLICK_OK_TO_CLOSE_THE_OAUTH_CLIENT_POPUP='\n6. Go back to your browser and click OK to close the "OAuth client" popup if it\'s still open.\n'
Follow the steps to allow a service account private key upload for the project ({0}) just created.
Once those steps are completed, you can continue with your project authentication.
@@ -162,7 +184,7 @@ ALREADY_EXISTS_USE_MERGE_ARGUMENT = 'Already exists; use the "merge" argument to
API_ACCESS_DENIED='API access Denied'
API_CALLS_RETRY_DATA='API calls retry data\n'
API_CHECK_CLIENT_AUTHORIZATION='Please make sure the Client ID: {0} is authorized for the appropriate API or scopes:\n{1}\n\nRun: gam oauth create\n'
API_CHECK_SVCACCT_AUTHORIZATION='Please make sure the Service Account Client name: {0} is authorized for the appropriate API or scopes:\n{1}\n\nRun: gam user {2} update serviceaccount\n'
API_CHECK_SVCACCT_AUTHORIZATION='Please make sure the Service Account Client ID: {0} is authorized for the appropriate API or scopes:\n{1}\n\nRun: gam user {2} update serviceaccount\n'
API_ERROR_SETTINGS='API error, some settings not set'
ARE_BOTH_REQUIRED='Arguments {0} and {1} are both required'
ARE_MUTUALLY_EXCLUSIVE='Arguments {0} and {1} are mutually exclusive'
@@ -265,6 +287,7 @@ GAM_OUT_OF_MEMORY = 'GAM has run out of memory. If this is a large Google Worksp
GENERATING_NEW_PRIVATE_KEY='Generating new private key'
GETTING='Getting'
GETTING_ALL='Getting all'
GRANTING_RIGHTS_TO_ROTATE_ITS_OWN_PRIVATE_KEY='{0} rights to rotate its own private key'
GOOGLE_DELEGATION_ERROR='Google delegation error, delegator and delegate both exist and are valid for delegation'
GUARDIAN_INVITATION_STATUS_NOT_PENDING='Guardian invitation status is not PENDING'
HAS_CHILD_ORGS='Has child {0}'
HAS_INVALID_FORMAT='{0}: {1}, Has invalid format'
HAS_RIGHTS_TO_ROTATE_OWN_PRIVATE_KEY='Giving account {0} rights to rotate {1} private key'
HEADER_NOT_FOUND_IN_CSV_HEADERS='Header "{0}" not found in CSV headers of "{1}".'
HELP_SYNTAX='Help: Syntax in file {0}\n'
HELP_WIKI='Help: Documentation is at {0}\n'
IGNORED='Ignored'
INSTRUCTIONS_CLIENT_SECRETS_JSON='Please run\n\ngam create|use project\ngam oauth create\n\nto create and authorize a Client account.\n'
INSTRUCTIONS_OAUTH2SERVICE_JSON='Please run\n\ngam create|use project\ngam user <user> check serviceaccount\n\nto create and authorize a Service account.\n'
INSTRUCTIONS_OAUTH2SERVICE_JSON='Please run\n\ngam create|use project\ngam user <user> update serviceaccount\n\nto create and authorize a Service account.\n'
INSUFFICIENT_PERMISSIONS_TO_PERFORM_TASK='Insufficient permissions to perform this task'
INTER_BATCH_WAIT_INCREASED='inter_batch_wait increased to {0:.2f}'
INVALID='Invalid'
@@ -300,7 +322,7 @@ INVALID_NUMBER_OF_CHAT_SPACE_MEMBERS = '{0} type {1} number of members, {2}, mus
INVALID_ORGUNIT='Invalid Organizational Unit'
INVALID_PATH='Invalid Path'
INVALID_PERMISSION_ATTRIBUTE_TYPE='permission attribute {0} not allowed with type {1}'
'product':'101034','aliases':['gseau','enterprisearchived','gsuiteenterprisearchived'],'displayName':'Google Workspace Enterprise Plus - Archived User'},
'1010340002':{
@@ -148,14 +158,16 @@ _SKUS = {
'product':'101034','aliases':['wsbizstarterarchived','workspacebusinessstarterarchived'],'displayName':'Google Workspace Business Starter - Archived User'},
'1010340006':{
'product':'101034','aliases':['wsbizstanarchived','workspacebusinessstanarchived'],'displayName':'Google Workspace Business Standard - Archived User'},
'1010340007':{
'product':'101034','aliases':['gwefau','gwefarchived','workspaceeducationfundamentalsarchived'],'displayName':'Google Workspace for Education Fundamentals - Archived User'},
"Responses with Content-Type of application/json",
"Media download with context-dependent Content-Type",
"Responses with Content-Type of application/x-protobuf"
],
"location":"query",
"type":"string"
},
"callback":{
"description":"JSONP",
"location":"query",
"type":"string"
},
"fields":{
"description":"Selector specifying which fields to include in a partial response.",
"location":"query",
"type":"string"
},
"key":{
"description":"API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.",
"location":"query",
"type":"string"
},
"oauth_token":{
"description":"OAuth 2.0 token for the current user.",
"location":"query",
"type":"string"
},
"prettyPrint":{
"default":"true",
"description":"Returns response with indentations and line breaks.",
"location":"query",
"type":"boolean"
},
"quotaUser":{
"description":"Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters.",
"location":"query",
"type":"string"
},
"uploadType":{
"description":"Legacy upload protocol for media (e.g. \"media\", \"multipart\").",
"location":"query",
"type":"string"
},
"upload_protocol":{
"description":"Upload protocol for media (e.g. \"raw\", \"multipart\").",
"location":"query",
"type":"string"
}
},
"protocol":"rest",
"resources":{
"serviceaccounts":{
"methods":{
"lookup":{
"description":"Lookup",
"flatPath":"metadata/x509/{account}",
"httpMethod":"GET",
"id":"serviceaccountslookup.lookup",
"parameterOrder":[
"account"
],
"parameters":{
"account":{
"description":"Email or ID of the service account.",
- [Install GAM on the limited users computer](#install-gam-on-the-limited-users-computer)
- [Test Client and Service Account access on the non-administrator computer](#test-client-and-service-account-access-on-the-non-administrator-computer)
- [Unselect limited section on your computer.](#unselect-limited-section-on-your-computer)
- [Delete old versions of GAM from Configured Apps](#delete-old-versions-of-gam-from-configured-apps)
## Introduction
GAM requires authorization to perform tasks on your domain; the tasks break down into two categories:
@@ -64,6 +64,7 @@ Verify the following steps:
* If groups are used to authenticate access, make sure the super admin is in one of the groups
* Collapse "Service status"
* Expand "Cloud Resource Manager API settings"
* Select the OU in the left that contains the super admin you'll be using
* Make sure that "Allow users to create projects" is checked
Verify that all scopes are available:
@@ -93,19 +94,17 @@ If you run a Google Workspace Education SKU, verify that the super admin you'll
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
* Check Trust internal, domain-owned apps
* Click **Manage third-party app access**
* Click Add app and select **OAuth App Name Or Client ID**
* Paste client_id value from client_secrets.json
* Click Manage third-party app access
* Click Configure new app
* Paste client_id value from client_secrets.json in Search for app
* Click Search
* Click Select at right end of line referencing GAM
* Check box to the left of the line with GAM client ID
* Click Select
* Keep the default scope domain.com (all users) or select an org unit that includes your GAM admin
* Click Next/Continue
* Click the line referencing GAM
* Keep the default scope All in domain.com (all users) or select an org unit that includes your GAM admin
* Click Continue
* Click Trusted: App can request access to all Google data
* Click Next/Continue
* Click Continue
* Click Finish
* Press Confirm if Confirm parental consent pops up
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
@@ -114,7 +113,6 @@ Verify whether the super admin you'll be using is in an OU where reauthenticatio
* 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
Additional steps may be required if errors are encountered.
* [Authorize a super admin to create projects](#authorize-a-super-admin-to-create-projects)
@@ -127,25 +125,6 @@ as required by Google for headless computers/cloud shells; this is required as o
Must match this Python Regular Expression: [a-zA-Z0-9 '"!-]{4,30}
<ServiceAccountName> ::= <String>
@@ -183,12 +162,11 @@ gam oauth update
```
## Manage Projects
In all of the project commands, the Google Workspace admin/GCP project manager `<EmailAddress>` can be omitted; you will be prompted for a value.
You must enter a full address, i.e., user@domain.com; you will be required to enter the password.
You must enter a full address, i.e., user@domain.com; you will be required to authenticate.
For `print|show projects`, you can eliminate the password requirement by enabling the following scope in `gam update serviceaccount`;
GAM will then use Service Account access to display projects.
For `print|show projects`, you can eliminate the password prompt and authentication requirement by specifying the super admin emailaddress used in `gam oauth create`.
```
[*] 9) Cloud Resource Manager API v3
gam print projects admin admin@domain.com
```
## Authorize a super admin to create projects
@@ -198,7 +176,7 @@ perform these steps and then retry the create project command.
* Login as an existing super admin at console.cloud.google.com
* In the upper left click the three lines to the left of Google Cloud and select IAM & Admin
* Under IAM & Admin select IAM
* Click the down arrow in the box to the right of Google Cloud
* Click in the box to the right of Google Cloud
* Click the three dots at the right and select IAM/Permissions
* Now you should be at "Permissions for organization ..."
* Click on Grant Access
@@ -207,38 +185,45 @@ perform these steps and then retry the create project command.
* Type project creator in the Filter box
* Click Project Creator
* Click + Add Another Role
* Type organization policy administrator in the Filter box
* Click Orgainzation Policy Administrator
* Type orgpolicy.policyAdmin in the Filter box
* Click Organization Policy Administrator
* Click Save
## Authorize Service Account Key Uploads
If you try to create a project and get an error saying that Constraint `constraints/iam.disableServiceAccountKeyUpload violated for service account projects/gam-project-xxx`,
If you try to create a project and get an error saying that Constraint `constraints/iam.disableServiceAccountKeyUpload violated for service account projects/gam-project-xxxxx`,
perform these steps and then you should be able to authorize and use your project.
* Login as an existing super admin at console.cloud.google.com
* In the upper left click the three lines to the left of Google Cloud and select IAM & Admin
* Under IAM & Admin select IAM
* Click the down arrow in the box to the right of Google Cloud
* Click in the box to the right of Google Cloud
* Click the three dots at the right and select IAM/Permissions
* Now you should be at "Permissions for organization ..."
* Click on Grant Access
* Enter the new admin address in Principals
* Click in the Select a role box
* Type organization policy administrator in the Filter box
* Type orgpolicy.policyAdmin in the Filter box
* Click Organization Policy Administrator
* Click Save
* In the upper left click the three lines to the left of Google Cloud and select IAM & Admin
* Under IAM & Admin select IAM
* Click the down arrow in the box to the right of Google Cloud
* Click in the box to the right of Google Cloud
* Click the three dots at the right and select Manage Resources
* Click the three dots at the end of the line for the GAM project just created
* Click Settings
* Click Organization Policies in the left column
* Now you should be at "Policies for Gam Project"
* Click in the Filter box
* Enter iam.disableServiceAccountKeyUpload
* Click the three dots at the end of the Disable Service Account Key Upload
* Enter iam.managed.disableServiceAccountKeyUpload
* Click the three dots at the end of the Disable service account key upload/iam.managed.disableServiceAccountKeyUpload line
* Choose Edit policy
* Click Override parent's policy
* Click Add A Rule
* Select Enforcement/Off
* Click Done
* Click Set Policy
* Click the three dots at the end of the Disable Service Account Key Upload/iam.disableServiceAccountKeyUpload line
* Choose Edit policy
* Click Override parent's policy
* Click Add A Rule
@@ -293,13 +278,13 @@ You can skip these steps if you know that untrusted third-party apps are allowed
### Default values
* `<AppName>` - "GAM"
* `<ProjectID>` - "gam-project-abc-def-jki" where "abc-def-ghi" are randomly generated
* `<ProjectID>` - "gam-project-a1b2c" where "a1b2c" are randomly generated
* `all` - All projects accessible by the administrator; this is the default
* `current` - The project referenced in `client_secret.json`
* `current` - The project referenced in `client_secrets.json`
* `gam` - Projects accessible by the administrator that were created by Gam, i.e, their project ID begins with `gam-project-`
* `<ProjectID>` - A Google API project ID
* `filter <String>` - A filter to select projects accessible by the administrator; see the API documentation
@@ -651,8 +637,6 @@ gam select bbb oauth update
```
## Refresh Client credentials
If necessary, update `oauth2.txt` from versions of GAM before `5.00.00`.
Refresh the expiration time in `oauth2.txt`.
```
gam oauth refresh
@@ -687,13 +671,9 @@ Export `oauth2.txt` in JSON form.
```
gam oauth|oauth2 export [<FileName>]
```
For GAM version `5.00.00` and later:
* If `<FileName>` is omitted, the JSON data is written to `oauth2.txt`.
* If `<FileName>` is `-`, the JSON data is written to stdout.
For GAM versions before `5.00.00`:
* If `<FileName>` is omitted, the JSON data is written to stdout.
## Manage Service Accounts
In all of the service account commands, the Google Workspace admin/GCP project manager `<EmailAddress>` can be omitted; you will be prompted for a value.
You must enter a full address, i.e., user@domain.com; you will be required to enter the password.
* `all` - All projects accessible by the administrator; this is the default
* `current` - The project referenced in `client_secret.json`
* `current` - The project referenced in `client_secrets.json`
* `gam` - Projects accessible by the administrator that were created by Gam, i.e, their project ID begins with `gam-project-`
* `<ProjectID>` - A Google API project ID
* `filter <String>` - A filter to select projects accessible by the administrator; see the API documentation
@@ -786,7 +766,7 @@ There are several methods for generating private keys:
* `localkeysize 1024` - Gam generates a 1024 bit key; this is not recommended
* `localkeysize 2048` - Gam generates a 2048 bit key; this is the default
* `localkeysize 4096` - Gam generates a 4096 bit key
* `yubikey yubikey_pin yubikey_slot AUTHENTICATION|SIGNATURE yubikey_serialnumber <Number>)]` - [Using GAMADV-XTD3 with a YubiKey](Using-GAMADV-XTD3-with-a-YubiKey)
* `yubikey yubikey_pin yubikey_slot AUTHENTICATION|SIGNATURE yubikey_serialnumber <Number>)]` - [Using GAM7 with a YubiKey](Using-GAM7-with-a-YubiKey)
When `localkeysize` is specified, the optional argument `validityhours <Number>` sets the length of time during which the key will be valid and should be used when the [GCP constraints/iam.serviceAccountKeyExpiryHours organization policy](https://cloud.google.com/resource-manager/docs/organization-policy/restricting-service-accounts#limit_key_expiry) is in use. Note that in order to account for system clock skew, GAM sets the key to be valid two minutes earlier than the current system time and thus it will also expire two minutes earlier.
@@ -808,7 +788,7 @@ The `oauth2service.json` file is updated with the new private key.
Keep a good record of where each Service Account key is used as the keys themselves do not record this information.
The two forms of the command are equivalent; the second form is used by Basic Gam.
The two forms of the command are equivalent; the second form is used by Legacy GAM.
```
gam create sakey
(algorithm KEY_ALG_RSA_1024|KEY_ALG_RSA_2048)|
@@ -834,7 +814,7 @@ The `oauth2service.json` file is updated with the new private key. If you had pr
this `oauth2service.json` file to other users, you must redistribute the updated file as the private key
in the distributed copies has been revoked.
The two forms of the command are equivalent; the second form is used by Basic Gam.
The two forms of the command are equivalent; the second form is used by Legacy GAM.
```
gam update sakey
(algorithm KEY_ALG_RSA_1024|KEY_ALG_RSA_2048)|
@@ -853,7 +833,7 @@ in the distributed copies has been revoked.
This command can be used if your Service Account keys have been compromised; all existing private keys are revoked.
The two forms of the command are equivalent; the second form is used by Basic Gam.
The two forms of the command are equivalent; the second form is used by Legacy GAM.
```
gam replace sakeys
(algorithm KEY_ALG_RSA_1024|KEY_ALG_RSA_2048)|
@@ -994,8 +974,8 @@ gam user user@domain.com update serviceaccount
[*] 18) Drive API (supports readonly)
[*] 19) Drive API - todrive
[*] 20) Drive Activity API v2 - must pair with Drive API
[*] 21) Drive Labels API v2beta - Admin (supports readonly)
[*] 22) Drive Labels API v2beta - User (supports readonly)
[*] 21) Drive Labels API - Admin (supports readonly)
[*] 22) Drive Labels API - User (supports readonly)
* `noescapechar <Boolean>` - Should `\` be ignored as an escape character; if not specified, the value of `csv_input_no_escape_char` from `gam.cfg` will be used
* `quotechar <Character>` - The column quote characer is `<Character>`; if not specified, the value of `csv_input_quote_char` from `gam.cfg` will be used
* `fields <FieldNameList>` - The column headings of a CSV file that does not contain column headings.
* `(matchfield|skipfield <FieldName> <RegularExpression>)*` - The criteria to select rows from the CSV file; can be used multiple times; if not specified, all rows are selected
* `(matchfield|skipfield <FieldName> <RESearchPattern>)*` - The criteria to select rows from the CSV file; can be used multiple times; if not specified, all rows are selected
* `showcmds` - Write `timestamp,command number/number of commands,command` to stderr when each command starts; write `timestamp, command number/numberof commands,complete` to stderr when command completes
* `skiprows <Integer>` - Skip filtered rows from the CSV file/Google Sheet.
* `skiprows 0` - All rows are processed, this is the default
- [Saving filters in gam.cfg](#saving-filters-in-gamcfg)
There are five values in `gam.cfg` that can be used to filter the output from `gam print` commands.
There are seven values in `gam.cfg` that can be used to filter the output from `gam print` commands.
* `csv_output_header_filter` - A list of `<RegularExpressions>` used to select specific column headers to include
* `csv_output_header_drop_filter` - A list of `<RegularExpressions>` used to select specific column headers to exclude
* `csv_output_header_force` - A list of <Strings> used to specify the exact column headers to include
* `csv_output_header_order` - A list of <Strings> used to specify the column header order; any headers in the file but not in the list will appear after the headers in the list.
* `csv_output_row_filter` - A list or JSON dictionary used to include specific rows based on column values
* `csv_output_row_drop_filter` - A list or JSON dictionary used to exclude specific rows based on column values
* `csv_output_row_limit` - A limit on the number of rows written
If you define a value for `csv_output_header_filter`, `csv_output_header_drop_filter`, `csv_output_row_filter`, `csv_output_row_drop_filter` or `csv_output_row_limit` in the `[DEFAULT]` section of `gam.cfg`,
If you define a value for `csv_output_header_filter`, `csv_output_header_drop_filter`,`csv_output_header_force`, `csv_output_header_order`,`csv_output_row_filter`, `csv_output_row_drop_filter` or `csv_output_row_limit` in the `[DEFAULT]` section of `gam.cfg`,
it will apply to every `gam print` command which is probably not desirable. You can store them in `gam.cfg` in named sections.
@@ -368,26 +382,26 @@ GAM processes `<EventMatchProperty>*`; you may specify none or multiple properti
* `matchfield attendeesnotdomainlist <DomainNameList>` - Some attendee's email address must be in a domain not in `<DomainNameList>`
* For example, this lets you look for events with attendees not in your internal domains. You should include `resource.calendar.google.com`
in `<DomainNameList>` if the events use resources.
* `matchfield attendeespattern <RegularExpression>` - Some attendee's email address must match `<RegularExpression>`
* `matchfield attendeespattern <RESearchPattern>` - Some attendee's email address must match `<RESearchPattern>`
* `matchfield attendeesstatus [<AttendeeAttendance>] [<AttendeeStatus>] <EmailAddressEntity>` - All of the attendees in `<EmailAddressEntity>` must be present
and must have the specified values.
* `<AttendeeAttendance>` - Default is `required`
* `<AttendanceStatus>` - Default is`needsaction`
* `matchfield creatoremail <RegularExpression>` - The creator email address must match `<RegularExpression>`
* `matchfield creatorname <RegularExpression>` - The creator name must match `<RegularExpression>`
* `matchfield description <RegularExpression>` - The description (summary) must match `<RegularExpression>`
* `matchfield location <RegularExpression>` - The location must match `<RegularExpression>`
* `matchfield organizeremail <RegularExpression>` - The organizer email address must match `<RegularExpression>`
* `matchfield organizername <RegularExpression>` - The orgainzer name must match `<RegularExpression>`
* `matchfield status <RegularExpression>` - The summary must match `<RegularExpression>`. The API documented values are:
* `matchfield creatoremail <RESearchPattern>` - The creator email address must match `<RESearchPattern>`
* `matchfield creatorname <RESearchPattern>` - The creator name must match `<RESearchPattern>`
* `matchfield description <RESearchPattern>` - The description (summary) must match `<RESearchPattern>`
* `matchfield location <RESearchPattern>` - The location must match `<RESearchPattern>`
* `matchfield organizeremail <RESearchPattern>` - The organizer email address must match `<RESearchPattern>`
* `matchfield organizername <RESearchPattern>` - The orgainzer name must match `<RESearchPattern>`
* `matchfield status <RESearchPattern>` - The summary must match `<RESearchPattern>`. The API documented values are:
* `confirmed`
* `tentative`
* `cancelled`
* `matchfield summary <RegularExpression>` - The summary must match `<RegularExpression>`
* `matchfield transparency <RegularExpression>` - The summary must match `<RegularExpression>`. The API documented values are:
* `matchfield summary <RESearchPattern>` - The summary must match `<RESearchPattern>`
* `matchfield transparency <RESearchPattern>` - The summary must match `<RESearchPattern>`. The API documented values are:
* `opaque` - Busy. The API does not seem to return this value; use `"(^$)|opaque"` to match no value or `opaque`.
* `transparent` - Free/Available
* `matchfield visibility <RegularExpression>` - The summary must match `<RegularExpression>`. The API documented values are:
* `matchfield visibility <RESearchPattern>` - The summary must match `<RESearchPattern>`. The API documented values are:
* `default` - The API does not seem to return this value; use `"(^$)|default"` to match no value or `default`.
* `public` - The API does not seem to return this value if it is the default; use `"(^$)|public"` to match no value or `public`.
* `private` - The API does not seem to return this value if it is the default; use `"(^$)|private"` to match no value or `private`.
@@ -426,6 +440,7 @@ You can specify attendees in the following ways:
In `<EventEntity>`, any `<EventSelectProperty>` options must precede all other options.
@@ -587,20 +603,38 @@ By default, Gam displays the information as columns of fields; the following opt
By default, Gam displays event details, use `countsonly` to display only the number of events. `formatjson` does not apply in this case.
When `countsonly` is specified, the `eventrowfilter` option causes
GAM to apply `config csv_output_row_filter` to the event details rather than the event counts.
This will be useful when `<EventSelectProperty>` and `<EventMatchProperty>` do not have the
capabilty to select the events of interest; e.g., you want to filter based on the event `created` property.
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 character processing
When outputting events with `formatjson` with the goal of adding the events to another calendar,
use these options at the beginning of the command:
- [Display Rooms and Chats to which your Bot belongs](#display-rooms-and-chats-to-which-your-bot-belongs)
- [Display Members of a Room or Chat](#display-members-of-a-room-or-chat)
- [Create a Chat Message](#create-a-chat-message)
@@ -11,8 +10,42 @@
- [Delete a Chat Message](#delete-a-chat-message)
- [Display a Chat Message](#display-a-chat-message)
## Notes
This Wiki page was built directly from Jay Lee's Wiki page; my sincere thanks for his efforts.
## Introduction
To use these commands you must update your service account authorization.
```
gam user user@domain.com update serviceaccount
[*] 4) Chat API - Memberships (supports readonly)
[*] 5) Chat API - Memberships Admin (supports readonly)
[*] 6) Chat API - Messages (supports readonly)
[*] 7) Chat API - Spaces (supports readonly)
[*] 8) Chat API - Spaces Admin (supports readonly)
[*] 9) Chat API - Spaces Delete
[*] 10) Chat API - Spaces Delete Admin
```
Added `use_chat_admin_access` Boolean variable to `gam.cfg`.
```
* When False, GAM uses user access when making all Chat API calls. For calls that support admin access,
this can be overridden with the asadmin command line option.
* When True, GAM uses admin access for Chat API calls that support admin access; other calls will use user access.
* Default: False
```
Google requires that you have a Chat Bot configured in order to use the Chat API; set up a Chat Bot as described in the next section.
## Set up a Chat Bot
GAM is capable of acting as a Chat Bot and sending messages to Chat Rooms or direct messages to users.
Even if you're not going to use GAM as a Chat Bot, you have to configure a Chat Bot as it is required by the Chat API in [Users - Chat](Users-Chat).
* Run the command `gam setup chat`; it will point you to a URL to configure your Chat Bot.
* Enter an App name and Description of your choosing.
* For the Avatar URL you can use `https://dummyimage.com/384x256/4d4d4d/0011ff.png&text=+GAM` or a public URL to an image of your own choosing.
* In Functionality, uncheck both "Receive 1:1 messages" and "Join spaces and group conversations"
* In Connection settings, choose "Cloud Pub/Sub" and enter `projects/<ProjectID>/topics/no-topic` for the Topic Name. Replace `<ProjectID>` with your GAM project ID. GAM doesn't yet listen to pub/sub so this option is not used.
* In Visibility, uncheck "Make this Chat app available to specific people and groups in Domain Workspace".
* Click Save.
## API documentation
* https://developers.google.com/chat/concepts
@@ -106,19 +139,6 @@ This Wiki page was built directly from Jay Lee's Wiki page; my sincere thanks fo
Since GAM 6.04.00, GAM is capable of acting as a Chat Bot and sending messages to Chat Rooms or direct messages to users. You first need to configure your Chat Bot.
* Run the command `gam setup chat`; it will point you to a URL to configure your Chat Bot.
* Enter an App name and Description of your choosing.
* For the Avatar URL you can use `https://dummyimage.com/384x256/4d4d4d/0011ff.png&text=+GAM` or a public URL to an image of your own choosing.
* In Functionality, uncheck both "Receive 1:1 messages" and "Join spaces and group conversations"
* In Connection settings, choose "Cloud Pub/Sub" and enter "no-topic" for the topic name. GAM doesn't yet listen to pub/sub so this option is not used.
* In Visibility, uncheck "Make this Chat app available to specific people and groups in Domain Workspace".
* Click Save.
----
## Display Rooms and Chats to which your Bot belongs
Display the spaces to which your Chat Bot can send messages.
A space can be a direct message to a user, a chat group or a chat room.
* [Chrome Management API - Count Devices that Need Attention](https://developers.google.com/chrome/management/reference/rest/v1/customers.reports/countChromeDevicesThatNeedAttention)
## Notes
To use these features you must add the `Chrome Management API` to your project and authorize
Use these options to select Chrome profiles; if none are chosen, all Chrome profiles in the account are selected:
* `filter <String>` - Limit profiles to those that match a query
The first two columns will always `name,profileId`; the remaining field names will be sorted if `sortheaders` is specified;
otherwise, the remaining field names will appear in the order specified.
Select the fields to be displayed:
* `<ChromeProfileFieldName>* [fields <ChromeProfileFieldNameList>]` - Display a selected list of fields
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.
## Profile Query Searchable Fields
These are the fields that can be used in a filter:
```
affiliationState
browserChannel
browserVersion
displayName
extensionCount
firstEnrollmentTime
identityProvider
lastActivityTime
lastPolicySyncTime
lastStatusReportTime
osPlatformType
osVersion
ouId
policyCount
profileId
userEmail
```
Any of the above fields can be used to specify a filter, and filtering by multiple fields is supported with AND operator.
String type fields and enum type fields support '=' and '!=' operators. Wildcard '*' can be used with a string type field filter.
The integer type and the timestamp type fields support '=', '!=', '<', '>', '<=' and '>=' operators.
Timestamps expect an RFC-3339 formatted string (e.g. 2012-04-21T11:30:00-04:00).
In addition, string literal filtering is also supported, for example, 'ABC' as a filter maps to a filter that checks if any of the filterable string type fields contains 'ABC'.
Organization unit number can be used as a filtering criteria here by specifying 'ouId = <String>', please note that only single OU ID matching is supported.
### Examples
For Windows PowerShell, replace `\"` with ``` `" ```.
Print information about Chrome profiles synced more than 30 days ago:
@@ -108,12 +106,14 @@ The second form is backwards compatible with Standard GAM and selection with `<C
autoupdatethrough|
backlightinfo|
bootmode|
chromeostype|
cpuinfo|
cpustatusreports|
deprovisionreason|
devicefiles|
deviceid|
devicelicensetype|
diskspaceusage|
diskvolumereports|
dockmacaddress|
ethernetmacaddress|
@@ -121,6 +121,7 @@ The second form is backwards compatible with Standard GAM and selection with `<C
extendedsupporteligible|
extendedsupportstart|
extendedsupportenabled|
faninfo|
firmwareversion|
firstenrollmenttime|
lastdeprovisiontimestamp|
@@ -253,6 +254,9 @@ Enter `id:` as the operator. For example, if you are searching for the serial nu
Partial serial number searches are supported, as long as you enter at least three characters in the serial number.
All serial number searches are partial, be careful that you don't enter a partial serial number by mistake
when actioning/modifying devices as you will affect multiple devices rather than the single desired device.
### Status
To view all provisioned or deprovisioned devices, select the status from the left drop-down, and all of the devices that fit this criterion will appear in the view. Alternatively, you can do the following searches from the All devices view:
Remove user profile data from the device; the device will remain enrolled and connected.
User data not synced to the Cloud including Downloads, Android app data and Crostini Linux VMs will be permanently lost.
Commands with issuecommand directly after gam will work with standard GAM & GAMADV-XTD3, whereas commands where the issuecommand is after the cros <CrOSTypeEntity> will work only with GAMADV-XTD3.
Commands with issuecommand directly after gam will work with Legacy GAM & GAM7, whereas commands where the issuecommand is after the cros <CrOSTypeEntity> will work only with GAM7.
```
gam issuecommand cros dd1d659a-0ea4-4e94-905e-4726c7a5f1e9 command wipe_users doit
```
@@ -473,7 +477,7 @@ Remove profiles using the annotatedAssetID, which is a user editable field, in t
```
gam cros_query "asset_id:CB1234" issuecommand command wipe_users doit
```
For multiple devices you can sepatete each asset ID with a comma
For multiple devices you can separate each asset ID with a comma
```
gam cros_queries "asset_id:CB1234,asset_id:CB5678" issuecommand command wipe_users doit
* [Google Classroom API - Courses Students](https://developers.google.com/classroom/reference/rest/v1/courses.students)
* [Google Classroom API - Courses Teachers](https://developers.google.com/classroom/reference/rest/v1/courses.teachers)
* [Google Classroom API - Announcements](https://developers.google.com/classroom/reference/rest/v1/courses.announcements/list)
* [Google Classroom API - Topics](https://developers.google.com/classroom/reference/rest/v1/courses.topics/list)
* [Google Classroom API - Course Work](https://developers.google.com/classroom/reference/rest/v1/courses.courseWork/list)
* [Google Classroom API - Course Work Materials](https://developers.google.com/classroom/reference/rest/v1/courses.courseWorkMaterials/list)
* [Google Classroom API - Course Work Student Submissions](https://developers.google.com/classroom/reference/rest/v1/courses.courseWork.studentSubmissions/list)
## Notes
In this document, `course materials` refers to stand-alone materials, not the materials associated with
@@ -44,54 +44,60 @@ gam user user@domain.com check|update serviceaccount
By default, all types of members (cbcmbrowser, chromeosdevice, customer, group, serviceaccount, user) in the group are displayed; this option modifies that behavior:
By default, members that are groups are displayed as a single entry of type GROUP; this option recursively expands group members to display their user members.
* `recursive` - Recursively expand group members
When `recursive` is specified, the default is to only display type user members; this option modifies those behaviors:
Members that have met the above qualifications to be displayed can be further qualifed by their email address.
* `memberemaildisplaypattern <RegularExpression>` - Members with email addresses that match `<RegularExpression>` will be displayed; others will not be displayed
* `memberemailskippattern <RegularExpression>` - Members with email addresses that match `<RegularExpression>` will not be displayed; others will be displayed
* `memberemaildisplaypattern <REMatchPattern>` - Members with email addresses that match `<REMatchPattern>` will be displayed; others will not be displayed
* `memberemailskippattern <REMatchPattern>` - Members with email addresses that match `<REMatchPattern>` will not be displayed; others will be displayed
By default, the ID, role, email address, type, createTime, updateTime and expireTime of each member is displayed along with the group email address;
these options specify which fields to display:
* `<CIGroupMembersFieldName>*` - Individual field names
* `fields <CIGroupMembersFieldNameList>` - A comma separated list of field names
* `full` - Fields displayed: group, type, id, role, email, createTime, updateTime, expireTime; this is the default
By default, the group email address is always shown, you can suppress it with the `nogroupemail` option.
By default, members that are groups are displayed as a single entry of type GROUP; this option recursively expands group members to display their user members.
* `recursive` - Recursively expand group members
The `recursive` option does not expand or display members of type CUSTOMER.
The `recursive` option adds two columns, level and subgroup, to the output:
* `level` - At what level of the expansion does the user appear; level 0 is the top level
* `subgroup` - The group that contained the user
@@ -421,13 +432,13 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
By default, all types of members (cbcmbrowser, chromeosdevice, customer, group, serviceaccount, user) in the group are displayed; this option modifies that behavior:
Members that have met the above qualifications to be displayed can be further qualifed by their email address.
* `memberemaildisplaypattern <RegularExpression>` - Members with email addresses that match `<RegularExpression>` will be displayed; others will not be displayed
* `memberemailskippattern <RegularExpression>` - Members with email addresses that match `<RegularExpression>` will not be displayed; others will be displayed
* `memberemaildisplaypattern <REMatchPattern>` - Members with email addresses that match `<REMatchPattern>` will be displayed; others will not be displayed
* `memberemailskippattern <REMatchPattern>` - Members with email addresses that match `<REMatchPattern>` will not be displayed; others will be displayed
By default, members of type GROUP are recursively expanded to show their constituent members. (Members of
type CUSTOMER are not expanded.) The `depth <Number>` argument controls the depth to which nested groups are displayed.
@@ -469,6 +480,11 @@ has in any constituent group, it is not necessarily its role in the top group.
The options `types user` and `includederivedmembership types user` return the same list of users.
The `includederivedmembership` option makes less API calls but doesn't show hierarchy.
@@ -272,11 +288,19 @@ By default, all direct members, managers and owners in the group are displayed;
* `membertree` - Display all roles; expand all groups
By default, when displaying members from a group, all types of members (customer, group, serviceaccount, user) in the group are displayed; this option modifies that behavior:
By default, when listing group members, GAM does not take the domain of the member into account.
* `internal internaldomains <DomainNameList>` - Display members whose domain is in `<DomainNameList>`
* `external internaldomains <DomainNameList>` - Display members whose domain is not in `<DomainNameList>`
* `internal external internaldomains <DomainNameList>` - Display all members, indicate their category: internal or external
* `internaldomains <DomainNameList>` - Defaults to value of `domain` in `gam.cfg`
Members without an email address, e.g. `customer`, `chrome-os-device` and `cbcm-browser` are considered internal.
Members that have met the above qualifications to be displayed can be further qualifed by their email address.
* `memberemaildisplaypattern <RegularExpression>` - Members with email addresses that match `<RegularExpression>` will be displayed; others will not be displayed
* `memberemailskippattern <RegularExpression>` - Members with email addresses that match `<RegularExpression>` will not be displayed; others will be displayed
* `memberemaildisplaypattern <REMatchPattern>` - Members with email addresses that match `<REMatchPattern>` will be displayed; others will not be displayed
* `memberemailskippattern <REMatchPattern>` - Members with email addresses that match `<REMatchPattern>` will not be displayed; others will be displayed
By default, all group aliases are displayed, these options modify that behavior:
* `noaliases` or `quick` - Do not display group aliases
@@ -296,13 +320,14 @@ This command displays information in CSV format.
@@ -313,12 +338,12 @@ By default, all groups in the account are displayed, these options allow selecti
* `query <String>` - Limit display to the groups that match the query
These options further limit the list of groups selected above:
* `emailmatchpattern <RegularExpression>` - Limit display to groups whose email address matches `<RegularExpression>`
* `emailmatchpattern not <RegularExpression>` - Limit display to groups whose email address does not match `<RegularExpression>`
* `namematchpattern <RegularExpression>` - Limit display to groups whose name matches `<RegularExpression>`
* `namematchpattern not <RegularExpression>` - Limit display to groups whose name does not match `<RegularExpression>`
* `descriptionmatchpattern <RegularExpression>` - Limit display to groups whose description matches `<RegularExpression>`
* `descriptionmatchpattern not <RegularExpression>` - Limit display to groups whose description does not match `<RegularExpression>`
* `emailmatchpattern <REMatchPattern>` - Limit display to groups whose email address matches `<REMatchPattern>`
* `emailmatchpattern not <REMatchPattern>` - Limit display to groups whose email address does not match `<REMatchPattern>`
* `namematchpattern <REMatchPattern>` - Limit display to groups whose name matches `<REMatchPattern>`
* `namematchpattern not <REMatchPattern>` - Limit display to groups whose name does not match `<REMatchPattern>`
* `descriptionmatchpattern <REMatchPattern>` - Limit display to groups whose description matches `<REMatchPattern>`
* `descriptionmatchpattern not <REMatchPattern>` - Limit display to groups whose description does not match `<REMatchPattern>`
By default, GAM does not make an additional API call todisplay the member restrictions from `SecuritySettings`.
* `memberrestrictions` - Make an additional API call and display the member restrictions from `SecuritySettings`
@@ -353,11 +378,19 @@ By default, no members, managers or owners in the group are displayed; these opt
* `totalcount` - Display sum of counts of members, managers, owners.
By default, when displaying members from a group, all types of members (customer, group, serviceaccount, user) in the group are displayed; this option modifies that behavior:
By default, when listing group members, GAM does not take the domain of the member into account.
* `internal internaldomains <DomainNameList>` - Display members whose domain is in `<DomainNameList>`
* `external internaldomains <DomainNameList>` - Display members whose domain is not in `<DomainNameList>`
* `internal external internaldomains <DomainNameList>` - Display all members, indicate their category: internal or external
* `internaldomains <DomainNameList>` - Defaults to value of `domain` in `gam.cfg`
Members without an email address, e.g. `customer`, `chrome-os-device` and `cbcm-browser` are considered internal.
Members that have met the above qualifications to be displayed can be further qualifed by their email address.
* `memberemaildisplaypattern <RegularExpression>` - Members with email addresses that match `<RegularExpression>` will be displayed; others will not be displayed
* `memberemailskippattern <RegularExpression>` - Members with email addresses that match `<RegularExpression>` will not be displayed; others will be displayed
* `memberemaildisplaypattern <REMatchPattern>` - Members with email addresses that match `<REMatchPattern>` will be displayed; others will not be displayed
* `memberemailskippattern <REMatchPattern>` - Members with email addresses that match `<REMatchPattern>` will not be displayed; others will be displayed
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.
@@ -368,6 +401,37 @@ 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.
* `filter <String>` - Display filtered policies, See https://cloud.google.com/identity/docs/reference/rest/v1beta1/policies/list
* `group <REMatchPattern>` - Only display policies whose group email address matches the `<REMatchPattern>`
* `ou|org|orgunit <REMatchPattern>` - Only display policies whose OU path matches the `<REMatchPattern>`
By default, policy warnings are displayed, use the `nowarnings` option to suppress their display.
By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist`
to get the application name for the application ID. Use option `noappnames` to suppress these calls.
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.
* `<FileName>(:<FieldName>)+` - A CSV file and the one or more columns that contain ChromeOS deviceIds
@@ -280,7 +277,7 @@ croscsvfile
* `quotechar <Character>` - The column quote characer is `<Character>`; if not specified, the value of `csv_input_quote_char` from `gam.cfg` will be used
* `endcsv` - Use this option to signal the end of the csvfile parameters in the case that the next argument on the command line is `fields` but is specifying the output field list for the command not column headings
* `fields <FieldNameList>` - The column headings of a CSV file that does not contain column headings
* `(matchfield|skipfield <FieldName> <RegularExpression>)*` - The criteria to select rows from the CSV file; can be used multiple times; if not specified, all rows are selected
* `(matchfield|skipfield <FieldName> <RESearchPattern>)*` - The criteria to select rows from the CSV file; can be used multiple times; if not specified, all rows are selected
* `delimiter <Character>` - There are multiple deviceIds per column separated by `<Character>`; if not specified, there is single deviceId per column
## Selected ChromeOS serial numbers in a CSV file/Google Sheet/Google Doc/Google Cloud Storage Object
* `<FileName>(:<FieldName>)+` - A CSV file and the one or more columns that contain ChromeOS serial numbers
@@ -308,7 +305,7 @@ croscsvfile_sn
* `quotechar <Character>` - The column quote characer is `<Character>`; if not specified, the value of `csv_input_quote_char` from `gam.cfg` will be used
* `endcsv` - Use this option to signal the end of the csvfile parameters in the case that the next argument on the command line is `fields` but is specifying the output field list for the command not column headings
* `fields <FieldNameList>` - The column headings of a CSV file that does not contain column headings
* `(matchfield|skipfield <FieldName> <RegularExpression>)*` - The criteria to select rows from the CSV file; can be used multiple times; if not specified, all rows are selected
* `(matchfield|skipfield <FieldName> <RESearchPattern>)*` - The criteria to select rows from the CSV file; can be used multiple times; if not specified, all rows are selected
* `delimiter <Character>` - There are multiple serial numbers per column separated by `<Character>`; if not specified, there is single deviceId per column
## ChromeOS devices from OUs in a flat file/Google Doc/Google Cloud Storage Object
* `cros|cros_ous|cros_ous_and_children` - The type of item in the file
@@ -354,7 +351,7 @@ csvdatafile
* `quotechar <Character>` - The column quote characer is `<Character>`; if not specified, the value of `csv_input_quote_char` from `gam.cfg` will be used
* `endcsv` - Use this option to signal the end of the csvfile parameters in the case that the next argument on the command line is `fields` but is specifying the output field list for the command not column headings
* `fields <FieldNameList>` - The column headings of a CSV file that does not contain column headings
* `(matchfield|skipfield <FieldName> <RegularExpression>)*` - The criteria to select rows from the CSV file; can be used multiple times; if not specified, all rows are selected
* `(matchfield|skipfield <FieldName> <RESearchPattern>)*` - The criteria to select rows from the CSV file; can be used multiple times; if not specified, all rows are selected
* `delimiter <Character>` - There are multiple deviceIds per column separated by `<Character>`; if not specified, there is single deviceId per column
## ChromeOS devices directly in or from OUs in a CSV file/Google Sheet/Google Doc/Google Cloud Storage Object
* `cros|cros_sn|cros_ous|cros_ous_and_children` - The type of item in the file
@@ -383,15 +380,15 @@ csvkmd
* `quotechar <Character>` - The column quote characer is `<Character>`; if not specified, the value of `csv_input_quote_char` from `gam.cfg` will be used
* `endcsv` - Use this option to signal the end of the csvfile parameters in the case that the next argument on the command line is `fields` but is specifying the output field list for the command not column headings
* `fields <FieldNameList>` - The column headings of a CSV file that does not contain column headings
* `keyfield <FieldName>` - The column containing key values
* `[keypattern <RegularExpression>] [keyvalue <String>]` - Allows transforming the value(s) in the `keyfield` column. If only `keyvalue <String>` is specified, all instances of `<FieldName>` in `keyvalue <String>` will be replaced by the item value. If `keypattern <RegularExpression>` is specified, the item value is matched against `<RegularExpression>` and the matched segments are substituted into `keyvalue <String>`
* `[keypattern <RESearchPattern>] [keyvalue <RESubstitution>]` - Allows transforming the value(s) in the `keyfield` column. If only `keyvalue <RESubstitution>` is specified, all instances of `<FieldName>` in `keyvalue <RESubstitution>` will be replaced by the item value. If `keypattern <RESearchPattern>` is specified, the item value is matched against `<RESearchPattern>` and the matched segments are substituted into `keyvalue <RESubstitution>`
* `delimiter <Character>` - There are multiple values per keyfield column separated by `<Character>`; if not specified, there is single value per keyfield column
* `subkeyfield <FieldName>` - The column containing subkey values
* `[keypattern <RegularExpression>] [keyvalue <String>]` - Allows transforming the value(s) in the `subkeyfield` column. If only `keyvalue <String>` is specified, all instances of `<FieldName>` in `keyvalue <String>` will be replaced by the item value. If `keypattern <RegularExpression>` is specified, the item value is matched against `<RegularExpression>` and the matched segments are substituted into `keyvalue <String>`
* `[keypattern <RESearchPattern>] [keyvalue <RESubstitution>]` - Allows transforming the value(s) in the `subkeyfield` column. If only `keyvalue <RESubstitution>` is specified, all instances of `<FieldName>` in `keyvalue <RESubstitution>` will be replaced by the item value. If `keypattern <RESearchPattern>` is specified, the item value is matched against `<RESearchPattern>` and the matched segments are substituted into `keyvalue <RESubstitution>`
* `delimiter <Character>` - There are multiple values per subkeyfield column separated by `<Character>`; if not specified, there is single value per subkeyfield column
* `(matchfield|skipfield <FieldName> <RegularExpression>)*` - The criteria to select rows from the CSV file; can be used multiple times; if not specified, all rows are selected
* `(matchfield|skipfield <FieldName> <RESearchPattern>)*` - The criteria to select rows from the CSV file; can be used multiple times; if not specified, all rows are selected
* `datafield <FieldName>(:<FieldName)*` - The column(s) containing data values
* `delimiter <Character>` - There are multiple values per datafield column separated by `<Character>`; if not specified, there is single value per datafield column
* `<FileName>(:<FieldName>)+` - A CSV file and the one or more columns that contain Items
@@ -79,7 +79,7 @@ A CSV file with one or more columns per row that contain Items.
* `quotechar <Character>` - The column quote characer is `<Character>`; if not specified, the value of `csv_input_quote_char` from `gam.cfg` will be used
* `endcsv` - Use this option to signal the end of the csvfile parameters in the case that the next argument on the command line is `fields` but is specifying the output field list for the command not column headings
* `fields <FieldNameList>` - The column headings of a CSV file that does not contain column headings
* `(matchfield|skipfield <FieldName> <RegularExpression>)*` - The criteria to select rows from the CSV file; can be used multiple times; if not specified, all rows are selected
* `(matchfield|skipfield <FieldName> <RESearchPattern>)*` - The criteria to select rows from the CSV file; can be used multiple times; if not specified, all rows are selected
* `delimiter <Character>` - There are multiple Items per column separated by `<Character>`; if not specified, there is single item per column
## CSVkmdSelector
@@ -92,9 +92,9 @@ A CSV file with a key column that contains an Item and optional subkey and data
* `<FileName>` - A CSV file containing rows with columns of items
@@ -107,15 +107,15 @@ A CSV file with a key column that contains an Item and optional subkey and data
* `quotechar <Character>` - The column quote characer is `<Character>`; if not specified, the value of `csv_input_quote_char` from `gam.cfg` will be used
* `endcsv` - Use this option to signal the end of the csvfile parameters in the case that the next argument on the command line is `fields` but is specifying the output field list for the command not column headings
* `fields <FieldNameList>` - The column headings of a CSV file that does not contain column headings
* `keyfield <FieldName>` - The column containing key values
* `[keypattern <RegularExpression>] [keyvalue <String>]` - Allows transforming the value(s) in the `keyfield` column. If only `keyvalue <String>` is specified, all instances of `<FieldName>` in `keyvalue <String>` will be replaced by the item value. If `keypattern <RegularExpression>` is specified, the item value is matched against `<RegularExpression>` and the matched segments are substituted into `keyvalue <String>`
* `[keypattern <RESearchPattern>] [keyvalue <RESubstitution>]` - Allows transforming the value(s) in the `keyfield` column. If only `keyvalue <RESubstitution>` is specified, all instances of `<FieldName>` in `keyvalue <RESubstitution>` will be replaced by the item value. If `keypattern <RESearchPattern>` is specified, the item value is matched against `<RESearchPattern>` and the matched segments are substituted into `keyvalue <RESubstitution>`
* `delimiter <Character>` - There are multiple values per keyfield column separated by `<Character>`; if not specified, there is single value per keyfield column
* `subkeyfield <FieldName>` - The column containing subkey values
* `[keypattern <RegularExpression>] [keyvalue <String>]` - Allows transforming the value(s) in the `subkeyfield` column. If only `keyvalue <String>` is specified, all instances of `<FieldName>` in `keyvalue <String>` will be replaced by the item value. If `keypattern <RegularExpression>` is specified, the item value is matched against `<RegularExpression>` and the matched segments are substituted into `keyvalue <String>`
* `[keypattern <RESearchPattern>] [keyvalue <RESubstitution>]` - Allows transforming the value(s) in the `subkeyfield` column. If only `keyvalue <RESubstitution>` is specified, all instances of `<FieldName>` in `keyvalue <RESubstitution>` will be replaced by the item value. If `keypattern <RESearchPattern>` is specified, the item value is matched against `<RESearchPattern>` and the matched segments are substituted into `keyvalue <RESubstitution>`
* `delimiter <Character>` - There are multiple values per subkeyfield column separated by `<Character>`; if not specified, there is single value per subkeyfield column
* `(matchfield|skipfield <FieldName> <RegularExpression>)*` - The criteria to select rows from the CSV file; can be used multiple times; if not specified, all rows are selected
* `(matchfield|skipfield <FieldName> <RESearchPattern>)*` - The criteria to select rows from the CSV file; can be used multiple times; if not specified, all rows are selected
* `datafield <FieldName>(:<FieldName)*` - The column(s) containing data values
* `delimiter <Character>` - There are multiple values per datafield column separated by `<Character>`; if not specified, there is single value per datafield column
@@ -144,6 +144,12 @@ Data fields identified in a `csvkmd` argument.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.