Compare commits

...

45 Commits

Author SHA1 Message Date
Ross Scroggs
3c09743f34 Updated gam delete chromepolicy to delete apps 2025-12-04 12:39:47 -08:00
Ross Scroggs
1dab9633aa Remove debugging message from gam <UserTypeEntity> move drivefile <DriveFileEntity>.
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-12-03 07:13:44 -08:00
Ross Scroggs
57222b1a77 Remove debugging message from gam <UserTypeEntity> move drivefile <DriveFileEntity>. 2025-12-03 07:13:35 -08:00
Ross Scroggs
b54fef185c Fixed bug in gam <UserTypeEntity> move drivefile <DriveFileEntity>
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-12-02 17:11:18 -08:00
Ross Scroggs
c36a71fe9e Fixed bug in gam <UserTypeEntity> move drivefile <DriveFileEntity> 2025-12-02 16:25:56 -08:00
Jay Lee
3491bd2286 actions: rebuild for Python 3.14.1
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
2025-12-02 16:24:50 -05:00
Ross Scroggs
36bc8837a7 Update Classroom-Courses.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
2025-12-01 07:11:07 -08:00
Fernando Fernández
395e01c1c9 Fix link in bug report template (#1864)
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-11-30 06:19:41 -05:00
Ross Scroggs
b6528c4bf5 Improve copy shareddriveacls documentation
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
2025-11-27 08:21:22 -08:00
Ross Scroggs
d361825165 Update GamUpdates.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-11-26 12:15:49 -08:00
Ross Scroggs
17bc6c9f44 Added option oneitemperrow to gam <UserTypeEntity> print calendars ... permissions 2025-11-26 11:44:21 -08:00
Ross Scroggs
4058399672 Added option oneitemperrow to gam <UserTypeEntity> print calendars ... permissions 2025-11-26 11:40:54 -08:00
Ross Scroggs
e9c11f8b8d Added option oneitemperrow to gam <UserTypeEntity> print calendars ... permissions 2025-11-26 11:40:08 -08:00
Jay Lee
a08865b0cd Merge branch 'main' of https://github.com/gam-team/gam
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-11-26 12:15:08 -05:00
Jay Lee
8782865da4 Yubikey updates. Fixes #1862 2025-11-26 12:14:59 -05:00
Jay Lee
8d79fdfe24 Wiki: Revise setup steps for GAM7 with YubiKey
Updated the setup steps for using GAM7 with a YubiKey, including formatting changes and clarifications on preserving PIV app data.
2025-11-26 11:42:43 -05:00
Ross Scroggs
d86be2014c Update <CSVFileInput> documentation
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
2025-11-25 11:40:55 -08:00
Ross Scroggs
700bdfe8f8 Update Users-Shared-Drives.md 2025-11-25 11:20:49 -08:00
Ross Scroggs
0c50f4a794 Added options mappermissionsemail and mappermissionsemailfile 2025-11-25 10:44:44 -08:00
Ross Scroggs
5cf154d70b Added options mappermissionsemail and mappermissionsemailfile
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
2025-11-25 09:51:15 -08:00
Ross Scroggs
a13101ca8a Added option addcsvdata <FieldName> <String> to gam <UserTypeEntity> print messages
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-11-24 10:31:44 -08:00
Ross Scroggs
1c8a3a3c57 Added option addcsvdata <FieldName> <String> to gam <UserTypeEntity> print messages 2025-11-24 10:30:18 -08:00
Ross Scroggs
4fc4a21909 Update Users-Gmail-Messages-Threads.md 2025-11-24 09:41:11 -08:00
Ross Scroggs
061fead29e Updated gam delete project to handle the following error:
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
```
ERROR: 400: failedPrecondition - Project not active
```
2025-11-21 16:25:52 -08:00
Ross Scroggs
36887ba658 Updated gam delete project to handle the following error:
```
ERROR: 400: failedPrecondition - Project not active
```
2025-11-21 16:25:31 -08:00
Ross Scroggs
cecd9dc7ae Update Authorization.md 2025-11-21 16:15:52 -08:00
Ross Scroggs
4a952cbd16 Update gam.cfg.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
2025-11-20 08:33:04 -08:00
Ross Scroggs
624ed5f57c Update Users-Drive-Permissions.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-11-19 18:14:37 -08:00
Ross Scroggs
0925ff8bd4 Update Users-Drive-Permissions.md 2025-11-19 18:12:51 -08:00
Ross Scroggs
2aecfc24dc Removed inheritance from gam create|update|info|print org 2025-11-19 17:49:34 -08:00
Ross Scroggs
d5d17676cc Removed inheritance from gam create|update|info|print org 2025-11-19 17:09:13 -08:00
Ross Scroggs
aa62ac4f3c Update Organizational-Units.md 2025-11-19 16:47:14 -08:00
Ross Scroggs
e555e5440d Added a command gam print course-counts
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-11-19 13:52:54 -08:00
Ross Scroggs
122f5c3c0d Added a command gam print course-counts 2025-11-19 13:23:26 -08:00
Ross Scroggs
4423a1ed0b Added a command gam print course-counts 2025-11-19 12:50:05 -08:00
Ross Scroggs
e0f8789a8a Fixed bug in gam print cigroups ... descriptionmatchpattern [not] <REMatchPattern> 2025-11-19 09:25:02 -08:00
Ross Scroggs
944e2ed5f4 Fixed bug in gam print cigroups ... descriptionmatchpattern [not] <REMatchPattern> 2025-11-19 09:24:45 -08:00
Ross Scroggs
0e7c3bee6a Update Classroom-Membership.md 2025-11-19 08:41:25 -08:00
Ross Scroggs
86e827ee66 Update Classroom-Membership.md 2025-11-19 08:13:49 -08:00
Ross Scroggs
3491267f9d Update Reports.md 2025-11-19 07:29:28 -08:00
Ross Scroggs
4b97accc21 Updated gam <UserTypeEntity> print|show chatmessages to improve performance
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-11-18 13:59:41 -08:00
Ross Scroggs
44daf499b1 Updated gam <UserTypeEntity> print|show chatmessages to improve performance
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
2025-11-18 13:59:28 -08:00
Ross Scroggs
d5ac0b6b8a Update gam.cfg.md 2025-11-18 09:28:32 -08:00
Ross Scroggs
ce1697baff Update Other-Resources.md
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
2025-11-17 08:44:11 -08:00
Ross Scroggs
10350fbe2e Update GamUpdates.md
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-11-15 09:56:41 -08:00
26 changed files with 672 additions and 173 deletions

View File

@@ -11,7 +11,7 @@ The issue tracker is for reporting product deficiencies. "How do I?" questions s
Please confirm the following:
* I have upgraded to the latest GAM release from https://github.com/GAM-team/GAM/releases and I still have this issue.
* I am typing the command as described in the GAM Wiki at https://github.com/jay0lee/gam/wiki
* I am typing the command as described in the GAM Wiki at https://github.com/GAM-team/GAM/wiki.
Full steps to reproduce the issue:
1.

View File

@@ -153,7 +153,7 @@ jobs:
with:
path: |
cache.tar.xz
key: gam-${{ matrix.jid }}-20251031
key: gam-${{ matrix.jid }}-20251202
- name: Untar Cache archive
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true'

View File

@@ -3268,6 +3268,11 @@ gam print course-participants [todrive <ToDriveAttribute>*]
[formatjson [quotechar <Character>]]
[showitemcountonly]
gam print course-counts students|teachers [todrive <ToDriveAttribute>*]
(course|class <CourseEntity>)*|([teacher <UserItem>] [student <UserItem>] [states <CourseStateList>])
[mincount <Integer>]
[formatjson [quotechar <Character>]]
<CourseAnnouncementFieldName> ::=
alternatelink|
assigneemode|
@@ -4446,22 +4451,21 @@ gam print mobile [todrive <ToDriveAttribute>*]
<OrgUnitFieldName> ::=
description|
id|orgunitid|
inherit|blockinheritance|
name|
parentid|parentorgunitid|
parent|parentorgunitpath|
path|orgunitpath
<OrgUnitFieldNameList> ::= "<OrgUnitFieldName>(,<OrgUnitFieldName>)*"
gam create|add org|ou <OrgUnitPath> [description <String>] [parent <OrgUnitItem>] [inherit|(blockinheritance False)] [buildpath]
gam update org|ou <OrgUnitItem> [name <String>] [description <String>] [parent <OrgUnitItem>] [inherit|(blockinheritance False)]
gam create|add org|ou <OrgUnitPath> [description <String>] [parent <OrgUnitItem>] [buildpath]
gam update org|ou <OrgUnitItem> [name <String>] [description <String>] [parent <OrgUnitItem>]
gam update org|ou <OrgUnitItem> add|move <CrOSTypeEntity> [quickcrosmove [<Boolean>]]
gam update org|ou <OrgUnitItem> add|move <UserTypeEntity>
gam update org|ou <OrgUnitItem> sync <CrOSTypeEntity> [removetoou <OrgUnitItem>] [quickcrosmove [<Boolean>]]
gam update org|ou <OrgUnitItem> sync <UserTypeEntity> [removetoou <OrgUnitItem>]
gam delete org|ou <OrgUnitItem>
gam update orgs|ous <OrgUnitEntity> [name <String>] [description <String>] [parent <OrgUnitItem>] [inherit|(blockinheritance False)]
gam update orgs|ous <OrgUnitEntity> [name <String>] [description <String>] [parent <OrgUnitItem>]
gam update orgs|ous <OrgUnitEntity> add|move <CrOSTypeEntity> [quickcrosmove [<Boolean>]]
gam update orgs|ous <OrgUnitEntity> add|move <UserTypeEntity>
gam update orgs|ous <OrgUnitEntity> sync <CrOSTypeEntity> [removetoou <OrgUnitItem>] [quickcrosmove [<Boolean>]]
@@ -5181,11 +5185,13 @@ gam copy shareddriveacls <SharedDriveEntity> to <SharedDriveEntity>
[adminaccess|asadmin]
[showpermissionsmessages [<Boolean>]]
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
(mappermissionsemail <EmailAddress> <EmailAddress>)* [mappermissionsemailfile <CSVFileInput> endcsv]
(mappermissionsdomain <DomainName> <DomainName>)*
gam sync shareddriveacls <SharedDriveEntity> with <SharedDriveEntity>
[adminaccess|asadmin]
[showpermissionsmessages [<Boolean>]]
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
(mappermissionsemail <EmailAddress> <EmailAddress>)* [mappermissionsemailfile <CSVFileInput> endcsv]
(mappermissionsdomain <DomainName> <DomainName>)*
gam print shareddriveacls [todrive <ToDriveAttribute>*]
@@ -5210,11 +5216,13 @@ gam <UserTypeEntity> copy shareddriveacls <SharedDriveEntity> to <SharedDriveEnt
[adminaccess|asadmin]
[showpermissionsmessages [<Boolean>]]
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
(mappermissionsemail <EmailAddress> <EmailAddress>)* [mappermissionsemailfile <CSVFileInput> endcsv]
(mappermissionsdomain <DomainName> <DomainName>)*
gam <UserTypeEntity> sync shareddriveacls <SharedDriveEntity> with <SharedDriveEntity>
[adminaccess|asadmin]
[showpermissionsmessages [<Boolean>]]
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
(mappermissionsemail <EmailAddress> <EmailAddress>)* [mappermissionsemailfile <CSVFileInput> endcsv]
(mappermissionsdomain <DomainName> <DomainName>)*
gam <UserTypeEntity> print shareddriveacls [todrive <ToDriveAttribute>*]
@@ -6088,7 +6096,7 @@ gam <UserTypeEntity> show calendars
[formatjson]
gam <UserTypeEntity> print calendars [todrive <ToDriveAttribute>*]
[primary] <CalendarSelectProperty>* [noprimary] [nogroups] [noresources] [nosystem] [nousers]
[fields <CalendarListFieldList>] [permissions]
[fields <CalendarListFieldList>] [permissions] [oneitemperrow]
[formatjson] [delimiter <Character>] [quotechar <Character>]
Display a users calendar settings
@@ -6305,7 +6313,7 @@ gam <UserTypeEntity> print events <UserCalendarEntity> [<EventEntity>] <EventDis
gam <UserTypeEntity> update calattendees <UserCalendarEntity> <EventEntity> [anyorganizer]
[<EventNotificationAttribute>] [splitupdate] [dryrun|doit]
(csv|csvfile <CSVFileInput>)
(csv|csvfile <CSVFileInput> endcsv)
(delete <EmailAddress>)*
(deleteentity <EmailAddressEntity>)*
(add <EmailAddress>)*
@@ -6804,6 +6812,7 @@ gam <UserTypeEntity> copy drivefile <DriveFileEntity>
[copypermissionroles <DriveFileACLRoleList>]
[copypermissiontypes <DriveFileACLTypeList>]
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
(mappermissionsemail <EmailAddress> <EmailAddress>)* [mappermissionsemailfile <CSVFileInput> endcsv]
(mappermissionsdomain <DomainName> <DomainName>)*
[copysheetprotectedranges [<Boolean>]]
[copysheetprotectedrangesinheritedpermissions [<Boolean>]]
@@ -6830,8 +6839,8 @@ gam <UserTypeEntity> move drivefile <DriveFileEntity> [newfilename <DriveFileNam
[copysubfolderinheritedpermissions [<Boolean>]]
[copysubfoldernoniheritedpermissions never|always|syncallfolders|syncupdatedfolders]
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
(mappermissionsemail <EmailAddress> <EmailAddress>)* [mappermissionsemailfile <CSVFileInput> endcsv]
(mappermissionsdomain <DomainName> <DomainName>)*
[updatefilepermissions [<Boolean>]]
[retainsourcefolders [<Boolean>]]
[sendemailifrequired [<Boolean>]]
[verifyorganizer [<Boolean>]]
@@ -7873,9 +7882,9 @@ gam <UserTypeEntity> show messages|threads
[labelids <LabelIDList>]
[quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <MessageIDEntity>)
[labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
[countsonly|positivecountsonly] [useronly]
[countsonly|positivecountsonly]
[headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
[showlabels] [delimiter <Character>] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
[showlabels] [useronly] [delimiter <Character>] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
[maxmessagesperthread <Number>]
[[attachmentnamepattern <REMatchPattern>]
[showattachments [noshowtextplain]]
@@ -7886,9 +7895,9 @@ gam <UserTypeEntity> print messages|threads [todrive <ToDriveAttribute>*]
[labelids <LabelIDList>]
[quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <MessageIDEntity>)
[labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
[countsonly|positivecountsonly] [useronly]
[countsonly|positivecountsonly]
[headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String> [dateheaderconverttimezone [<Boolean>]]]
[showlabels] [delimiter <Character>] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
[showlabels] [useronly] [delimiter <Character>] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
[maxmessagesperthread <Number>]
[convertcrnl] [delimiter <Character>]
[[attachmentnamepattern <REMatchPattern>]

View File

@@ -1,6 +1,86 @@
7.29.04
Updated `gam delete chromepolicy chrome.users.apps.InstallType ou <OrgUnitItem> appid <AppID>`
to allow deleting an app, i.e., explicitly remove it from management. `<OrgUnitItem>` must specify where it was added for management.
7.29.03
Remove debugging message from `gam <UserTypeEntity> move drivefile <DriveFileEntity>`.
7.29.02
Fixed bug in `gam <UserTypeEntity> move drivefile <DriveFileEntity>` where the following options
were only applied to top level files or folders re-created in the destination. Now, domain
and email address mappings apply to all moved files/folders.
```
excludepermissionsfromdomains <DomainNameList>
includepermissionsfromdomains <DomainNameList>
mappermissionsdomain <DomainName> <DomainName>
mappermissionsemail <EmailAddress> <EmailAddress>
mappermissionsemailfile <CSVFileInput> endcsv
```
Upgraded to Python 3.14.1.
7.29.01
Added option `oneitemperrow` to `gam <UserTypeEntity> print calendars ... permissions` to have each of a
calendar's permissions displayed on a separate row with all of the other calendar fields.
Updated `gam yubikey reset_piv` to handle YubiKey firmware updates that caused an error.
7.29.00
Added options `mappermissionsemail <EmailAddress> <EmailAddress>` and ` mappermissionsemailfile <CSVFileInput> endcsv`
to these commands:
```
gam [<UserTypeEntity>] copy shareddriveacls <SharedDriveEntity> to <SharedDriveEntity>
gam [<UserTypeEntity>] sync shareddriveacls <SharedDriveEntity> with <SharedDriveEntity>
gam <UserTypeEntity> copy drivefile <DriveFileEntity>
gam <UserTypeEntity> move drivefile <DriveFileEntity>
```
When `mappermissionsemail <EmailAddress> <EmailAddress>` is specifed, an ACL that references the first `<EmailAddress>`
in the source will be modified to reference the second `<EmailAddress>` in the destination.
Bulk permission email address mapping can be specified with `mappermissionsemailfile <CSVFileInput> endcsv`.
`<CSVFileInput>` must include these columns: `sourceEmail` and `destinationEmail`.
These options will be most useful with inter-workspace Shared Drive copies and moves.
7.28.13
Added option `addcsvdata <FieldName> <String>` to `gam <UserTypeEntity> print messages`
that adds additional columns of data to the CSV file output.
7.28.12
Updated `gam delete project` to handle the following error:
```
ERROR: 400: failedPrecondition - Project not active
```
7.28.11
Removed all options/fields referencing inheritance from `gam create|update|info|print org` as this option/field is deprecated.
7.28.10
Added a command `gam print course-counts` that dsplays the count of the number of courses in which a teacher or student is a participant.
* See: https://github.com/GAM-team/GAM/wiki/Classroom-Membership#display-course-counts-for-teachers-students
7.28.09
Fixed bug in `gam print cigroups ... descriptionmatchpattern [not] <REMatchPattern>` that caused a trap.
7.28.08
Updated `gam <UserTypeEntity> print|show chatmessages` to cache the sender UID to email address
map so that each sender UID only has to be looked up once; this improves performance.
7.28.07
Fixed bug in 'gam report users ... aggregatebydate|aggregatebyuser` where `accounts:used_quota_in_percentage` was incorrectly displayed.
Fixed bug in `gam report users ... aggregatebydate|aggregatebyuser` where `accounts:used_quota_in_percentage` was incorrectly displayed.
7.28.06
@@ -17315,7 +17395,7 @@ Current version of Gam with drive_v3_name_names = false
Owner,title,parents,parents.0.id,parents.1.id
testuser@domain.com,TestFile,2,PPPP1111,PPPP2222
Current version of Gam with drive_v3_name_names = true
Current version of Gam with drive_v3_name_names = true
Owner,name,parents
testuser@domain.com,TestFile,PPPP1111 PPPP2222

View File

@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
"""
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
__version__ = '7.28.07'
__version__ = '7.29.04'
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
#pylint: disable=wrong-import-position
@@ -12068,10 +12068,10 @@ def doDeleteProject():
projectId = project['projectId']
try:
callGAPI(crm.projects(), 'delete',
throwReasons=[GAPI.FORBIDDEN, GAPI.PERMISSION_DENIED],
throwReasons=[GAPI.FORBIDDEN, GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
name=project['name'])
entityActionPerformed([Ent.PROJECT, projectId])
except (GAPI.forbidden, GAPI.permissionDenied) as e:
except (GAPI.forbidden, GAPI.permissionDenied, GAPI.failedPrecondition) as e:
entityActionFailedWarning([Ent.PROJECT, projectId], str(e))
Ind.Decrement()
@@ -17603,23 +17603,7 @@ def doShowTransferApps():
Ind.Decrement()
Ind.Decrement()
def _getOrgInheritance(myarg, body):
if myarg == 'noinherit':
Cmd.Backup()
deprecatedArgumentExit(myarg)
elif myarg == 'inherit':
body['blockInheritance'] = False
elif myarg in {'blockinheritance', 'inheritanceblocked'}:
location = Cmd.Location()-1
if getBoolean():
Cmd.SetLocation(location)
deprecatedArgumentExit(myarg)
body['blockInheritance'] = False
else:
return False
return True
# gam create org|ou <String> [description <String>] [parent <OrgUnitItem>] [inherit|(blockinheritance False)] [buildpath]
# gam create org|ou <String> [description <String>] [parent <OrgUnitItem>] [buildpath]
def doCreateOrg():
def _createOrg(body, parentPath, fullPath):
@@ -17648,8 +17632,6 @@ def doCreateOrg():
body['description'] = getStringWithCRsNLs()
elif myarg == 'parent':
parent = getOrgUnitItem()
elif _getOrgInheritance(myarg, body):
pass
elif myarg == 'buildpath':
buildPath = True
else:
@@ -17933,8 +17915,6 @@ def _doUpdateOrgs(entityList):
body['parentOrgUnitId'] = parent
else:
body['parentOrgUnitPath'] = parent
elif _getOrgInheritance(myarg, body):
pass
else:
unknownArgumentExit()
i = 0
@@ -17956,7 +17936,7 @@ def _doUpdateOrgs(entityList):
except (GAPI.badRequest, GAPI.invalidCustomerId, GAPI.loginRequired):
checkEntityAFDNEorAccessErrorExit(cd, Ent.ORGANIZATIONAL_UNIT, orgUnitPath)
# gam update orgs|ous <OrgUnitEntity> [name <String>] [description <String>] [parent <OrgUnitItem>] [inherit|(blockinheritance False)]
# gam update orgs|ous <OrgUnitEntity> [name <String>] [description <String>] [parent <OrgUnitItem>]
# gam update orgs|ous <OrgUnitEntity> add|move <CrosTypeEntity> [quickcrosmove [<Boolean>]]
# gam update orgs|ous <OrgUnitEntity> add|move <UserTypeEntity>
# gam update orgs|ous <OrgUnitEntity> sync <CrosTypeEntity> [removetoou <OrgUnitItem>] [quickcrosmove [<Boolean>]]
@@ -17964,7 +17944,7 @@ def _doUpdateOrgs(entityList):
def doUpdateOrgs():
_doUpdateOrgs(getEntityList(Cmd.OB_ORGUNIT_ENTITY, shlexSplit=True))
# gam update org|ou <OrgUnitItem> [name <String>] [description <String>] [parent <OrgUnitItem>] [inherit|(blockinheritance False)]
# gam update org|ou <OrgUnitItem> [name <String>] [description <String>] [parent <OrgUnitItem>]
# gam update org|ou <OrgUnitItem> add|move <CrosTypeEntity> [quickcrosmove [<Boolean>]]
# gam update org|ou <OrgUnitItem> add|move <UserTypeEntity>
# gam update org|ou <OrgUnitItem> sync <CrosTypeEntity> [removetoou <OrgUnitItem>] [quickcrosmove [<Boolean>]]
@@ -18096,9 +18076,6 @@ def doInfoOrgs():
_doInfoOrgs(getEntityList(Cmd.OB_ORGUNIT_ENTITY, shlexSplit=True))
ORG_ARGUMENT_TO_FIELD_MAP = {
'blockinheritance': 'blockInheritance',
'inheritanceblocked': 'blockInheritance',
'inherit': 'blockInheritance',
'description': 'description',
'id': 'orgUnitId',
'name': 'name',
@@ -28051,10 +28028,14 @@ def printShowChatMembers(users):
def doPrintShowChatMembers():
printShowChatMembers([None])
def _getChatSenderEmail(cd, sender):
def _getChatSenderEmail(cd, sender, chatSenders):
if sender['type'] == 'HUMAN':
_, senderUid = sender['name'].split('/')
sender['email'], _ = convertUIDtoEmailAddressWithType(f'uid:{senderUid}', cd, None, emailTypes=['user'])
if senderUid in chatSenders:
sender['email'] = chatSenders[senderUid]
else:
sender['email'], _ = convertUIDtoEmailAddressWithType(f'uid:{senderUid}', cd, None, emailTypes=['user'])
chatSenders[senderUid] = sender['email']
def trimChatMessageIfRequired(body):
if 'text' in body:
@@ -28269,6 +28250,7 @@ def infoChatMessage(users):
FJQC.GetFormatJSON(myarg)
if not name:
missingArgumentExit('name')
chatSenders = {}
fields = getFieldsFromFieldsList(fieldsList)
i, count, users = getEntityArgument(users)
for user in users:
@@ -28280,7 +28262,7 @@ def infoChatMessage(users):
message = callGAPI(chat.spaces().messages(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
name=name, fields=fields)
_getChatSenderEmail(cd, message['sender'])
_getChatSenderEmail(cd, message['sender'], chatSenders)
if not FJQC.formatJSON:
entityPerformAction(kvList, i, count)
Ind.Increment()
@@ -28328,6 +28310,7 @@ def printShowChatMessages(users):
FJQC.GetFormatJSONQuoteChar(myarg, True)
if not parentList:
missingArgumentExit('space')
chatSenders = {}
fields = getItemFieldsFromFieldsList('messages', fieldsList)
i, count, users = getEntityArgument(users)
for user in users:
@@ -28361,7 +28344,7 @@ def printShowChatMessages(users):
fields=fields)
for message in messages:
if 'sender' in message:
_getChatSenderEmail(cd, message['sender'])
_getChatSenderEmail(cd, message['sender'], chatSenders)
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
continue
@@ -29136,6 +29119,25 @@ def doDeleteChromePolicy():
return
kvList = setPolicyKVList([entityType, targetName, Ent.CHROME_POLICY, ','.join(schemaNameList)], printer_id, app_id)
updatePolicyRequests(body, targetResource, printer_id, app_id)
if orgUnit and app_id:
for request in body['requests']:
if request['policySchema'] == 'chrome.users.apps.InstallType':
# Deleting an app must be done at the Organizational Unit at which the app was explicitly added for management.
# When calling resolve, the field addedSourceKey contains the Organization Unit where it was added for management.
# In other words, delete should only be called for apps where the Organizational Unit in addedSourceKey is equal to the one in policyTargetKey.
# In order to delete an app (explicitly remove it from management) you should send a batchInherit request in which
# the policySchema is the schema for the given app type, with an asterisk (*) in place of a specific policy.
try:
result = callGAPI(cp.customers().policies(), 'resolve', 'resolvedPolicies',
throwReasons=[GAPI.NOT_FOUND, GAPI.PERMISSION_DENIED, GAPI.INVALID_ARGUMENT,
GAPI.SERVICE_NOT_AVAILABLE, GAPI.QUOTA_EXCEEDED],
customer=customer, body={'policySchemaFilter': request['policySchema'], 'policyTargetKey': request['policyTargetKey']})
if result:
policy = result['resolvedPolicies'][0]
if request['policyTargetKey']['targetResource'] == policy['addedSourceKey'].get('targetResource', ''):
request['policySchema'] = 'chrome.users.apps.*'
except (GAPI.notFound, GAPI.permissionDenied, GAPI.invalidArgument, GAPI.serviceNotAvailable, GAPI.quotaExceeded) as e:
continue
try:
callGAPI(service, function,
throwReasons=[GAPI.NOT_FOUND, GAPI.PERMISSION_DENIED,
@@ -34694,10 +34696,10 @@ def checkGroupMatchPatterns(groupEmail, group, matchPatterns):
return False
else: # field in {'name', 'displayName', 'description'}:
if not matchp['not']:
if not matchp['pattern'].match(group[field]):
if not matchp['pattern'].match(group.get(field, '')):
return False
else:
if matchp['pattern'].match(group[field]):
if matchp['pattern'].match(group.get(field, '')):
return False
return True
@@ -50284,6 +50286,64 @@ def doPrintCourseParticipants():
csvPF.SetSortTitles(COURSE_PARTICIPANTS_SORT_TITLES)
csvPF.writeCSVfile('Course Participants')
COURSE_COUNTS_MEMBER_ARGUMENTS = ['students', 'teachers']
COURSE_COUNTS_KEY_TITLE = {'students': 'Student', 'teachers': 'Teacher'}
# gam print course-counts students|teachers [todrive <ToDriveAttribute>*]
# (course|class <CourseEntity>)*|([teacher <UserItem>] [student <UserItem>] [states <CourseStateList>])
# [mincount <Integer>]
# [formatjson [quotechar <Character>]]
def doPrintCourseCounts():
croom = buildGAPIObject(API.CLASSROOM)
courseSelectionParameters = _initCourseSelectionParameters()
courseShowProperties = _initCourseShowProperties()
courseShowProperties['members'] = getChoice(COURSE_COUNTS_MEMBER_ARGUMENTS)
keyTitle = COURSE_COUNTS_KEY_TITLE[courseShowProperties['members']]
csvPF = CSVPrintFile([keyTitle, 'CourseCount'])
FJQC = FormatJSONQuoteChar(csvPF)
minCount = 0
useOwnerAccess = GC.Values[GC.USE_COURSE_OWNER_ACCESS]
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'todrive':
csvPF.GetTodriveParameters()
elif _getCourseSelectionParameters(myarg, courseSelectionParameters):
pass
elif myarg == 'mincount':
minCount = getInteger(minVal=0)
else:
FJQC.GetFormatJSONQuoteChar(myarg, False)
coursesInfo = _getCoursesInfo(croom, courseSelectionParameters, courseShowProperties, useOwnerAccess)
if not coursesInfo:
coursesInfo = []
teachersFields = 'nextPageToken,teachers(profile(emailAddress))'
studentsFields = 'nextPageToken,students(profile(emailAddress))'
courseCounts = {}
count = len(coursesInfo)
i = 0
for course in coursesInfo:
i += 1
courseId = course['id']
ocroom = _getCourseOwnerSA(croom, course, useOwnerAccess)
if not ocroom:
continue
_, teachers, students = _getCourseAliasesMembers(croom, ocroom, courseId, courseShowProperties, teachersFields, studentsFields, True, i, count)
members = teachers if courseShowProperties['members'] == 'teachers' else students
for member in members:
memberKey = member['profile'].get('emailAddress', '')
courseCounts.setdefault(memberKey, 0)
courseCounts[memberKey] += 1
if not FJQC.formatJSON:
for key, count in sorted(courseCounts.items()):
if count >= minCount:
csvPF.WriteRow({keyTitle: key, 'CourseCount': count})
else:
csvPF.SetJSONTitles(['JSON'])
for key, count in sorted(courseCounts.items()):
if count >= minCount:
csvPF.WriteRow({'JSON': {keyTitle: key, 'CourseCount': count}})
csvPF.writeCSVfile(f'{keyTitle} Course Counts')
def _batchAddItemsToCourse(croom, courseId, i, count, addItems, addType):
def _addIdToResponse(response, riItem):
if addType == Ent.COURSE_ANNOUNCEMENT:
@@ -53010,7 +53070,7 @@ CALENDAR_EXCLUDE_DOMAINS = {
# gam <UserTypeEntity> print calendars <UserCalendarEntity> [todrive <ToDriveAttribute>*]
# [primary] <CalendarSelectProperty>* [noprimary] [nogroups] [noresources] [nosystem] [nousers]
# [fields <CalendarFieldList>] [permissions]
# [fields <CalendarFieldList>] [permissions] [oneitemperrow]
# [formatjson [quotechar <Character>]] [delimiter <Character>]
# gam <UserTypeEntity> show calendars <UserCalendarEntity>
# [primary] <CalendarSelectProperty>* [noprimary] [nogroups] [noresources] [nosystem] [nousers]
@@ -53018,7 +53078,7 @@ CALENDAR_EXCLUDE_DOMAINS = {
# [formatjson]
def printShowCalendars(users):
acls = []
getCalPermissions = noPrimary = primaryOnly = False
getCalPermissions = oneItemPerRow = noPrimary = primaryOnly = False
excludes = set()
excludeDomains = set()
csvPF = CSVPrintFile(['primaryEmail', 'calendarId'], 'sortall') if Act.csvFormat() else None
@@ -53032,6 +53092,8 @@ def printShowCalendars(users):
csvPF.GetTodriveParameters()
elif myarg in [Cmd.ARG_ACLS, Cmd.ARG_CALENDARACLS, Cmd.ARG_PERMISSIONS]:
getCalPermissions = True
elif myarg == 'oneitemperrow':
oneItemPerRow = True
elif myarg == 'allcalendars':
pass
elif myarg == 'primary':
@@ -53107,17 +53169,35 @@ def printShowCalendars(users):
Ind.Decrement()
else:
if calendars:
for calendar in calendars:
row = {'primaryEmail': user, 'calendarId': calendar['id']}
if getCalPermissions:
flattenJSON({'permissions': _getCalendarPermissions(cal, calendar)}, flattened=row)
flattenJSON(calendar, flattened=row, simpleLists=CALENDAR_SIMPLE_LISTS, delimiter=delimiter)
if not FJQC.formatJSON:
row.pop('id')
csvPF.WriteRowTitles(row)
elif csvPF.CheckRowTitles(row):
csvPF.WriteRowNoFilter({'primaryEmail': user, 'calendarId': calendar['id'],
'JSON': json.dumps(cleanJSON(calendar), ensure_ascii=False, sort_keys=True)})
if not getCalPermissions or not oneItemPerRow:
for calendar in calendars:
row = {'primaryEmail': user, 'calendarId': calendar['id']}
if getCalPermissions:
calPerms = _getCalendarPermissions(cal, calendar)
flattenJSON({'permissions': calPerms}, flattened=row)
flattenJSON(calendar, flattened=row, simpleLists=CALENDAR_SIMPLE_LISTS, delimiter=delimiter)
if not FJQC.formatJSON:
row.pop('id')
csvPF.WriteRowTitles(row)
elif csvPF.CheckRowTitles(row):
if getCalPermissions:
calendar.update({'permissions': calPerms})
csvPF.WriteRowNoFilter({'primaryEmail': user, 'calendarId': calendar['id'],
'JSON': json.dumps(cleanJSON(calendar), ensure_ascii=False, sort_keys=True)})
else:
for calendar in calendars:
baserow = {'primaryEmail': user, 'calendarId': calendar['id']}
flattenJSON(calendar, flattened=baserow, simpleLists=CALENDAR_SIMPLE_LISTS, delimiter=delimiter)
for permission in _getCalendarPermissions(cal, calendar):
row = baserow.copy()
flattenJSON({'permission': permission}, flattened=row)
if not FJQC.formatJSON:
row.pop('id')
csvPF.WriteRowTitles(row)
elif csvPF.CheckRowTitles(row):
calendar.update({'permission': permission})
csvPF.WriteRowNoFilter({'primaryEmail': user, 'calendarId': calendar['id'],
'JSON': json.dumps(cleanJSON(calendar), ensure_ascii=False, sort_keys=True)})
elif GC.Values[GC.CSV_OUTPUT_USERS_AUDIT]:
csvPF.WriteRowNoFilter({'primaryEmail': user})
if csvPF:
@@ -53589,7 +53669,7 @@ def emptyCalendarTrash(users):
# gam <UserTypeEntity> update calattendees <UserCalendarEntity> <EventEntity> [anyorganizer]
# [<EventNotificationAttribute>] [splitupdate] [doit]
# (<CSVFileSelector>)
# (csv|csvfile <CSVFileInput> endcsv)
# (delete <EmailAddress>)*
# (deleteentity <EmailAddressEntity>)*
# (add <EmailAddress>)*
@@ -61086,6 +61166,7 @@ def initCopyMoveOptions(copyCmd):
'noCopyNonInheritedPermissions': COPY_NONINHERITED_PERMISSIONS_NEVER,
'excludePermissionsFromDomains': set(),
'includePermissionsFromDomains': set(),
'mapPermissionsEmails': {},
'mapPermissionsDomains': {},
'copySheetProtectedRangesInheritedPermissions': False,
'copySheetProtectedRangesNonInheritedPermissions': COPY_NONINHERITED_PERMISSIONS_NEVER,
@@ -61162,6 +61243,18 @@ def getCopyMoveOptions(myarg, copyMoveOptions):
elif myarg == 'includepermissionsfromdomains':
copyMoveOptions['includePermissionsFromDomains'] = set(getString(Cmd.OB_DOMAIN_NAME_LIST).lower().replace(',', ' ').split())
copyMoveOptions['excludePermissionsFromDomains'] = set()
elif myarg == 'mappermissionsemail':
sourceEmail = getEmailAddress(noUid=True).lower()
copyMoveOptions['mapPermissionsEmails'][sourceEmail] = getEmailAddress(noUid=True).lower()
elif myarg == 'mappermissionsemailfile':
csvInputLocation = Cmd.Location()
f, csvFile, _ = openCSVFileReader(getString(Cmd.OB_FILE_NAME))
if 'sourceEmail' not in csvFile.fieldnames or 'destinationEmail' not in csvFile.fieldnames:
Cmd.SetLocation(csvInputLocation)
usageErrorExit(Msg.MAP_PERMISSIONS_EMAIL_FILE_HEADERS_REQUIRED.format(myarg))
for row in csvFile:
copyMoveOptions['mapPermissionsEmails'][row['sourceEmail']] = row['destinationEmail']
closeFile(f)
elif myarg == 'mappermissionsdomain':
oldDomain = getString(Cmd.OB_DOMAIN_NAME).lower()
copyMoveOptions['mapPermissionsDomains'][oldDomain] = getString(Cmd.OB_DOMAIN_NAME).lower()
@@ -61323,9 +61416,9 @@ def _copyPermissions(drive, user, i, count, j, jcount,
if permissionType in {'group', 'user'}:
atLoc = emailAddress.find('@')
if atLoc > 0:
domain = emailAddress[atLoc+1:]
domain = emailAddress[atLoc+1:].lower()
elif permissionType == 'domain':
domain = permission.get('domain', '')
domain = permission.get('domain', '').lower()
if role not in copyMoveOptions['copyPermissionRoles']:
notCopiedMessage = f'role {role} not selected'
elif permissionType not in copyMoveOptions['copyPermissionTypes']:
@@ -61375,7 +61468,12 @@ def _copyPermissions(drive, user, i, count, j, jcount,
def mapPermissionsDomains(srcPerm):
if 'emailAddress' in srcPerm:
email, domain = srcPerm['emailAddress'].lower().split('@', 1)
sourceEmail = srcPerm['emailAddress'].lower()
destEmail = copyMoveOptions['mapPermissionsEmails'].get(sourceEmail, None)
if destEmail:
srcPerm['emailAddress'] = destEmail
return True
email, domain = sourceEmail.split('@', 1)
if domain in copyMoveOptions['mapPermissionsDomains']:
srcPerm['emailAddress'] = f"{email}@{copyMoveOptions['mapPermissionsDomains'][domain]}"
return True
@@ -61389,6 +61487,7 @@ def _copyPermissions(drive, user, i, count, j, jcount,
sourcePerms = getPermissions(fileId)
if sourcePerms is None:
return
Ind.Increment()
copySourcePerms = {}
deleteTargetPermIds = set()
updateTargetPerms = {}
@@ -61397,18 +61496,19 @@ def _copyPermissions(drive, user, i, count, j, jcount,
if isPermissionCopyable(kvList, permission):
copySourcePerms[permissionId] = permission
if copyMoveOptions[copyNonInherited] == COPY_NONINHERITED_PERMISSIONS_ALWAYS:
if copyMoveOptions['mapPermissionsDomains']:
if copyMoveOptions['mapPermissionsDomains'] or copyMoveOptions['mapPermissionsEmails']:
for permissionId in getNonInheritedPermissions(copySourcePerms):
mapPermissionsDomains(copySourcePerms[permissionId])
elif copyMoveOptions[copyNonInherited] in {COPY_NONINHERITED_PERMISSIONS_SYNC_ALL_FOLDERS,
COPY_NONINHERITED_PERMISSIONS_SYNC_UPDATED_FOLDERS}:
targetPerms = getPermissions(newFileId)
if targetPerms is None:
Ind.Decrement()
return
sourceNonInheritedPermIDs = getNonInheritedPermissions(copySourcePerms)
targetNonInheritedPermIDs = getNonInheritedPermissions(targetPerms)
# Permissions in Source only
if copyMoveOptions['mapPermissionsDomains']:
if copyMoveOptions['mapPermissionsDomains'] or copyMoveOptions['mapPermissionsEmails']:
for permissionId in sourceNonInheritedPermIDs-targetNonInheritedPermIDs:
mapPermissionsDomains(copySourcePerms[permissionId])
# Permissions in Target only
@@ -61416,7 +61516,7 @@ def _copyPermissions(drive, user, i, count, j, jcount,
# Permissions in Source and Target
for permissionId in targetNonInheritedPermIDs&sourceNonInheritedPermIDs:
srcPerm = copySourcePerms[permissionId]
if copyMoveOptions['mapPermissionsDomains'] and mapPermissionsDomains(srcPerm):
if (copyMoveOptions['mapPermissionsDomains'] or copyMoveOptions['mapPermissionsEmails']) and mapPermissionsDomains(srcPerm):
deleteTargetPermIds.add(permissionId)
continue
tgtPerm = targetPerms[permissionId]
@@ -61441,7 +61541,6 @@ def _copyPermissions(drive, user, i, count, j, jcount,
deleteUpdateKwargs = {'useDomainAdminAccess': copyMoveOptions['useDomainAdminAccess']}
if entityType != Ent.SHAREDDRIVE:
deleteUpdateKwargs['enforceExpansiveAccess'] = copyMoveOptions['enforceExpansiveAccess']
Ind.Increment()
action = Act.Get()
Act.Set(Act.COPY)
kcount = len(copySourcePerms)
@@ -61797,6 +61896,7 @@ copyReturnItemMap = {
# [copypermissionroles <DriveFileACLRoleList>]
# [copypermissiontypes <DriveFileACLTypeList>]
# [excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
# (mappermissionsemail <EmailAddress> <EmailAddress>)* [mappermissionsemailfile <CSVFileInput> endcsv]
# (mappermissionsdomain <DomainName> <DomainName>)*
# [copysheetprotectedranges [<Boolean>]]
# [copysheetprotectedrangesinheritedpermissions [<Boolean>]]
@@ -62471,9 +62571,9 @@ def _updateMoveFilePermissions(drive, user, i, count,
if permission['type'] in {'group', 'user'}:
atLoc = permission.get('emailAddress', '').find('@')
if atLoc > 0:
domain = permission['emailAddress'][atLoc+1:]
domain = permission['emailAddress'][atLoc+1:].lower()
elif permission['type'] == 'domain':
domain = permission.get('domain', '')
domain = permission.get('domain', '').lower()
if domain and domain in copyMoveOptions['excludePermissionsFromDomains']:
notMovedMessage = f'domain {domain} excluded'
elif domain and copyMoveOptions['includePermissionsFromDomains'] and domain not in copyMoveOptions['includePermissionsFromDomains']:
@@ -62489,13 +62589,24 @@ def _updateMoveFilePermissions(drive, user, i, count,
def mapPermissionsDomains(kvList, permission):
if 'emailAddress' in permission:
email, domain = permission['emailAddress'].lower().split('@', 1)
if domain in copyMoveOptions['mapPermissionsDomains']:
sourceEmail = permission['emailAddress'].lower()
destEmail = copyMoveOptions['mapPermissionsEmails'].get(sourceEmail, None)
if destEmail:
deleteSourcePerms[permission['id']] = permission.copy()
if copyMoveOptions['showPermissionMessages']:
notMovedMessage = f"domain {domain} mapped to {copyMoveOptions['mapPermissionsDomains'][domain]}"
notMovedMessage = f"email {sourceEmail} mapped to {destEmail}"
entityActionNotPerformedWarning(kvList, notMovedMessage, 0, 0)
permission['emailAddress'] = f"{email}@{copyMoveOptions['mapPermissionsDomains'][domain]}"
permission['emailAddress'] = destEmail
addSourcePerms[permission['id']] = permission
return True
email, domain = sourceEmail.split('@', 1)
if domain in copyMoveOptions['mapPermissionsDomains']:
destEmail = f"{email}@{copyMoveOptions['mapPermissionsDomains'][domain]}"
deleteSourcePerms[permission['id']] = permission.copy()
if copyMoveOptions['showPermissionMessages']:
notMovedMessage = f"email {sourceEmail} mapped to {destEmail}"
entityActionNotPerformedWarning(kvList, notMovedMessage, 0, 0)
permission['emailAddress'] = destEmail
addSourcePerms[permission['id']] = permission
return True
elif 'domain' in permission:
@@ -62513,14 +62624,14 @@ def _updateMoveFilePermissions(drive, user, i, count,
sourcePerms = getPermissions(fileId)
if sourcePerms is None:
return
Ind.Increment()
deleteSourcePerms = {}
addSourcePerms = {}
for permissionId, permission in sourcePerms.items():
kvList = permissionKVList(user, entityType, fileTitle, permission)
if isPermissionDeletable(kvList, permission):
pass
elif copyMoveOptions['mapPermissionsDomains']:
if permission.get('permissionDetails', {}).get('inherited', False):
continue
if (not isPermissionDeletable(kvList, permission) and
(copyMoveOptions['mapPermissionsDomains'] or copyMoveOptions['mapPermissionsEmails'])):
mapPermissionsDomains(kvList, permission)
action = Act.Get()
kcount = len(deleteSourcePerms)
@@ -62547,7 +62658,6 @@ def _updateMoveFilePermissions(drive, user, i, count,
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
userDriveServiceNotEnabledWarning(user, str(e), i, count)
_incrStatistic(statistics, stat)
Ind.Decrement()
Act.Set(action)
return
kcount = len(addSourcePerms)
@@ -62594,12 +62704,41 @@ def _updateMoveFilePermissions(drive, user, i, count,
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
userDriveServiceNotEnabledWarning(user, str(e), i, count)
_incrStatistic(statistics, stat)
Ind.Decrement()
Act.Set(action)
return
Ind.Decrement()
Act.Set(action)
def _recursiveUpdateMovePermissions(drive, user, i, count,
fileId, fileTitle,
statistics, copyMoveOptions, sourceSearchArgs):
_updateMoveFilePermissions(drive, user, i, count,
Ent.DRIVE_FOLDER, fileId, fileTitle,
statistics, STAT_FOLDER_PERMISSIONS_FAILED, copyMoveOptions)
sourceChildren = callGAPIpages(drive.files(), 'list', 'files',
throwReasons=GAPI.DRIVE_USER_THROW_REASONS,
retryReasons=[GAPI.UNKNOWN_ERROR],
q=WITH_PARENTS.format(fileId),
orderBy='folder desc,name,modifiedTime desc',
fields='nextPageToken,files(id,name,mimeType)',
pageSize=GC.Values[GC.DRIVE_MAX_RESULTS], **sourceSearchArgs)
kcount = len(sourceChildren)
if kcount > 0:
Ind.Increment()
k = 0
for child in sourceChildren:
k += 1
childId = child['id']
childName = child['name']
if child['mimeType'] == MIMETYPE_GA_FOLDER:
_recursiveUpdateMovePermissions(drive, user, i, count,
childId, childName,
statistics, copyMoveOptions, sourceSearchArgs)
else:
_updateMoveFilePermissions(drive, user, i, count,
Ent.DRIVE_FILE, childId, childName,
statistics, STAT_FILE_PERMISSIONS_FAILED, copyMoveOptions)
Ind.Decrement()
# gam <UserTypeEntity> move drivefile <DriveFileEntity> [newfilename <DriveFileName>]
# [summary [<Boolean>]] [showpermissionsmessages [<Boolean>]]
# [<DriveFileParentAttribute>]
@@ -62620,8 +62759,8 @@ def _updateMoveFilePermissions(drive, user, i, count,
# [copypermissiontypes <DriveFileACLTypeList>]
# [synctopfoldernoniheritedpermissions [<Boolean>]] [syncsubfoldernoninheritedpermissions [<Boolean>]]
# [excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
# (mappermissionsemail <EmailAddress> <EmailAddress>)* [mappermissionsemailfile <CSVFileInput> endcsv]
# (mappermissionsdomain <DomainName> <DomainName>)*
# [updatefilepermissions [<Boolean>]]
# [retainsourcefolders [<Boolean>]]
# [sendemailifrequired [<Boolean>]]
# [verifyorganizer [<Boolean>]]
@@ -62657,7 +62796,7 @@ def moveDriveFile(users):
copyFolderNonInheritedPermissions,
False)
source.pop('oldparents', None)
return (newParentId, newParentName, True)
return (newParentId, newParentName, True, True)
# Merge parent folders
if atTop and copyMoveOptions['sourceIsMyDriveSharedDrive']:
pass
@@ -62686,11 +62825,11 @@ def moveDriveFile(users):
['copySubFolderInheritedPermissions', 'copyTopFolderInheritedPermissions'][atTop],
copyFolderNonInheritedPermissions,
False)
return (newFolderId, newFolderName, True)
return (newFolderId, newFolderName, True, True)
entityActionFailedWarning(kvList+[Ent.DRIVE_FOLDER, newParentNameId], Msg.NOT_WRITABLE, j, jcount)
_incrStatistic(statistics, STAT_FOLDER_NOT_WRITABLE)
copyMoveOptions['retainSourceFolders'] = True
return (None, None, False)
return (None, None, False, False)
elif copyMoveOptions['duplicateFolders'] == DUPLICATE_FOLDER_UNIQUE_NAME:
newFolderName = _getUniqueFilename(newFolderName, sourceMimeType, targetChildren)
elif copyMoveOptions['duplicateFolders'] == DUPLICATE_FOLDER_SKIP:
@@ -62701,7 +62840,7 @@ def moveDriveFile(users):
Msg.DUPLICATE, j, jcount)
_incrStatistic(statistics, STAT_FOLDER_DUPLICATE)
copyMoveOptions['retainSourceFolders'] = True
return (None, None, False)
return (None, None, False, False)
# Update parents on: not retain and MD->MD, SD->MD, SD->SD
if atTop and copyMoveOptions['sourceIsMyDriveSharedDrive']:
pass
@@ -62730,7 +62869,7 @@ def moveDriveFile(users):
[Ent.DRIVE_FOLDER, newParentNameId, Ent.DRIVE_FOLDER, f'{newFolderName}({folderId})'],
j, jcount)
_incrStatistic(statistics, STAT_FILE_COPIED_MOVED)
return (None, None, False)
return (None, None, False, True)
except (GAPI.badRequest, GAPI.insufficientParentPermissions, GAPI.fileOwnerNotMemberOfTeamDrive, GAPI.fileOwnerNotMemberOfWriterDomain,
GAPI.fileWriterTeamDriveMoveInDisabled, GAPI.targetUserRoleLimitedByLicenseRestriction,
GAPI.cannotMoveTrashedItemIntoTeamDrive, GAPI.cannotMoveTrashedItemOutOfTeamDrive,
@@ -62740,8 +62879,8 @@ def moveDriveFile(users):
userDriveServiceNotEnabledWarning(user, str(e), i, count)
_incrStatistic(statistics, STAT_FILE_FAILED)
copyMoveOptions['retainSourceFolders'] = True
return (None, None, False)
# Create new parent on: retain or MD->SD
return (None, None, False, False)
# Create new parent on: retain or MD->SD
source.pop('oldparents', None)
body = source.copy()
body.pop('capabilities', None)
@@ -62775,7 +62914,7 @@ def moveDriveFile(users):
['copySubFolderInheritedPermissions', 'copyTopFolderInheritedPermissions'][atTop],
['copySubFolderNonInheritedPermissions', 'copyTopFolderNonInheritedPermissions'][atTop],
True)
return (newFolderId, newFolderName, False)
return (newFolderId, newFolderName, False, True)
except (GAPI.forbidden, GAPI.insufficientFilePermissions, GAPI.insufficientParentPermissions,
GAPI.internalError, GAPI.storageQuotaExceeded, GAPI.teamDriveFileLimitExceeded, GAPI.teamDriveHierarchyTooDeep,
GAPI.badRequest, GAPI.targetUserRoleLimitedByLicenseRestriction) as e:
@@ -62784,7 +62923,7 @@ def moveDriveFile(users):
userDriveServiceNotEnabledWarning(user, str(e), i, count)
_incrStatistic(statistics, STAT_FOLDER_FAILED)
copyMoveOptions['retainSourceFolders'] = True
return (None, None, False)
return (None, None, False, False)
def _makeMoveShortcut(drive, user, k, kcount, entityType, childId, childName, newParentId, newParentName):
kvList = [Ent.USER, user, entityType, f'{childName}({childId})']
@@ -62834,7 +62973,7 @@ def moveDriveFile(users):
def _moveFile(drive, user, i, count, k, kcount, entityType, childId, childName, newChildName, newParentId, newParentName, removeParents, body):
kvList = [Ent.USER, user, entityType, f'{childName}({childId})']
newParentNameId = f'{newParentName}({newParentId})'
if updateFilePermissions:
if updateMovePermissions:
_updateMoveFilePermissions(drive, user, i, count,
entityType, childId, childName,
statistics, STAT_FILE_PERMISSIONS_FAILED, copyMoveOptions)
@@ -62879,11 +63018,17 @@ def moveDriveFile(users):
def _recursiveFolderMove(drive, user, i, count, j, jcount,
source, targetChildren, newFolderName, newParentId, newParentName, mergeParentModifiedTime, atTop):
folderId = source['id']
newFolderId, newFolderName, existingTargetFolder = _cloneFolderMove(drive, user, i, count, j, jcount,
source, targetChildren, newFolderName,
newParentId, newParentName, mergeParentModifiedTime,
statistics, copyMoveOptions, atTop)
newFolderId, newFolderName, existingTargetFolder, status = _cloneFolderMove(drive, user, i, count, j, jcount,
source, targetChildren, newFolderName,
newParentId, newParentName, mergeParentModifiedTime,
statistics, copyMoveOptions, atTop)
if not status:
return
if newFolderId is None:
if updateMovePermissions:
_recursiveUpdateMovePermissions(drive, user, i, count,
folderId, source['name'],
statistics, copyMoveOptions, sourceSearchArgs)
return
movedFiles[newFolderId] = 1
sourceChildren = callGAPIpages(drive.files(), 'list', 'files',
@@ -62970,7 +63115,7 @@ def moveDriveFile(users):
parentBody = {}
parentParms = initDriveFileAttributes()
copyMoveOptions = initCopyMoveOptions(False)
newParentsSpecified = updateFilePermissions = False
newParentsSpecified = False
movedFiles = {}
verifyOrganizer = True
while Cmd.ArgumentsRemaining():
@@ -62979,12 +63124,13 @@ def moveDriveFile(users):
pass
elif getDriveFileParentAttribute(myarg, parentParms):
newParentsSpecified = True
elif myarg == 'updatefilepermissions':
updateFilePermissions = getBoolean()
elif myarg == 'verifyorganizer':
verifyOrganizer = getBoolean()
else:
unknownArgumentExit()
updateMovePermissions = (copyMoveOptions['excludePermissionsFromDomains'] or copyMoveOptions['includePermissionsFromDomains'] or
copyMoveOptions['mapPermissionsDomains'] or copyMoveOptions['mapPermissionsEmails'])
i, count, users = getEntityArgument(users)
for user in users:
i += 1
@@ -68094,10 +68240,16 @@ def doPrintShowOrgunitSharedDrives():
csvPF.writeCSVfile('OrgUnit {orgUnitPath} SharedDrives')
# gam [<UserTypeEntity>] copy shareddriveacls <SharedDriveEntity> to <SharedDriveEntity>
# [asadmin]
# [showpermissionsmessages [<Boolean>]]
# [excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
# (mappermissionsemail <EmailAddress> <EmailAddress>)* [mappermissionsemailfile <CSVFileInput> endcsv]
# (mappermissionsdomain <DomainName> <DomainName>)*
# gam [<UserTypeEntity>] sync shareddriveacls <SharedDriveEntity> with <SharedDriveEntity>
# [asadmin]
# [showpermissionsmessages [<Boolean>]]
# [excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
# (mappermissionsemail <EmailAddress> <EmailAddress>)* [mappermissionsemailfile <CSVFileInput> endcsv]
# (mappermissionsdomain <DomainName> <DomainName>)*
def copySyncSharedDriveACLs(users, useDomainAdminAccess=False):
copyMoveOptions = initCopyMoveOptions(True)
@@ -68125,13 +68277,15 @@ def copySyncSharedDriveACLs(users, useDomainAdminAccess=False):
if not drive:
continue
if not srcFileIdEntity.get('shareddrivename'):
srcFileIdEntity['shareddrivename'] = _getSharedDriveNameFromId(drive, srcFileIdEntity['shareddrive']['driveId'])
srcFileIdEntity['shareddrivename'] = _getSharedDriveNameFromId(drive, srcFileIdEntity['shareddrive']['driveId'],
useDomainAdminAccess)
if tgtFileIdEntity.get('shareddrivename'):
if not _convertSharedDriveNameToId(drive, user, i, count, tgtFileIdEntity, useDomainAdminAccess):
continue
tgtFileIdEntity['shareddrive']['corpora'] = 'drive'
else:
tgtFileIdEntity['shareddrivename'] = _getSharedDriveNameFromId(drive, tgtFileIdEntity['shareddrive']['driveId'])
tgtFileIdEntity['shareddrivename'] = _getSharedDriveNameFromId(drive, tgtFileIdEntity['shareddrive']['driveId'],
useDomainAdminAccess)
statistics = _initStatistics()
copyMoveOptions['sourceDriveId'] = srcFileIdEntity['shareddrive']['driveId']
copyMoveOptions['destDriveId'] = tgtFileIdEntity['shareddrive']['driveId']
@@ -73549,6 +73703,8 @@ def printShowMessagesThreads(users, entityType):
row[f'Attachments{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}{i}{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}mimeType'] = attachment[1]
row[f'Attachments{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}{i}{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}size'] = attachment[2]
row[f'Attachments{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}{i}{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}charset'] = attachment[3]
if addCSVData:
row.update(addCSVData)
csvPF.WriteRowTitles(row)
if checkMax:
parameters['messagesProcessed'] += 1
@@ -74037,7 +74193,7 @@ def printShowMessagesThreads(users, entityType):
# [quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <MessageIDEntity>)
# [labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
# [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
# [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
# [showlabels] [useronly] [delimiter <Character>] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
# [convertcrnl] [delimiter <Character>]
# [countsonly|positivecountsonly] [useronly]
# [[attachmentnamepattern <REMatchPattern>]
@@ -74049,8 +74205,8 @@ def printShowMessagesThreads(users, entityType):
# [quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <MessageIDEntity>)
# [labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
# [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
# [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
# [countsonly|positivecountsonly] [useronly]
# [showlabels] [useronly] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
# [countsonly|positivecountsonly]
# [[attachmentnamepattern <REMatchPattern>]
# [showattachments [noshowtextplain]]
# [saveattachments [targetfolder <FilePath>] [overwrite [<Boolean>]]]
@@ -78796,6 +78952,7 @@ MAIN_COMMANDS_WITH_OBJECTS = {
Cmd.ARG_COURSE: doPrintCourses,
Cmd.ARG_COURSES: doPrintCourses,
Cmd.ARG_COURSEANNOUNCEMENTS: doPrintCourseAnnouncements,
Cmd.ARG_COURSECOUNTS: doPrintCourseCounts,
Cmd.ARG_COURSEMATERIALS: doPrintCourseMaterials,
Cmd.ARG_COURSEPARTICIPANTS: doPrintCourseParticipants,
Cmd.ARG_COURSESTUDENTGROUP: doPrintCourseStudentGroups,
@@ -79122,6 +79279,7 @@ MAIN_COMMANDS_OBJ_ALIASES = {
Cmd.ARG_CLASSIFICATIONLABELPERMISSIONS: Cmd.ARG_DRIVELABELPERMISSION,
Cmd.ARG_CLASS: Cmd.ARG_COURSE,
Cmd.ARG_CLASSES: Cmd.ARG_COURSES,
Cmd.ARG_CLASSCOUNTS: Cmd.ARG_COURSECOUNTS,
Cmd.ARG_CLASSPARTICIPANTS: Cmd.ARG_COURSEPARTICIPANTS,
Cmd.ARG_CLASSROOMINVITATIONS: Cmd.ARG_CLASSROOMINVITATION,
Cmd.ARG_CONTACTS: Cmd.ARG_CONTACT,

View File

@@ -788,6 +788,7 @@ class GamCLArgs():
ARG_CLASSIFICATIONLABELPERMISSIONS = 'classificationlabelpermissions'
ARG_CLASS = 'class'
ARG_CLASSES = 'classes'
ARG_CLASSCOUNTS = 'classcounts'
ARG_CLASSPARTICIPANTS = 'classparticipants'
ARG_CLASSROOMINVITATION = 'classroominvitation'
ARG_CLASSROOMINVITATIONS = 'classroominvitations'
@@ -806,6 +807,7 @@ class GamCLArgs():
ARG_COURSE = 'course'
ARG_COURSES = 'courses'
ARG_COURSEANNOUNCEMENTS = 'courseannouncements'
ARG_COURSECOUNTS = 'coursecounts'
ARG_COURSEMATERIALS = 'coursematerials'
ARG_COURSEPARTICIPANTS = 'courseparticipants'
ARG_COURSESTUDENTGROUP = 'coursestudentgroup'

View File

@@ -355,6 +355,7 @@ LESS_THAN_1_SECOND = 'less than 1 second'
LIST_CHROMEOS_INVALID_INPUT_PAGE_TOKEN_RETRY = 'List ChromeOSdevices Invalid Input: pageToken retry'
LOGGING_INITIALIZATION_ERROR = 'Logging initialization error: {0}'
LOOKING_UP_GOOGLE_UNIQUE_ID = 'Looking up Google Unique ID'
MAP_PERMISSIONS_EMAIL_FILE_HEADERS_REQUIRED = '{0} <CSVFileInput> requires headers "sourceEmail" and "destinationEmail"'
MARKED_AS = 'Marked as'
MATCHED_THE_FOLLOWING = 'Matched the following'
MATTER_NOT_OPEN = 'Matter needs to be open, current state is: {0}'

View File

@@ -19,12 +19,11 @@
"""YubiKey"""
import base64
from datetime import datetime, timedelta
from secrets import SystemRandom
import string
import sys
import arrow
from gam import mplock
from gam import systemErrorExit
@@ -41,7 +40,6 @@ from ykman.piv import generate_self_signed_certificate, generate_chuid
from yubikit.piv import DEFAULT_MANAGEMENT_KEY, \
InvalidPinError, \
KEY_TYPE, \
MANAGEMENT_KEY_TYPE, \
PIN_POLICY, \
PivSession, \
OBJECT_ID, \
@@ -149,17 +147,17 @@ class YubiKey():
piv.change_puk('12345678', new_puk)
piv.change_pin('123456', new_pin)
writeStdout(Msg.YUBIKEY_PIN_SET_TO.format(new_pin))
piv.authenticate(MANAGEMENT_KEY_TYPE.TDES, DEFAULT_MANAGEMENT_KEY)
piv.authenticate(piv.management_key_type, DEFAULT_MANAGEMENT_KEY)
piv.verify_pin(new_pin)
writeStdout(Msg.YUBIKEY_GENERATING_NONEXPORTABLE_PRIVATE_KEY)
pubkey = piv.generate_key(SLOT.AUTHENTICATION,
KEY_TYPE.RSA2048,
PIN_POLICY.ALWAYS,
TOUCH_POLICY.NEVER)
now = arrow.utcnow()
valid_to = now.shift(days=36500)
now = datetime.utcnow()
valid_to = now + timedelta(days=3650)
subject = 'CN=GAM Created Key'
piv.authenticate(MANAGEMENT_KEY_TYPE.TDES, DEFAULT_MANAGEMENT_KEY)
piv.authenticate(piv.management_key_type, DEFAULT_MANAGEMENT_KEY)
piv.verify_pin(new_pin)
cert = generate_self_signed_certificate(piv,
SLOT.AUTHENTICATION,

View File

@@ -394,9 +394,9 @@ gam show projects [[admin] <EmailAddress>] [all|<ProjectIDEntity>]
* `<EmailAddress>` - A Google Workspace admin/GCP project manager; if omitted, you will be prompted for the address
Use these options to select projects.
* `all` - All projects accessible by the administrator; this is the default
* `all` - All projects accessible by the administrator
* `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-`
* `gam` - Projects accessible by the administrator that were created by Gam, i.e, their project ID begins with `gam-project-`; this is the default
* `<ProjectID>` - A Google API project ID
* `filter <String>` - A filter to select projects accessible by the administrator; see the API documentation
* `states all|active|deleterequested` - Limit display to projects based on state; the default is `active`
@@ -412,9 +412,9 @@ gam print projects [[admin] <EmailAddress>] [all|<ProjectIDEntity>] [todrive <To
* `<EmailAddress>` - A Google Workspace admin/GCP project manager; if omitted, you will be prompted for the address
Use these options to select projects.
* `all` - All projects accessible by the administrator; this is the default
* `all` - All projects accessible by the administrator
* `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-`
* `gam` - Projects accessible by the administrator that were created by Gam, i.e, their project ID begins with `gam-project-`; this is the default
* `<ProjectID>` - A Google API project ID
* `filter <String>` - A filter to select projects accessible by the administrator; see the API documentation
* `states all|active|deleterequested` - Limit display to projects based on state; the default is `active`

View File

@@ -379,7 +379,7 @@ Drive files with `shareMode` `Each student will get a copy` don't seem to be abl
## Delete courses
Classes can only be deleted when they are in the ARCHIVED state; to delete a class, you can update its state to ARCHIVED
and then delete it or you can specify that it be archived as parot of the delete command.
and then delete it or you can specify that it be archived as part of the delete command.
```
gam delete course <CourseID> [archived]
gam delete courses <CourseEntity> [archived]

View File

@@ -7,6 +7,7 @@
- [Bulk membership changes](#bulk-membership-changes)
- [Display course membership](#display-course-membership)
- [Display course membership counts](#display-course-membership-counts)
- [Display course counts for teachers-students](#display-course-counts-for-teachers-students)
## API documentation
* [Google Classroom API](https://developers.google.com/classroom/reference/rest)
@@ -167,3 +168,46 @@ $count = & gam print course-participants teacher asmith states active show stude
Windows Command Prompt
for /f "delims=" %a in ('gam print course-participants teacher asmith states active show students showitemcountonly') do set count=%a
```
## Display course counts for teachers-students
You can get a count of the number of courses in which a teacher or student is a participant.
```
gam print course-counts students|teachers [todrive <ToDriveAttribute>*]
(course|class <CourseEntity>)*|([teacher <UserItem>] [student <UserItem>] [states <CourseStateList>])
[mincount <Integer>]
[formatjson [quotechar <Character>]]
```
By default, the `print course-counts` command displays participant counts about all courses.
To get participant counts for a specific set of courses, use the following option; it can be repeated to select multiple courses.
* `(course|class <CourseID>)*` - Display courses with the specified `<CourseID>`.
To get participant counts for courses based on their having a particular participant, use the following options. Both options can be specified.
* `teacher <UserItem>` - Display courses with the specified teacher.
* `student <UserItem>` - Display courses with the specified student.
To get participant counts for courses based on their state, use the following option. This option can be combined with the `teacher` and `student` options.
By default, all course states are selected.
* `states <CourseStateList>` - Display courses with any of the specified states.
By default, all count values are displayed, use `mincount <Integer>` to limit the display to those counts
greater that or equal to the specified `<Integer>`.
By default, Gam displays the counts 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.
### Example
For teachers in all active courses, print the number of classes for which they are a participant.
```
gam print coursecounts teachers states active
```
For teachers in all active courses, print the number of classes (if it is >= 5) for which they are a participant.
```
gam print coursecounts teachers states active mincount 5
```

View File

@@ -10,9 +10,84 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation
### 7.29.03
Remove debugging message from `gam <UserTypeEntity> move drivefile <DriveFileEntity>`.
### 7.29.02
Fixed bug in `gam <UserTypeEntity> move drivefile <DriveFileEntity>` where the following options
were only applied to top level files or folders re-created in the destination. Now, domain
and email address mappings apply to all moved files/folders.
```
excludepermissionsfromdomains <DomainNameList>
includepermissionsfromdomains <DomainNameList>
mappermissionsdomain <DomainName> <DomainName>
mappermissionsemail <EmailAddress> <EmailAddress>
mappermissionsemailfile <CSVFileInput> endcsv
```
Upgraded to Python 3.14.1.
### 7.29.01
Added option `oneitemperrow` to `gam <UserTypeEntity> print calendars ... permissions` to have each of a
calendar's permissions displayed on a separate row with all of the other calendar fields.
Updated `gam yubikey reset_piv` to handle YubiKey firmware updates that caused an error.
### 7.29.00
Added options `mappermissionsemail <EmailAddress> <EmailAddress>` and ` mappermissionsemailfile <CSVFileInput> endcsv`
to these commands:
```
gam [<UserTypeEntity>] copy shareddriveacls <SharedDriveEntity> to <SharedDriveEntity>
gam [<UserTypeEntity>] sync shareddriveacls <SharedDriveEntity> with <SharedDriveEntity>
gam <UserTypeEntity> copy drivefile <DriveFileEntity>
gam <UserTypeEntity> move drivefile <DriveFileEntity>
```
When `mappermissionsemail <EmailAddress> <EmailAddress>` is specifed, an ACL that references the first `<EmailAddress>`
in the source will be modified to reference the second `<EmailAddress>` in the destination.
Bulk permission email address mapping can be specified with `mappermissionsemailfile <CSVFileInput> endcsv`.
`<CSVFileInput>` must include these columns: `sourceEmail` and `destinationEmail`.
These options will be most useful with inter-workspace Shared Drive copies and moves.
### 7.28.13
Added option `addcsvdata <FieldName> <String>` to `gam <UserTypeEntity> print messages`
that adds additional columns of data to the CSV file output.
### 7.28.12
Updated `gam delete project` to handle the following error:
```
ERROR: 400: failedPrecondition - Project not active
```
### 7.28.11
Removed all options/fields referencing inheritance from `gam create|update|info|print org` as this option/field is deprecated.
### 7.28.10
Added a command `gam print course-counts` that dsplays the count of the number of courses in which a teacher or student is a participant.
* See: https://github.com/GAM-team/GAM/wiki/Classroom-Membership#display-course-counts-for-teachers-students
### 7.28.09
Fixed bug in `gam print cigroups ... descriptionmatchpattern [not] <REMatchPattern>` that caused a trap.
### 7.28.08
Updated `gam <UserTypeEntity> print|show chatmessages` to cache the sender UID to email address
map so that each sender UID only has to be looked up once; this improves performance.
### 7.28.07
Fixed bug in 'gam report users ... aggregatebydate|aggregatebyuser` where `accounts:used_quota_in_percentage` was incorrectly displayed.
Fixed bug in `gam report users ... aggregatebydate|aggregatebyuser` where `accounts:used_quota_in_percentage` was incorrectly displayed.
### 7.28.06

View File

@@ -252,9 +252,9 @@ writes the credentials into the file oauth2.txt.
admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt
admin@server:/Users/admin$ gam version
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
GAM 7.28.07 - https://github.com/GAM-team/GAM - pyinstaller
GAM 7.29.03 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.0 64-bit final
Python 3.14.1 64-bit final
macOS Tahoe 26.1 x86_64
Path: /Users/admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
@@ -990,9 +990,9 @@ writes the credentials into the file oauth2.txt.
C:\>del C:\GAMConfig\oauth2.txt
C:\>gam version
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
GAM 7.28.07 - https://github.com/GAM-team/GAM - pythonsource
GAM 7.29.03 - https://github.com/GAM-team/GAM - pythonsource
GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.0 64-bit final
Python 3.14.1 64-bit final
Windows 11 10.0.26200 AMD64
Path: C:\GAM7
Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com

View File

@@ -32,7 +32,6 @@
<OrgUnitFieldName> ::=
description|
id|orgunitid|
inherit|blockinheritance|
name|
parentid|parentorgunitid|
parent|parentorgunitpath|
@@ -73,18 +72,15 @@ For quoting rules, see: [List Quoting Rules](Command-Line-Parsing)
Create, update and delete organization units.
```
gam create org|ou <OrgUnitPath> [description <String>]
[parent <OrgUnitItem>] [inherit|(blockinheritance False)]
[parent <OrgUnitItem>]
[buildpath]
gam update org|ou <OrgUnitPath> [name <String>] [description <String>]
[parent <OrgUnitItem>] [inherit|(blockinheritance False)]
[parent <OrgUnitItem>]
gam delete org|ou <OrgUnitPath>
gam update orgs|ous <OrgUnitEntity> [name <String>] [description <String>]
[parent <OrgUnitItem>] [inherit|(blockinheritance False)]
[parent <OrgUnitItem>]
gam delete orgs|ous <OrgUnitEntity>
```
Inheritance specifies whether sub-OUs of the specified OU inherit its settings.
* `inherit|blockinheritance false` - Sub-OUs inherit settings from the specified OU; this is the default
## Add users to an organizational unit
When adding users to an OU, Gam uses a batch method to speed up processing.

View File

@@ -14,5 +14,10 @@ Thank you.
* Korey Rideout - https://chatgpt.com/g/g-PTxxnVPMG-gam-assist-now-turbocharged-with-gam7
* Paul Ogier (Taming.Tech) - GAM7 Course on Udemy https://taming.tech/GAMCourse
* Paul Ogier (Taming.Tech) - GAM7 Tutorials https://www.youtube.com/watch?v=g9LDeyXQNLI&list=PL_dLiK09pJVhKJxZHNk9CHK0q5hkZ856w
* Paul Ogier (Taming.Tech) - Installation videos
* GAM7 Windows Install - https://www.youtube.com/watch?v=l8pTF5UWz7o&list=PL_dLiK09pJVhKJxZHNk9CHK0q5hkZ856w&index=4
* GAM7 macOS Install - https://www.youtube.com/watch?v=eaLWpxhC91w&list=PL_dLiK09pJVhKJxZHNk9CHK0q5hkZ856w&index=5
* GAM7 Ubuntu Linux Install - https://www.youtube.com/watch?v=zBwhNTxGlcM&list=PL_dLiK09pJVhKJxZHNk9CHK0q5hkZ856w&index=7
* GAM7 ChromeOS Install - https://www.youtube.com/watch?v=BNWQh8GqvgY&list=PL_dLiK09pJVhKJxZHNk9CHK0q5hkZ856w&index=6
* Paul Ogier (Taming.Tech) - https://taming.tech/taming-gam-a-practical-guide-to-gam-and-gamadv-xtd3/
* Steve Larsen - https://docs.google.com/spreadsheets/d/1MzzA-u-cmoQcJnQOovCnZcEKMjvOyFhfkdFdf10X_GI/edit

View File

@@ -52,11 +52,12 @@ config csv_output_row_filter "'\"accounts:used_quota_in_mb\":count>15000'"
chrome|
classroom|
contextawareaccess|
gplus|currents|google+|
datastudio|
drive|doc|docs|
gcp|cloud|
geminiinworkspaceapps|gemini|geminiforworkspace|
gmail|
gplus|currents|google+|
groups|group|
groupsenterprise|enterprisegroups|
jamboard|

View File

@@ -80,6 +80,15 @@
<ColorValue> ::= <ColorName>|<ColorHex>
```
```
<CSVFileInput> ::=
((<FileName> [charset <Charset>] )|
(gsheet <UserGoogleSheet>)|
(gdoc <UserGoogleDoc>)|
(gcscsv <StorageBucketObjectName>)|
(gcsdoc <StorageBucketObjectName>))
[warnifnodata] [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
[endcsv|(fields <FieldNameList>)]
<JSONData> ::= (json [charset <Charset>] <String>) | (json file <FileName> [charset <Charset>]) |
<OrganizerType> ::= user|group
@@ -94,7 +103,8 @@
<REMatchPattern> ::= <RegularExpression>
<RESearchPattern> ::= <RegularExpression>
<RESubstitution> ::= <String>>
```
```
<DriveFileOrderByFieldName> ::=
createddate|createdtime|
folder|
@@ -649,15 +659,23 @@ When deleting permissions from JSON data, permissions with role `owner` true are
These commands are used to transfer ACLs from one Shared Drive to another.
* `copy` - Copy all ACLs from the source Shared Drive to the target Shared Drive. The role of an existing ACL in the target Shared Drive will never be reduced.
* `sync` - Add/delete/update ACLs in the target Shared Drive to match those in the source Shared Drive.
* `<UserTypeEntity>` - Not Specified
* All Shared Drives must be in the same workspace as the admin in `oauth2.txt`.
* `<UserTypeEntity>` - Specified
* `adminaccess|asadmin` specified - All Shared Drives must be in the same workspace as `<UserTypeEntity>`.
* `adminaccess|asadmin` not specified - Shared Drives can be in separate workspaces if `<UserTypeEntity>` in a manager of all of them.
```
gam [<UserTypeEntity>] copy shareddriveacls <SharedDriveEntity> to <SharedDriveEntity>
[showpermissionsmessages [<Boolean>]]
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
(mappermissionsemail <EmailAddress> <EmailAddress)* [mappermissionsemailfile <CSVFileInput> endcsv]
(mappermissionsdomain <DomainName> <DomainName>)*
[adminaccess|asadmin]
gam [<UserTypeEntity>] sync shareddriveacls <SharedDriveEntity> with <SharedDriveEntity>
[showpermissionsmessages [<Boolean>]]
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
(mappermissionsemail <EmailAddress> <EmailAddress)* [mappermissionsemailfile <CSVFileInput> endcsv]
(mappermissionsdomain <DomainName> <DomainName>)*
[adminaccess|asadmin]
```
@@ -665,8 +683,14 @@ When `excludepermissionsfromdomains <DomainNameList>` is specified, any ACL that
When `includepermissionsfromdomains <DomainNameList>` is specified, only ACLs that reference a domain in `<DomainNameList>` will be copied.
When `mappermissionsemail <EmailAddress> <EmailAddress>` is specifed, an ACL that references the first `<EmailAddress>` will be modified
to reference the second `<EmailAddress>` when copied; the original ACL is not modified. The option can be repeated if multiple email addresses are to be mapped.
Bulk permission email address mapping can be specified with `mappermissionsemailfile <CSVFileInput> endcsv`.
`<CSVFileInput>` must include these columns: `sourceEmail` and `destinationEmail`.
When `mappermissionsdomain <DomainName> <DomainName>` is specifed, any ACL that references the first `<DomainName>` will be modified
to reference the second `<DonainName>` when copied; the original ACL is not modified. The option can be repeated if multiple domain names are to me mapped.
to reference the second `<DomainName>` when copied; the original ACL is not modified. The option can be repeated if multiple domain names are to be mapped.
## Display Shared Drive access

View File

@@ -718,7 +718,7 @@ properly processed.
```
gam <UserTypeEntity> update calattendees <UserCalendarEntity> <EventEntity> [anyorganizer]
[<EventNotificationAttribute>] [splitupdate] [dryrun|doit]
(csv|csvfile <CSVFileInput>)
(csv|csvfile <CSVFileInput> endcsv)
(delete <EmailAddress>)*
(deleteentity <EmailAddressEntity>)*
(add <EmailAddress>)*

View File

@@ -288,11 +288,10 @@ By default, Gam displays the information as an indented list of keys and values.
gam <UserTypeEntity> print calendars [todrive <ToDriveAttribute>*]
[primary] <CalendarSelectProperty>*
[noprimary] [nogroups] [noresources] [nosystem] [nousers]
[fields <CalendarListFieldList>] [permissions]
[fields <CalendarListFieldList>] [permissions] [oneitemperrow]
[formatjson] [delimiter <Character>] [quotechar <Character>]
```
By default, information for all visible, non-deleted calendars is shown.
* `permissions` adds permission information for user owned calendars to the output.
* `primary` - Limits the selection to the user's primary calendar
* `<CalendarSelectProperty>`
* `minaccessrole <CalendarACLRole>`- Limits the selection to those calendars where the user's role is at least `<CalendarACLRole>`
@@ -303,6 +302,8 @@ By default, information for all visible, non-deleted calendars is shown.
* `noresources` - Do not display resource calendars, email address ends in "@resource.calendar.google.com"
* `nosystem` - Do not display system calendars, email address ends in "@group.v.calendar.google.com"
* `nousers` - Do not display users calendars, email address ends in `domain` value from `gam.cfg`.
* `permissions` Adds permission information for user owned calendars to the output.
* `oneitemperrow` - Each permission is output on a separate row with all of the other calendar fields.
By default, list items are separated by the `csv_output_field_delimiter' from `gam.cfg`.
* `delimiter <Character>` - Separate list items with `<Character>`

View File

@@ -26,6 +26,15 @@
* [`<UserTypeEntity>`](Collections-of-Users)
```
<CSVFileInput> ::=
((<FileName> [charset <Charset>] )|
(gsheet <UserGoogleSheet>)|
(gdoc <UserGoogleDoc>)|
(gcscsv <StorageBucketObjectName>)|
(gcsdoc <StorageBucketObjectName>))
[warnifnodata] [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
[endcsv|(fields <FieldNameList>)]
<RegularExpression> ::= <String>
See: https://docs.python.org/3/library/re.html
<REMatchPattern> ::= <RegularExpression>
@@ -38,7 +47,8 @@
<EmailAddress> ::= <String>@<DomainName>
<UniqueID> ::= id:<String>
<UserItem> ::= <EmailAddress>|<UniqueID>|<String>
```
```
<DriveFileACLRole> ::=
manager|organizer|owner|
contentmanager|fileorganizer|
@@ -114,6 +124,7 @@ gam <UserTypeEntity> copy drivefile <DriveFileEntity>
[copysheetprotectedrangesinheritedpermissions [<Boolean>]]
[copysheetprotectedrangesnoninheritedpermissions [<Boolean>]]
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
(mappermissionsemail <EmailAddress> <EmailAddress)* [mappermissionsemailfile <CSVFileInput> endcsv]
(mappermissionsdomain <DomainName> <DomainName>)*
[sendemailifrequired [<Boolean>]]
[verifyorganizer [<Boolean>]]
@@ -313,8 +324,14 @@ When `excludepermissionsfromdomains <DomainNameList>` is specified, any ACL that
When `includepermissionsfromdomains <DomainNameList>` is specified, only ACLs that reference a domain in `<DomainNameList>` will be copied.
When `mappermissionsemail <EmailAddress> <EmailAddress>` is specifed, an ACL that references the first `<EmailAddress>` will be modified
to reference the second `<EmailAddress>` when copied; the original ACL is not modified. The option can be repeated if multiple email addresses are to be mapped.
Bulk permission email address mapping can be specified with `mappermissionsemailfile <CSVFileInput> endcsv`.
`<CSVFileInput>` must include these columns: `sourceEmail` and `destinationEmail`.
When `mappermissionsdomain <DomainName> <DomainName>` is specified, any ACL that references the first `<DomainName>` will be modified
to reference the second `<DomainName>` when copied; the original ACL is not modified. The option can be repeated if multiple domain names are to me mapped.
to reference the second `<DomainName>` when copied; the original ACL is not modified. The option can be repeated if multiple domain names are to be mapped.
When copying an ACL that references a non Google account, an error is generated unless an email is sent to the account;
by default, no email notifications are sent. The `sendemailifrequired` options instructs GAM to send an email notification in this case.
@@ -542,8 +559,8 @@ gam <UserTypeEntity> move drivefile <DriveFileEntity> [newfilename <DriveFileNam
[copysubfolderinheritedpermissions [<Boolean>]]
[copysubfoldernoninheritedpermissions never|always|syncallfolders|syncupdatedfolders]
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
(mappermissionsemail <EmailAddress> <EmailAddress)* [mappermissionsemailfile <CSVFileInput> endcsv]
(mappermissionsdomain <DomainName> <DomainName>)*
[updatefilepermissions [<Boolean>]]
[retainsourcefolders [<Boolean>]]
[sendemailifrequired [<Boolean>]]
[verifyorganizer [<Boolean>]]
@@ -666,8 +683,14 @@ When `excludepermissionsfromdomains <DomainNameList>` is specified, any ACL that
When `includepermissionsfromdomains <DomainNameList>` is specified, only ACLs that reference a domain in `<DomainNameList>` will be copied.
When `mappermissionsemail <EmailAddress> <EmailAddress>` is specifed, an ACL that references the first `<EmailAddress>` will be modified
to reference the second `<EmailAddress>` when copied; the original ACL is not modified. The option can be repeated if multiple email addresses are to be mapped.
Bulk permission email address mapping can ge specified with `mappermissionsemailfile <CSVFileInput> endcsv`.
`<CSVFileInput>` must include these columns: `sourceEmail` and `destinationEmail`.
When `mappermissionsdomain <DomainName> <DomainName>` is specified, any ACL that references the first `<DomainName>` will be modified
to reference the second `<DomainName>` when copied; the original ACL is not modified. The option can be repeated if multiple domain names are to me mapped.
to reference the second `<DomainName>` when copied; the original ACL is not modified. The option can be repeated if multiple domain names are to be mapped.
When copying an ACL that references a non Google account, an error is generated unless an email is sent to the account;
by default, no email notifications are sent. The `sendemailifrequired` options instructs GAM to send an email notification in this case.
@@ -684,8 +707,14 @@ When `excludepermissionsfromdomains <DomainNameList>` is specified, any ACL that
When `includepermissionsfromdomains <DomainNameList>` is specified, any ACLs that references a domain not in `<DomainNameList>` will be removed.
When `mappermissionsemail <EmailAddress> <EmailAddress>` is specifed, an ACL that references the first `<EmailAddress>` will be removed;
a new ACL with the same properties referencing the second `<EmailAddess>` will be created. The option can be repeated if multiple domain names are to be mapped.
Bulk email address mapping can ge specified with `mappermissionsemailfile <CSVFileInput> endcsv`.
`<CSVFileInput>` must include these columns: `sourceEmail` and `destinationEmail`.
When `mappermissionsdomain <DomainName> <DomainName>` is specified, any ACL that references the first `<DomainName>` will be removed;
a new ACL with the same properties referencing the second `<DomainName>` will be created. The option can be repeated if multiple domain names are to me mapped.
a new ACL with the same properties referencing the second `<DomainName>` will be created. The option can be repeated if multiple domain names are to be mapped.
When creating an ACL that references a non Google account, an error is generated unless an email is sent to the account;
by default, no email notifications are sent. The `sendemailifrequired` options instructs GAM to send an email notification in this case.

View File

@@ -234,7 +234,6 @@ The option `updatesheetprotectedranges` only applies to items in `<DriveFileEnti
* ACLs with role reader or commenter will be removed from existing protected ranges
* ACLs with role writer or higher will be added to existing protected ranges
`
`enforceexpansiveaccess` defaults to the value of `gam.cfg/enforce_expansive_access` that controls
the ability to update inherited ACLs.
* False - Inherited ACLs can be updated
@@ -261,7 +260,7 @@ The option `updatesheetprotectedranges` only applies to items in `<DriveFileEnti
* ACLs with any role will be removed from existing protected ranges
`enforceexpansiveaccess` defaults to the value of `gam.cfg/enforce_expansive_access` that controls
the ability to delete delete inherited ACLs.
the ability to delete inherited ACLs.
* False - Inherited ACLs can be deleted
* True = Inherited ACLs can not be deleted
@@ -308,7 +307,7 @@ gam <UserTypeEntity> delete permissions <DriveFileEntity> <DriveFilePermissionID
[enforceexpansiveaccess [<Boolean>]]
```
`enforceexpansiveaccess` defaults to the value of `gam.cfg/enforce_expansive_access` that controls
the ability to delete delete inherited ACLs.
the ability to delete inherited ACLs.
* False - Inherited ACLs can be deleted
* True = Inherited ACLs can not be deleted

View File

@@ -589,9 +589,9 @@ gam <UserTypeEntity> show messages|threads
[labelids <LabelIDList>]
[quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <MessageIDEntity>)
[labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
[countsonly|positivecountsonly] [useronly]
[countsonly|positivecountsonly]
[headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
[showlabels] [delimiter <Character>] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
[showlabels] [useronly] [delimiter <Character>] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
[maxmessagesperthread <Number>]
[showattachments [attachmentnamepattern <REMatchPattern>>] [noshowtextplain]]
[saveattachments [attachmentnamepattern <REMatchPattern>>]]
@@ -601,12 +601,13 @@ gam <UserTypeEntity> print messages|threads [todrive <ToDriveAttribute>*]
[labelids <LabelIDList>]
[quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <MessageIDEntity>)
[labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
[countsonly|positivecountsonly] [useronly]
[countsonly|positivecountsonly]
[headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
[showlabels] [delimiter <Character>] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
[showlabels] [useronly] [delimiter <Character>] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
[maxmessagesperthread <Number>]
[showattachments [attachmentnamepattern <REMatchPattern>>]]
[convertcrnl]
(addcsvdata <FieldName> <String>)*
```
## Display all messages
By default, Gam displays all messages.
@@ -692,6 +693,7 @@ The `dateheaderconverttimezone [<Boolean>]>` option converts `<SMTPDateHeader>`
## Print only options
These options are valid with `print`.
* `convertcrnl` - In the message body, convert carriage returns to `\r` and newlines to `\n`; the default value is `csv_output_convert_cr_nl` from `gam.cfg`.
* `addcsvdata <FieldName> <String>` - Add additional columns of data from the command line to the output
By default, message attachment information is not displayed.
* `showattachments` - Display attachment filename, MIME type and size

View File

@@ -15,6 +15,7 @@
- [Display Shared Drive Counts](#display-shared-drive-counts)
- [Display Shared Drive Organizers](#display-shared-drive-organizers)
- [Manage Shared Drive access](#manage-shared-drive-access)
- [Transfer Shared Drive access](#transfer-shared-drive-access)
- [Display Shared Drive access](#display-shared-drive-access)
- [Display Shared Drive access for specific Shared Drives](#display-shared-drive-access-for-specific-shared-drives)
- [Display Shared Drive access for selected Shared Drives](#display-shared-drive-access-for-selected-shared-drives)
@@ -72,6 +73,15 @@
<ColorValue> ::= <ColorName>|<ColorHex>
```
```
<CSVFileInput> ::=
((<FileName> [charset <Charset>] )|
(gsheet <UserGoogleSheet>)|
(gdoc <UserGoogleDoc>)|
(gcscsv <StorageBucketObjectName>)|
(gcsdoc <StorageBucketObjectName>))
[warnifnodata] [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
[endcsv|(fields <FieldNameList>)]
<JSONData> ::= (json [charset <Charset>] <String>) | (json file <FileName> [charset <Charset>]) |
<OrganizerType> ::= user|group
@@ -86,7 +96,8 @@
<REMatchPattern> ::= <RegularExpression>
<RESearchPattern> ::= <RegularExpression>
<RESubstitution> ::= <String>>
```
```
<DriveFileOrderByFieldName> ::=
createddate|createdtime|
folder|
@@ -516,6 +527,40 @@ When adding permissions from JSON data, permissions with `deleted` true are neve
When deleting permissions from JSON data, permissions with role `owner` true are never processed.
## Transfer Shared Drive access
These commands are used to transfer ACLs from one Shared Drive to another.
* `copy` - Copy all ACLs from the source Shared Drive to the target Shared Drive. The role of an existing ACL in the target Shared Drive will never be reduced.
* `sync` - Add/delete/update ACLs in the target Shared Drive to match those in the source Shared Drive.
* `adminaccess|asadmin` specified - All Shared Drives must be in the same workspace as `<UserTypeEntity>`.
* `adminaccess|asadmin` not specified - Shared Drives can be in separate workspaces if `<UserTypeEntity>` in a manager of all of them.
```
gam <UserTypeEntity> copy shareddriveacls <SharedDriveEntity> to <SharedDriveEntity>
[showpermissionsmessages [<Boolean>]]
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
(mappermissionsemail <EmailAddress> <EmailAddress)* [mappermissionsemailfile <CSVFileInput> endcsv]
(mappermissionsdomain <DomainName> <DomainName>)*
[adminaccess|asadmin]
gam <UserTypeEntity> sync shareddriveacls <SharedDriveEntity> with <SharedDriveEntity>
[showpermissionsmessages [<Boolean>]]
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
(mappermissionsemail <EmailAddress> <EmailAddress)* [mappermissionsemailfile <CSVFileInput> endcsv]
(mappermissionsdomain <DomainName> <DomainName>)*
[adminaccess|asadmin]
```
When `excludepermissionsfromdomains <DomainNameList>` is specified, any ACL that references a domain in `<DomainNameList>` will not be copied.
When `includepermissionsfromdomains <DomainNameList>` is specified, only ACLs that reference a domain in `<DomainNameList>` will be copied.
When `mappermissionsemail <EmailAddress> <EmailAddress>` is specifed, an ACL that references the first `<EmailAddress>` will be modified
to reference the second `<EmailAddress>` when copied; the original ACL is not modified. The option can be repeated if multiple email addresses are to be mapped.
Bulk permission email address mapping can be specified with `mappermissionsemailfile <CSVFileInput> endcsv`.
`<CSVFileInput>` must include these columns: `sourceEmail` and `destinationEmail`.
When `mappermissionsdomain <DomainName> <DomainName>` is specifed, any ACL that references the first `<DomainName>` will be modified
to reference the second `<DomainName>` when copied; the original ACL is not modified. The option can be repeated if multiple domain names are to be mapped.
## Display Shared Drive access
These commands are used to display the ACLs on Shared Drives themselves, not the files/folders on the Shared Drives.

View File

@@ -29,23 +29,32 @@ No, because the YubiKey generated the private key it cannot be digitally exporte
When using domain-wide delegation with GAM7, 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 the [latest version of GAM7](https://github.com/GAM-team/GAM/wiki/How-to-Update-GAM7).
2. **If you are using a new YubiKey or don't care about the PIV app data on the YubiKey**
1. Tell GAM7 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 GAM7.
1. Upgrade to the [latest version of GAM7](https://github.com/GAM-team/GAM/wiki/How-to-Update-GAM7).
2. If you are using a new YubiKey or don't care about the PIV app data on the YubiKey:
a. Tell GAM7 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 GAM7.
* Single YubiKey - `gam yubikey reset_piv`
* Multiple YubiKeys - `gam yubikey reset_piv yubikeyserialnumber <Number>`
2. During the PIV reset, GAM7 will print out a PIN for the private key, record this key.
4. **If you are already using the YubiKey and wish to preserve the PIV app data and keys**
1. You need to configure one of the PIV slots for a private key GAM7 can use.
b. During the PIV reset, GAM7 will print out a PIN for the private key, record this key.
3. OR if you are already using the YubiKey and wish to preserve the PIV app data and keys
a. You need to configure one of the PIV slots for a private key GAM7 can use.
* [ykman piv keys generate](https://docs.yubico.com/software/yubikey/tools/ykman/PIV_Commands.html#ykman-piv-keys-options-command-args)
`ykman piv keys generate -P <Text> --pin-policy ALWAYS --touch-policy NEVER --algorithm RSA2048 9a new_pubkey.txt`
* Use `9a` for the `AUTHENTICATION` slot, `9c` for the `SIGNATURE` slot
2. You need to generate a certificate for that slot.
b. You need to generate a certificate for that slot.
* [ykman piv certificates generate](https://docs.yubico.com/software/yubikey/tools/ykman/PIV_Commands.html#ykman-piv-certificates-generate-options-slot-public-key)
`ykman piv certificates generate -P <Text> --subject "GAM Service Account" -d 36500 9a new_pubkey.txt`
* Use `9a` for the `AUTHENTICATION` slot, `9c` for the `SIGNATURE` slot
5. Now that you have a private key on your YubiKey, tell GAM7 to use that instead of the private_key stored in oauth2service.json. We can do that by rotating the key:
4. Now that you have a private key on your YubiKey, tell GAM7 to use that instead of the private_key stored in oauth2service.json. We can do that by rotating the key:
```
copy oauth2service.json to oauth2service.save
gam create sakey yubikey yubikey_pin yubikey_slot AUTHENTICATION|SIGNATURE
@@ -58,10 +67,10 @@ copy oauth2service.json to oauth2service.yk
copy oauth2service.save to oauth2service.json
```
6. Now you should be able to run GAM7 commands like:
5. Now you should be able to run GAM7 commands like:
```
gam user admin@example.com check serviceaccount
```
and see the YubiKey lights flash as the YubiKey interacts with GAM7 to sign the GAM7 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 GAM7 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.
6. 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.

View File

@@ -3,9 +3,9 @@
Print the current version of Gam with details
```
gam version
GAM 7.28.07 - https://github.com/GAM-team/GAM - pyinstaller
GAM 7.29.03 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.0 64-bit final
Python 3.14.1 64-bit final
macOS Tahoe 26.1 x86_64
Path: /Users/Admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
@@ -15,9 +15,9 @@ Time: 2023-06-02T21:10:00-07:00
Print the current version of Gam with details and time offset information
```
gam version timeoffset
GAM 7.28.07 - https://github.com/GAM-team/GAM - pyinstaller
GAM 7.29.03 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.0 64-bit final
Python 3.14.1 64-bit final
macOS Tahoe 26.1 x86_64
Path: /Users/Admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
@@ -27,9 +27,9 @@ Your system time differs from www.googleapis.com by less than 1 second
Print the current version of Gam with extended details and SSL information
```
gam version extended
GAM 7.28.07 - https://github.com/GAM-team/GAM - pyinstaller
GAM 7.29.03 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.0 64-bit final
Python 3.14.1 64-bit final
macOS Tahoe 26.1 x86_64
Path: /Users/Admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
@@ -68,7 +68,7 @@ MacOS High Sierra 10.13.6 x86_64
Path: /Users/Admin/bin/gam7
Version Check:
Current: 5.35.08
Latest: 7.28.07
Latest: 7.29.03
echo $?
1
```
@@ -76,7 +76,7 @@ echo $?
Print the current version number without details
```
gam version simple
7.28.07
7.29.03
```
In Linux/MacOS you can do:
```
@@ -86,9 +86,9 @@ echo $VER
Print the current version of Gam and address of this Wiki
```
gam help
GAM 7.28.07 - https://github.com/GAM-team/GAM
GAM 7.29.03 - https://github.com/GAM-team/GAM
GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.0 64-bit final
Python 3.14.1 64-bit final
macOS Tahoe 26.1 x86_64
Path: /Users/Admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com

View File

@@ -2,6 +2,7 @@
- [Introduction](#introduction)
- [Variables](#variables)
- [Multiple Computers](#multiple-computers)
- [Separate Staff-Student Domains](#separate-staff-student-domains)
- [Multiple Customers and Domains](#multiple-customers-and-domains)
- [Multiple Users-Projects on One Computer](#multiple-users-projects-on-one-computer)
@@ -564,10 +565,10 @@ timezone
to your local timezone. If you are running GAM on a remote computer or on a
cloud shell, "local" will mean the time at the remote/cloud shell computer,
not your location, Use "+|-hh:mm" to specify the timezone at your location.
Starting with version 7.21.00 you can use a timezone name.
Starting with version 7.21.00 you can use a timezone name; the names are case sensitive.
See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
Default: utc
Range: utc|z|local|(+|-hh:mm)I<ValidTimezoneName>
Range: utc|z|local|(+|-hh:mm)|<ValidTimezoneName>
tls_max_version
Allowed values: '', tlsv1_2, tlsv1.2, tlsv1_3, tlsv1.3
The maximum TLS version to use in https connections
@@ -621,7 +622,7 @@ todrive_timeformat
Default: '' which selects an ISO format timestamp
Example: %Y-%m-%dT%H:%M:%S will display as 2020-07-06T17:48:54
todrive_timezone
The Spreadsheet settings Timezone value.
The Spreadsheet settings Timezone value; the values are case sensitive.
See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
Default: ''
todrive_upload_nodata
@@ -816,6 +817,26 @@ Edit `gam.cfg` on the other computer
* config_dir
* drive_dir
## Separate Staff-Student Domains
Suppose you have a single workspace with separate staff and student domains; e.g., school.org and students.school.org.
You can simplifiy typing email addresses by making two sections.
```
[DEFAULT]
customer_id = C1234567
[staff]
domain = school.org
[students]
domain = students.school.org
```
To issue commands about staff users, do: `gam config staff save`
Subsequent commands can omit `@school.org` from email addresses, GAM will supply `@school.org`.
To issue commands about student users, do: `gam config students save`
Subsequent commands can omit `@students.school.org` from email addresses, GAM will supply `@students.school.org`.
You can always type a complete email address if desired.
## Multiple Customers and Domains
There are four arguments to GAM that should simplify how you use GAM with multiple clients/domains.
Each client/domain will have a section in gam.cfg that sets the values specific to it.