Compare commits

...

37 Commits

Author SHA1 Message Date
Ross Scroggs
0c593b5809 Add new <CrOSFieldName>
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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
2026-06-01 11:59:32 -07:00
Ross Scroggs
d76ef999c5 Add new <CrOSFieldName> 2026-06-01 11:22:14 -07:00
Ross Scroggs
ddaad4d655 Add new <CrOSFieldName>s 2026-06-01 09:26:16 -07:00
Ross Scroggs
36a1bdc56b 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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Push wiki / pushwiki (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
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
2026-05-29 19:49:25 -07:00
Ross Scroggs
089a5994aa Merge branch 'main' of https://github.com/GAM-team/GAM 2026-05-29 19:44:55 -07:00
Ross Scroggs
3e9b46b650 Update gam print crostelemetry 2026-05-29 19:44:49 -07:00
github-actions[bot]
7ca3b4d7da chore: upgrade PyPi deps (#1921)
Co-authored-by: jay0lee <4623536+jay0lee@users.noreply.github.com>
2026-05-29 22:19:35 -04:00
Ross Scroggs
22d70ca2c3 Update gam print crostelemetry 2026-05-29 18:32:49 -07:00
Ross Scroggs
b3acdf5955 Update Cloud-Identity-Devices.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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
2026-05-29 10:25:39 -07:00
Ross Scroggs
c13a5215fe Update Other-Resources.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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2026-05-28 08:28:04 -07:00
Ross Scroggs
45750b591a Update Users-Chat.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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2026-05-27 13:06:33 -07:00
Ross Scroggs
c76f1b2128 Update Users-Chat.md 2026-05-27 13:04:46 -07:00
Ross Scroggs
e85e7f6868 Update Command-Line-Parsing.md 2026-05-27 12:53:56 -07:00
Ross Scroggs
055c74ed2e chat message searching, user attributes, license cleanup 4ba9385c 2026-05-27 12:24:10 -07:00
Ross Scroggs
4ba9385c23 chat message searching, user attributes, license cleanup
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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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
CodeQL / Analyze (python) (push) Has been cancelled
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
2026-05-27 11:15:31 -07:00
Jay Lee
9d8442c7ad It's CIF, not CI
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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
2026-05-26 16:16:48 +00:00
Jay Lee
cc19878ba4 Merge branch 'main' of https://github.com/GAM-team/GAM 2026-05-26 16:15:09 +00:00
Jay Lee
23ed20a298 user suspend/archive time support. #1920 2026-05-26 16:15:03 +00:00
Jay Lee
5b32bc31c7 actions: rebuild for Python 3.14.5
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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
CodeQL / Analyze (python) (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
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
2026-05-23 19:02:09 -04:00
Ross Scroggs
e1260dbd95 Updated/fixed gam <UserTypeEntity> forward message|thread
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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
2026-05-22 17:54:00 -07:00
Ross Scroggs
ea41edbfcb Updated/fixed gam <UserTypeEntity> forward message|thread
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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2026-05-22 16:11:28 -07:00
Ross Scroggs
869eb3a0c2 Updated/fixed gam <UserTypeEntity> forward message|thread 2026-05-22 15:59:35 -07:00
Ross Scroggs
61735701b3 Fixed bug in gam <UserTypeEntity> print filelist that caused a trap. 2026-05-22 10:29:44 -07:00
Ross Scroggs
c60ef582be Fixed bug in gam <UserTypeEntity> print filelist that caused a trap. 2026-05-22 09:29:52 -07:00
github-actions[bot]
cd8c43a0cc chore: upgrade PyPi deps (#1919)
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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
Co-authored-by: jay0lee <4623536+jay0lee@users.noreply.github.com>
2026-05-22 02:06:13 -04:00
github-actions[bot]
7582c42eff chore: upgrade PyPi deps (#1918)
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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
Co-authored-by: jay0lee <4623536+jay0lee@users.noreply.github.com>
2026-05-21 00:17:04 -04:00
Ross Scroggs
d9a75af87c Fixed bug and formatting issues in gam info device <DeviceEntity>.
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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2026-05-20 11:55:52 -07:00
Ross Scroggs
6c443fa0c6 Fixed bug and formatting issues in gam info device <DeviceEntity>. 2026-05-20 11:10:05 -07:00
github-actions[bot]
b6a9229a67 chore: upgrade PyPi deps (#1917)
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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Push wiki / pushwiki (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
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
Co-authored-by: jay0lee <4623536+jay0lee@users.noreply.github.com>
2026-05-19 01:27:08 -04:00
Ross Scroggs
84175ba80d Improve device query validation 2026-05-18 19:01:57 -07:00
Ross Scroggs
56c2b77f25 Improve device query validation 2026-05-18 17:38:49 -07:00
Ross Scroggs
dfe01e5272 Validate device queries 2026-05-18 16:56:56 -07:00
Jay Lee
e25c302616 Uncomment artifact archiving step in build workflow 2026-05-18 19:16:05 -04:00
Ross Scroggs
1ca5b1a610 Validate device queries
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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
2026-05-18 15:07:12 -07:00
Ross Scroggs
b9c81e2e24 Update Domains.md 2026-05-18 07:26:20 -07:00
Ross Scroggs
9766fa42e7 Update ChromeOS-Devices.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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2026-05-16 17:51:29 -07:00
Ross Scroggs
7bd150e5bf Added option max_to_deprov <Integer> to gam update cros <CrOSEntity> action
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 x86_64 macOS 26, macos-26-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Intel Windows, windows-2025-vs2026) (push) Has been cancelled
Build and test GAM / build (false, build, 14, 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, 15, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 18, Test Python 3.13, ubuntu-24.04, 3.13) (push) Has been cancelled
Build and test GAM / build (false, test, 19, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 20, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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
Daily Dependency Pinning (2-Week Buffer) / pin-deps (push) Has been cancelled
2026-05-15 22:59:23 -07:00
23 changed files with 733 additions and 166 deletions

View File

@@ -165,7 +165,7 @@ jobs:
with: with:
path: | path: |
cache.tar.xz cache.tar.xz
key: gam-${{ matrix.jid }}-20260508 key: gam-${{ matrix.jid }}-20260523
- name: Untar Cache archive - name: Untar Cache archive
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true' if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true'
@@ -713,16 +713,16 @@ jobs:
write-host "sleeping during login..." write-host "sleeping during login..."
Start-Sleep 10 Start-Sleep 10
# - name: Archive artifacts - name: Archive artifacts
# uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # 7.0.0 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # 7.0.0
# if: runner.os == 'Windows' if: runner.os == 'Windows'
# with: with:
# archive: true archive: true
# name: images-${{ matrix.os }} name: images-${{ matrix.os }}
# if-no-files-found: ignore if-no-files-found: ignore
# path: | path: |
# ${{ github.workspace }}/*.png ${{ github.workspace }}/*.png
# ${{ github.workspace }}/*.log ${{ github.workspace }}/*.log
- name: Sign gam.exe - name: Sign gam.exe
if: runner.os == 'Windows' if: runner.os == 'Windows'

View File

@@ -10,13 +10,13 @@ authors = [
dependencies = [ dependencies = [
"arrow==1.4.0", "arrow==1.4.0",
"chardet==7.4.3", "chardet==7.4.3",
"cryptography==47.0.0", "cryptography==48.0.0",
"distro==1.9.0 ; sys_platform=='linux'", "distro==1.9.0 ; sys_platform=='linux'",
"filelock==3.29.0", "filelock==3.29.0",
"google-api-python-client==2.195.0", "google-api-python-client==2.196.0",
"google-auth-httplib2==0.3.1", "google-auth-httplib2==0.4.0",
"google-auth-oauthlib==1.3.1", "google-auth-oauthlib==1.4.0",
"google-auth==2.50.0", "google-auth==2.53.0",
"httplib2==0.31.2", "httplib2==0.31.2",
"lxml==6.1.0", "lxml==6.1.0",
"passlib==1.7.4", "passlib==1.7.4",

View File

@@ -270,7 +270,7 @@ If an item contains spaces, it should be surrounded by ".
assuredcontrolsplus | 1010390002 | Assured Controls Plus | assuredcontrolsplus | 1010390002 | Assured Controls Plus |
bce | beyondcorp | beyondcorpenterprise | cep | chromeenterprisepremium | 1010400001 | Chrome Enterprise Premium | bce | beyondcorp | beyondcorpenterprise | cep | chromeenterprisepremium | 1010400001 | Chrome Enterprise Premium |
cdm | chrome | googlechromedevicemanagement | Google-Chrome-Device-Management | cdm | chrome | googlechromedevicemanagement | Google-Chrome-Device-Management |
cloudidentity | identity | 1010010001 | Cloud Identity | cloudidentityfree | cloudidentity | identity | 1010010001 | Cloud Identity Free |
cloudidentitypremium | identitypremium | 1010050001 | Cloud Identity Premium | cloudidentitypremium | identitypremium | 1010050001 | Cloud Identity Premium |
cloudsearch | 1010350001 | Cloud Search | cloudsearch | 1010350001 | Cloud Search |
colabpro | 1010500001 | Colab Pro | colabpro | 1010500001 | Colab Pro |
@@ -560,9 +560,9 @@ If an item contains spaces, it should be surrounded by ".
See: https://cloud.google.com/access-context-manager/docs/custom-access-level-spec See: https://cloud.google.com/access-context-manager/docs/custom-access-level-spec
<QueryContact> ::= <String> <QueryContact> ::= <String>
See: https://developers.google.com/google-apps/contacts/v3/reference#contacts-query-parameters-reference See: https://developers.google.com/google-apps/contacts/v3/reference#contacts-query-parameters-reference
<QueryCrOS> ::= <String> <QueryCrOS> ::= <String>:<String>
See: https://support.google.com/chrome/a/answer/1698333 See: https://support.google.com/chrome/a/answer/1698333
<QueryDevice> ::= <String> <QueryDevice> ::= <String>:<String>
See: https://support.google.com/a/answer/7549103 See: https://support.google.com/a/answer/7549103
<QueryDriveFile> ::= <String> <QueryDriveFile> ::= <String>
See: https://developers.google.com/drive/api/v3/search-files See: https://developers.google.com/drive/api/v3/search-files
@@ -575,7 +575,7 @@ If an item contains spaces, it should be surrounded by ".
<QueryItem> ::= <UniqueID>|<String> <QueryItem> ::= <UniqueID>|<String>
<QueryMemberRestrictions> ::= <String> <QueryMemberRestrictions> ::= <String>
See: https://cloud.google.com/identity/docs/reference/rest/v1beta1/SecuritySettings#MemberRestriction See: https://cloud.google.com/identity/docs/reference/rest/v1beta1/SecuritySettings#MemberRestriction
<QueryMobile> ::= <String> <QueryMobile> ::= <String>:<String>
See: https://support.google.com/a/answer/7549103 See: https://support.google.com/a/answer/7549103
<QueryTeamDrive> ::= <String> <QueryTeamDrive> ::= <String>
See: https://developers.google.com/drive/api/v3/search-parameters See: https://developers.google.com/drive/api/v3/search-parameters
@@ -2511,6 +2511,7 @@ gam <CrOSTypeEntity> update <CrOSAttribute>+ [quickcrosmove [<Boolean>]] [nobatc
autoupdateexpiration| autoupdateexpiration|
autoupdatethrough| autoupdatethrough|
backlightinfo| backlightinfo|
bluetoothadapterinfo|
bootmode| bootmode|
chromeostype| chromeostype|
cpuinfo| cpuinfo|
@@ -2544,6 +2545,7 @@ gam <CrOSTypeEntity> update <CrOSAttribute>+ [quickcrosmove [<Boolean>]] [nobatc
orgunitpath|org|ou| orgunitpath|org|ou|
osupdatestatus| osupdatestatus|
osversion| osversion|
osversioncompliance|
platformversion| platformversion|
recentusers| recentusers|
screenshotfiles| screenshotfiles|
@@ -2725,25 +2727,30 @@ gam <CrOSTypeEntity> get devicefile [select <DeviceFileEntity>] [targetfolder <F
Print telemetry data for specified CrOS devices. Print telemetry data for specified CrOS devices.
<CrOSTelemetryFieldName> ::= <CrOSTelemetryFieldName> ::=
appreport|
audiostatusreport| audiostatusreport|
batteryinfo| batteryinfo|
batterystatusreport| batterystatusreport|
bootPerformancereport| bootperformancereport|
cpuinfo| cpuinfo|
cpustatusreport| cpustatusreport|
customer| customer|
deviceid| deviceid|
graphicsinfo| graphicsinfo|
graphicsstatusreport| graphicsstatusreport|
heartbeatstatusreport|
kioskappstatusreport|
memoryinfo| memoryinfo|
memorystatusreport| memorystatusreport|
name| name|
networkbandwidthreport|
networkdiagnosticsreport| networkdiagnosticsreport|
networkinfo| networkinfo|
networkstatusreport| networkstatusreport|
orgunitid| orgunitid|
osupdatestatus| osupdatestatus|
peripheralsreport| peripheralsreport|
runtimecountersreport|
serialnumber| serialnumber|
storageinfo| storageinfo|
storagestatusreport| storagestatusreport|
@@ -2751,20 +2758,22 @@ Print telemetry data for specified CrOS devices.
<CrOSTelemetryFieldNameList> ::= "<CrOSTelemetryFieldName>(,<CrOSTelemetryFieldName>)*" <CrOSTelemetryFieldNameList> ::= "<CrOSTelemetryFieldName>(,<CrOSTelemetryFieldName>)*"
<CrOSTelemetryListFieldName> ::= <CrOSTelemetryListFieldName> ::=
appreport|
audiostatusreport| audiostatusreport|
batteryinfo|
batterystatusreport| batterystatusreport|
bootperformancereport| bootperformancereport|
cpuinfo|
cpustatusreport| cpustatusreport|
graphicsstatusreport| graphicsstatusreport|
heartbeatstatusreport|
kioskappstatusreport|
memorystatusreport| memorystatusreport|
networkbandwidthreport|
networkdiagnosticsreport| networkdiagnosticsreport|
networkstatusreport| networkstatusreport|
osupdatestatus| osupdatestatus|
peripheralsreport| peripheralsreport|
storagestatusreport| runtimecountersreport|
thunderboltinfo storagestatusreport
<CrOSTelemetryListFieldNameList> ::= "<CrOSTelemetryListFieldName>(,<CrOSTelemetryLIstFieldName>)*" <CrOSTelemetryListFieldNameList> ::= "<CrOSTelemetryListFieldName>(,<CrOSTelemetryLIstFieldName>)*"
gam info crostelemetry <SerialNumber> gam info crostelemetry <SerialNumber>
@@ -2781,7 +2790,7 @@ gam show crostelemetry
gam print crostelemetry [todrive <ToDriveAttribute>*] gam print crostelemetry [todrive <ToDriveAttribute>*]
[(ou|org|orgunit|ou_and_children <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)] [(ou|org|orgunit|ou_and_children <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)]
<CrOSTelemetryFieldName>* [fields <CrOSTelemetryFieldNameList>] <CrOSTelemetryFieldName>* [fields <CrOSTelemetryFieldNameList>]
[reverselists <CrOSTelemetryListFieldNameList>] [reverselists <CrOSTelemetryListFieldNameList>] [oneitemperrow]
[start <Date>] [end <Date>] [listlimit <Number>] [start <Date>] [end <Date>] [listlimit <Number>]
[formatjson [quotechar <Character>]] [formatjson [quotechar <Character>]]
@@ -6768,13 +6777,41 @@ gam <UserTypeEntity> info chatmessage name <ChatMessage>
[formatjson] [formatjson]
gam <UserTypeEntity> show chatmessages gam <UserTypeEntity> show chatmessages
<ChatSpace>+ <ChatSpace>+
[showdeleted [<Boolean>]] [filter <String>] [showdeleted [<Boolean>]
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
[fields <ChatMessageFieldNameList>] [fields <ChatMessageFieldNameList>]
[orderby createtime [ascending|descending]]
[formatjson] [formatjson]
gam <UserTypeEntity> print chatmessages [todrive <ToDriveAttribute>*] gam <UserTypeEntity> print chatmessages [todrive <ToDriveAttribute>*]
<ChatSpace>+ <ChatSpace>+
[showdeleted [<Boolean>]] [filter <String>] [showdeleted [<Boolean>]
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
[thread <ChatThread>])
[fields <ChatMessageFieldNameList>] [fields <ChatMessageFieldNameList>]
[orderby createtime [ascending|descending]]
[formatjson [quotechar <Character>]]
gam <UserTypeEntity> show chatsearchmessages
keywords <StringList>
<ChatSpace>*
[displaynames [all|any] <StringList>]
[senders <EmailAddressEntity>]*
[usermentions [all|any] <EmailAddressEntity>]*
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
[hasattachment]
[fields <ChatMessageFieldNameList>]
[orderby createtime|relevance]
[formatjson]
gam <UserTypeEntity> print chatsearchmessages [todrive <ToDriveAttribute>*]
keywords <StringList>
<ChatSpace>*
[displaynames [all|any] <StringList>]
[senders <EmailAddressEntity>]*
[usermentions [all|any] <EmailAddressEntity>]*
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
[hasattachment]
[fields <ChatMessageFieldNameList>]
[orderby createtime|relevance]
[formatjson [quotechar <Character>]] [formatjson [quotechar <Character>]]
gam <UserTypeEntity> info chatevent name <ChatEvent> gam <UserTypeEntity> info chatevent name <ChatEvent>
@@ -8031,12 +8068,12 @@ gam <UserTypeEntity> export thread|threads
[quick|notquick] [doit] [max_to_export <Number>])|(ids <ThreadIDEntity>) [quick|notquick] [doit] [max_to_export <Number>])|(ids <ThreadIDEntity>)
[targetfolder <FilePath>] [targetname <FileName>] [overwrite [<Boolean>]] [targetfolder <FilePath>] [targetname <FileName>] [overwrite [<Boolean>]]
gam <UserTypeEntity> forward message|messages recipient|to <RecipientEntity> gam <UserTypeEntity> forward message|messages [recipient|to] <RecipientEntity>
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[labelids <LabelIDList>] [labelids <LabelIDList>]
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <MessageIDEntity>) [quick|notquick] [doit] [max_to_forward <Number>])|(ids <MessageIDEntity>)
[subject <String>] [addorigfieldstosubject [<Boolean>]] [altcharset <String>] [subject <String>] [addorigfieldstosubject [<Boolean>]] [altcharset <String>]
gam <UserTypeEntity> forward thread|thtreads recipient|to <RecipientEntity> gam <UserTypeEntity> forward thread|thtreads [recipient|to] <RecipientEntity>
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[labelids <LabelIDList>] [labelids <LabelIDList>]
quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>) quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>)

View File

@@ -1,3 +1,72 @@
7.44.02
Added fields `bluetoothadapterinfo` and `osversioncompliance` to `<CrOSFieldName>` for use
in `gam info|print cros`.
7.44.01
Added option `oneitemperrow` to `gam print crostelemetry` to have each of a device's
report field entries displayed on a separate row with all of the other device fields.
Added additional fields to `<CrOSTelemetryFieldName>`and `<CrOSTelemetryListFieldName>`:
```
appreport
heartbeatstatusreport
kioskappstatusreport
networkbandwidthreport
runtimecountersreport
```
7.44.00
Added support for User data `archivalTime` and `suspensionTime` that is available
when fields `archived` and `suspended` are requested in `gam info user` and `gam print users`.
Added the following options to `gam <UserTypeEntity> show chatmessages` to simplify specifying a filter.
```
start|starttime <Date>|<Time>
end|endtime <Date>|<Time>
range <Date>|<Time> <Date>|<Time>
thread <ChatThread>
```
Added commands to search for and display chat messages.
* See: https://github.com/GAM-team/GAM/wiki/Users-Chat#display-chat-messages-by-searching
These commands are in Developer Preview; to use them you must have these values set in `gam.cfg`.
```
developer_preview_apis = chat
developer_preview_api_key = <DeveloperPreviewKey>
```
Upgraded to Python 3.14.5.
7.43.10
Updated `gam <UserTypeEntity> forward message|thread [recipient|to] <RecipientEntity>` to not forward messages
to the `Bcc` recipients of the original message.
Fixed bug in `gam <UserTypeEntity> forward message|thread [recipient|to] <RecipientEntity> addorigfieldstosubject`
where the recipient of the forwarded message was added to the subject line instead of the recipient of the original message.
7.43.09
Fixed bug in `gam <UserTypeEntity> print filelist` that caused a trap.
7.43.08
Fixed bug and formatting issues in `gam info device <DeviceEntity>`.
7.43.07
Improved validation of `<QueryCrOS>`, `<QueryDevice>` and `<QueryMobile>`.
7.43.06
Updated commands that use `<QueryCrOS>`, `<QueryDevice>` or `<QueryMobile>` to validate
that it is of the form `field:value` and that `value` does not contain a '?'.
Without validation, Google can return many more devices than are expected.
7.43.05 7.43.05
Added option `matchfield attendeesorganizer <Boolean> <EmailAddressEntity>` to `<EventMatchProperty>` Added option `matchfield attendeesorganizer <Boolean> <EmailAddressEntity>` to `<EventMatchProperty>`

View File

@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
""" """
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>' __author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
__version__ = '7.43.05' __version__ = '7.44.02'
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)' __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
# pylint: disable=wrong-import-position # pylint: disable=wrong-import-position
@@ -1002,6 +1002,13 @@ def getChoiceAndValue(item, choices, delimiter):
missingArgumentExit(item) missingArgumentExit(item)
invalidChoiceExit(choice, choices, False) invalidChoiceExit(choice, choices, False)
AND_OR_CONJUNCTION_MAP = {
'and': 'AND',
'or': 'OR',
'all': 'AND',
'any': 'OR',
}
SUSPENDED_ARGUMENTS = {'notsuspended', 'suspended', 'issuspended'} SUSPENDED_ARGUMENTS = {'notsuspended', 'suspended', 'issuspended'}
SUSPENDED_CHOICE_MAP = {'notsuspended': False, 'suspended': True} SUSPENDED_CHOICE_MAP = {'notsuspended': False, 'suspended': True}
def _getIsSuspended(myarg): def _getIsSuspended(myarg):
@@ -6071,6 +6078,26 @@ def getQueries(myarg):
return [getString(Cmd.OB_QUERY)] return [getString(Cmd.OB_QUERY)]
return shlexSplitList(getString(Cmd.OB_QUERY_LIST)) return shlexSplitList(getString(Cmd.OB_QUERY_LIST))
def _validateDeviceQuery(entityType, query):
if ':' in query:
qfield, qvalue = query.split(':', 1)
qfield = qfield.strip()
else:
qfield = ''
qvalue = query
if (not qfield) or (not qvalue) or ('?' in query):
Cmd.Backup()
usageErrorExit(Msg.INVALID_DEVICE_QUERY.format(Ent.Singular(entityType), query))
def getDeviceQueries(myarg, entityType):
if myarg in {'query', 'filter'}:
queries = [getString(Cmd.OB_QUERY)]
else:
queries = shlexSplitList(getString(Cmd.OB_QUERY_LIST))
for query in queries:
_validateDeviceQuery(entityType, query)
return queries
def convertEntityToList(entity, shlexSplit=False, nonListEntityType=False): def convertEntityToList(entity, shlexSplit=False, nonListEntityType=False):
if not entity: if not entity:
return [] return []
@@ -6756,6 +6783,7 @@ def getItemsToModify(entityType, entity, memberRoles=None, isSuspended=None, isA
if entityType == Cmd.ENTITY_CROS_SN: if entityType == Cmd.ENTITY_CROS_SN:
queries = [f'id:{query}' for query in queries] queries = [f'id:{query}' for query in queries]
for query in queries: for query in queries:
_validateDeviceQuery(Ent.CROS_DEVICE, query)
printGettingAllAccountEntities(Ent.CROS_DEVICE, query) printGettingAllAccountEntities(Ent.CROS_DEVICE, query)
try: try:
result = callGAPIpages(cd.chromeosdevices(), 'list', 'chromeosdevices', result = callGAPIpages(cd.chromeosdevices(), 'list', 'chromeosdevices',
@@ -6782,9 +6810,9 @@ def getItemsToModify(entityType, entity, memberRoles=None, isSuspended=None, isA
includeChildOrgunits = entityType in Cmd.CROS_OU_CHILDREN_ENTITY_TYPES includeChildOrgunits = entityType in Cmd.CROS_OU_CHILDREN_ENTITY_TYPES
allQualifier = Msg.DIRECTLY_IN_THE.format(Ent.Choose(Ent.ORGANIZATIONAL_UNIT, numOus)) if not includeChildOrgunits else Msg.IN_THE.format(Ent.Choose(Ent.ORGANIZATIONAL_UNIT, numOus)) allQualifier = Msg.DIRECTLY_IN_THE.format(Ent.Choose(Ent.ORGANIZATIONAL_UNIT, numOus)) if not includeChildOrgunits else Msg.IN_THE.format(Ent.Choose(Ent.ORGANIZATIONAL_UNIT, numOus))
if entityType in Cmd.CROS_OU_QUERY_ENTITY_TYPES: if entityType in Cmd.CROS_OU_QUERY_ENTITY_TYPES:
queries = getQueries('query') queries = getDeviceQueries('query', Ent.CROS_DEVICE)
elif entityType in Cmd.CROS_OU_QUERIES_ENTITY_TYPES: elif entityType in Cmd.CROS_OU_QUERIES_ENTITY_TYPES:
queries = getQueries('queries') queries = getDeviceQueries('queries', Ent.CROS_DEVICE)
else: else:
queries = [None] queries = [None]
for ou in ous: for ou in ous:
@@ -24621,7 +24649,7 @@ def _getFilterDateTime():
return (filterDate, filterDate.replace(tzinfo='UTC')) return (filterDate, filterDate.replace(tzinfo='UTC'))
CROS_FIELDS_CHOICE_MAP = { CROS_FIELDS_CHOICE_MAP = {
'activetimeranges': ['activeTimeRanges.activeTime', 'activeTimeRanges.date'], 'activetimeranges': 'activeTimeRanges',
'annotatedassetid': 'annotatedAssetId', 'annotatedassetid': 'annotatedAssetId',
'annotatedlocation': 'annotatedLocation', 'annotatedlocation': 'annotatedLocation',
'annotateduser': 'annotatedUser', 'annotateduser': 'annotatedUser',
@@ -24630,12 +24658,13 @@ CROS_FIELDS_CHOICE_MAP = {
'autoupdateexpiration': 'autoUpdateExpiration', 'autoupdateexpiration': 'autoUpdateExpiration',
'autoupdatethrough': 'autoUpdateThrough', 'autoupdatethrough': 'autoUpdateThrough',
'backlightinfo': 'backlightInfo', 'backlightinfo': 'backlightInfo',
'bluetoothadapterinfo': 'bluetoothAdapterInfo',
'bootmode': 'bootMode', 'bootmode': 'bootMode',
'chromeostype': 'chromeOsType', 'chromeostype': 'chromeOsType',
'cpuinfo': 'cpuInfo', 'cpuinfo': 'cpuInfo',
'cpustatusreports': 'cpuStatusReports', 'cpustatusreports': 'cpuStatusReports',
'deprovisionreason': 'deprovisionReason', 'deprovisionreason': 'deprovisionReason',
'devicefiles': ['deviceFiles.type', 'deviceFiles.createTime'], 'devicefiles': 'deviceFiles',
'deviceid': 'deviceId', 'deviceid': 'deviceId',
'devicelicensetype': 'deviceLicenseType', 'devicelicensetype': 'deviceLicenseType',
'diskspaceusage': 'diskSpaceUsage', 'diskspaceusage': 'diskSpaceUsage',
@@ -24665,9 +24694,10 @@ CROS_FIELDS_CHOICE_MAP = {
'orgunitpath': 'orgUnitPath', 'orgunitpath': 'orgUnitPath',
'osupdatestatus': 'osUpdateStatus', 'osupdatestatus': 'osUpdateStatus',
'osversion': 'osVersion', 'osversion': 'osVersion',
'osversioncompliance': 'osVersionCompliance',
'ou': 'orgUnitPath', 'ou': 'orgUnitPath',
'platformversion': 'platformVersion', 'platformversion': 'platformVersion',
'recentusers': ['recentUsers.email', 'recentUsers.type'], 'recentusers': 'recentUsers',
'screenshotfiles': 'screenshotFiles', 'screenshotfiles': 'screenshotFiles',
'serialnumber': 'serialNumber', 'serialnumber': 'serialNumber',
'status': 'status', 'status': 'status',
@@ -24675,11 +24705,11 @@ CROS_FIELDS_CHOICE_MAP = {
'systemramfreereports': 'systemRamFreeReports', 'systemramfreereports': 'systemRamFreeReports',
'systemramtotal': 'systemRamTotal', 'systemramtotal': 'systemRamTotal',
'tag': 'annotatedAssetId', 'tag': 'annotatedAssetId',
'timeranges': ['activeTimeRanges.activeTime', 'activeTimeRanges.date'], 'timeranges': 'activeTimeRanges',
'times': ['activeTimeRanges.activeTime', 'activeTimeRanges.date'], 'times': 'activeTimeRanges',
'tpmversioninfo': 'tpmVersionInfo', 'tpmversioninfo': 'tpmVersionInfo',
'user': 'annotatedUser', 'user': 'annotatedUser',
'users': ['recentUsers.email', 'recentUsers.type'], 'users': 'recentUsers',
'willautorenew': 'willAutoRenew', 'willautorenew': 'willAutoRenew',
} }
CROS_BASIC_FIELDS_LIST = ['deviceId', 'annotatedAssetId', 'annotatedLocation', 'annotatedUser', 'lastSync', 'notes', 'serialNumber', 'status'] CROS_BASIC_FIELDS_LIST = ['deviceId', 'annotatedAssetId', 'annotatedLocation', 'annotatedUser', 'lastSync', 'notes', 'serialNumber', 'status']
@@ -24700,6 +24730,7 @@ CROS_SCALAR_PROPERTY_PRINT_ORDER = [
'firmwareVersion', 'firmwareVersion',
'platformVersion', 'platformVersion',
'osVersion', 'osVersion',
'osVersionCompliance',
'bootMode', 'bootMode',
'meid', 'meid',
'dockMacAddress', 'dockMacAddress',
@@ -24948,6 +24979,9 @@ def infoCrOSDevices(entityList):
backlightInfo = _filterBasicList(cros, 'backLightInfo', True, listLimit) backlightInfo = _filterBasicList(cros, 'backLightInfo', True, listLimit)
if backlightInfo: if backlightInfo:
showJSON('backlightInfo', backlightInfo, dictObjectsKey={'backlightInfo': 'path'}) showJSON('backlightInfo', backlightInfo, dictObjectsKey={'backlightInfo': 'path'})
bluetoothAdapterInfo = _filterBasicList(cros, 'bluetoothAdapterInfo', True, listLimit)
if bluetoothAdapterInfo:
showJSON('bluetoothAdapterInfo', bluetoothAdapterInfo, dictObjectsKey={'bluetoothAdapterInfo': 'address'})
fanInfo = _filterBasicList(cros, 'fanInfo', True, listLimit) fanInfo = _filterBasicList(cros, 'fanInfo', True, listLimit)
if fanInfo: if fanInfo:
showJSON('fanInfo', fanInfo) showJSON('fanInfo', fanInfo)
@@ -25177,7 +25211,8 @@ CROS_ENTITIES_MAP = {
} }
CROS_INDEXED_TITLES = ['activeTimeRanges', 'recentUsers', 'deviceFiles', CROS_INDEXED_TITLES = ['activeTimeRanges', 'recentUsers', 'deviceFiles',
'cpuStatusReports', 'cpuInfo', 'backlightInfo', 'fanInfo', 'diskVolumeReports', 'lastKnownNetwork', 'screenshotFiles', 'systemRamFreeReports'] 'cpuStatusReports', 'cpuInfo', 'backlightInfo', 'bluetoothAdapterInfo', 'fanInfo',
'diskVolumeReports', 'lastKnownNetwork', 'screenshotFiles', 'systemRamFreeReports']
# gam print cros [todrive <ToDriveAttribute>*] # gam print cros [todrive <ToDriveAttribute>*]
# [(query <QueryCrOS>)|(queries <QueryCrOSList>) [querytime<String> <Time>] # [(query <QueryCrOS>)|(queries <QueryCrOSList>) [querytime<String> <Time>]
@@ -25251,7 +25286,7 @@ def doPrintCrOSDevices(entityList=None):
return return
row = {} row = {}
for attrib in cros: for attrib in cros:
if attrib in {'cpuInfo', 'backlightInfo', 'fanInfo'}: if attrib in {'cpuInfo', 'backlightInfo', 'bluetoothAdapterInfo', 'fanInfo'}:
flattenJSON({attrib: cros[attrib]}, flattened=row) flattenJSON({attrib: cros[attrib]}, flattened=row)
elif attrib not in {'kind', 'etag', 'diskSpaceUsage', 'osUpdateStatus', 'tpmVersionInfo', 'activeTimeRanges', 'recentUsers', elif attrib not in {'kind', 'etag', 'diskSpaceUsage', 'osUpdateStatus', 'tpmVersionInfo', 'activeTimeRanges', 'recentUsers',
'deviceFiles', 'cpuStatusReports', 'diskVolumeReports', 'lastKnownNetwork', 'screenshotFiles', 'systemRamFreeReports'}: 'deviceFiles', 'cpuStatusReports', 'diskVolumeReports', 'lastKnownNetwork', 'screenshotFiles', 'systemRamFreeReports'}:
@@ -25283,7 +25318,7 @@ def doPrintCrOSDevices(entityList=None):
for key in ['email', 'type']: for key in ['email', 'type']:
new_row[f'recentUsers{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}{key}'] = recentUsers[i][key] new_row[f'recentUsers{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}{key}'] = recentUsers[i][key]
if i < lenDF: if i < lenDF:
for key in ['type', 'createTime']: for key in ['name', 'type', 'downloadUrl', 'createTime']:
new_row[f'deviceFiles{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}{key}'] = deviceFiles[i][key] new_row[f'deviceFiles{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}{key}'] = deviceFiles[i][key]
if i < lenCSR: if i < lenCSR:
new_row[f'cpuStatusReports{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}reportTime'] = cpuStatusReports[i]['reportTime'] new_row[f'cpuStatusReports{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}reportTime'] = cpuStatusReports[i]['reportTime']
@@ -25361,7 +25396,7 @@ def doPrintCrOSDevices(entityList=None):
selectionAllowed = False selectionAllowed = False
includeChildOrgunits = myarg in {Cmd.ENTITY_CROS_OU_AND_CHILDREN, Cmd.ENTITY_CROS_OUS_AND_CHILDREN} includeChildOrgunits = myarg in {Cmd.ENTITY_CROS_OU_AND_CHILDREN, Cmd.ENTITY_CROS_OUS_AND_CHILDREN}
elif (selectionAllowed or queries == [None]) and myarg in {'query', 'queries'}: elif (selectionAllowed or queries == [None]) and myarg in {'query', 'queries'}:
queries = getQueries(myarg) queries = getDeviceQueries(myarg, Ent.CROS_DEVICE)
elif myarg.startswith('querytime'): elif myarg.startswith('querytime'):
queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19] queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19]
elif selectionAllowed and myarg == 'select': elif selectionAllowed and myarg == 'select':
@@ -25640,7 +25675,7 @@ def doPrintCrOSActivity(entityList=None):
selectionAllowed = False selectionAllowed = False
directlyInOU = myarg in {Cmd.ENTITY_CROS_OU, Cmd.ENTITY_CROS_OUS} directlyInOU = myarg in {Cmd.ENTITY_CROS_OU, Cmd.ENTITY_CROS_OUS}
elif (selectionAllowed or queries == [None]) and myarg in {'query', 'queries'}: elif (selectionAllowed or queries == [None]) and myarg in {'query', 'queries'}:
queries = getQueries(myarg) queries = getDeviceQueries(myarg, Ent.CROS_DEVICE)
elif myarg.startswith('querytime'): elif myarg.startswith('querytime'):
queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19] queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19]
elif selectionAllowed and myarg == 'select': elif selectionAllowed and myarg == 'select':
@@ -25799,6 +25834,7 @@ def doPrintCrOSEntity(entityList):
doPrintCrOSActivity(entityList) doPrintCrOSActivity(entityList)
CROS_TELEMETRY_FIELDS_CHOICE_MAP = { CROS_TELEMETRY_FIELDS_CHOICE_MAP = {
'appreport': 'appReport',
'audiostatusreport': 'audioStatusReport', 'audiostatusreport': 'audioStatusReport',
'batteryinfo': 'batteryInfo', 'batteryinfo': 'batteryInfo',
'batterystatusreport': 'batteryStatusReport', 'batterystatusreport': 'batteryStatusReport',
@@ -25809,35 +25845,41 @@ CROS_TELEMETRY_FIELDS_CHOICE_MAP = {
'deviceid': 'deviceId', 'deviceid': 'deviceId',
'graphicsinfo': 'graphicsInfo', 'graphicsinfo': 'graphicsInfo',
'graphicsstatusreport': 'graphicsStatusReport', 'graphicsstatusreport': 'graphicsStatusReport',
'heartbeatstatusreport': 'heartbeatStatusReport',
'kioskappstatusreport': 'kioskAppStatusReport',
'memoryinfo': 'memoryInfo', 'memoryinfo': 'memoryInfo',
'memorystatusreport': 'memoryStatusReport', 'memorystatusreport': 'memoryStatusReport',
'name': 'name', 'name': 'name',
'networkinfo': 'networkInfo', 'networkbandwidthreport': 'networkBandwidthReport',
'networkdiagnosticsreport': 'networkDiagnosticsReport', 'networkdiagnosticsreport': 'networkDiagnosticsReport',
'networkinfo': 'networkInfo',
'networkstatusreport': 'networkStatusReport', 'networkstatusreport': 'networkStatusReport',
'orgunitid': 'orgUnitId', 'orgunitid': 'orgUnitId',
'osupdatestatus': 'osUpdateStatus', 'osupdatestatus': 'osUpdateStatus',
'peripheralsreport': 'peripheralsReport', 'peripheralsreport': 'peripheralsReport',
'runtimecountersreport': 'runtimeCountersReport',
'serialnumber': 'serialNumber', 'serialnumber': 'serialNumber',
'storageinfo': 'storageInfo', 'storageinfo': 'storageInfo',
'storagestatusreport': 'storageStatusReport', 'storagestatusreport': 'storageStatusReport',
'thunderboltinfo': 'thunderboltInfo', 'thunderboltinfo': 'thunderboltInfo',
} }
CROS_TELEMETRY_LIST_FIELDS_CHOICE_MAP = { CROS_TELEMETRY_LIST_FIELDS_CHOICE_MAP = {
'appreport': 'appReport',
'audiostatusreport': 'audioStatusReport', 'audiostatusreport': 'audioStatusReport',
'batteryinfo': 'batteryInfo',
'batterystatusreport': 'batteryStatusReport', 'batterystatusreport': 'batteryStatusReport',
'bootperformancereport': 'bootPerformanceReport', 'bootperformancereport': 'bootPerformanceReport',
'cpuinfo': 'cpuInfo',
'cpustatusreport': 'cpuStatusReport', 'cpustatusreport': 'cpuStatusReport',
'graphicsstatusreport': 'graphicsStatusReport', 'graphicsstatusreport': 'graphicsStatusReport',
'heartbeatstatusreport': 'heartbeatStatusReport',
'kioskappstatusreport': 'kioskAppStatusReport',
'memorystatusreport': 'memoryStatusReport', 'memorystatusreport': 'memoryStatusReport',
'networkbandwidthreport': 'networkBandwidthReport',
'networkdiagnosticsreport': 'networkDiagnosticsReport', 'networkdiagnosticsreport': 'networkDiagnosticsReport',
'networkstatusreport': 'networkStatusReport', 'networkstatusreport': 'networkStatusReport',
'osupdatestatus': 'osUpdateStatus', 'osupdatestatus': 'osUpdateStatus',
'peripheralsreport': 'peripheralsReport', 'peripheralsreport': 'peripheralsReport',
'runtimecountersreport': 'runtimeCountersReport',
'storagestatusreport': 'storageStatusReport', 'storagestatusreport': 'storageStatusReport',
'thunderboltinfo': 'thunderboltInfo',
} }
CROS_TELEMETRY_SCALAR_FIELDS = ['deviceId', 'serialNumber', 'customer', 'name', 'orgUnitId', 'orgUnitPath'] CROS_TELEMETRY_SCALAR_FIELDS = ['deviceId', 'serialNumber', 'customer', 'name', 'orgUnitId', 'orgUnitPath']
@@ -25859,7 +25901,7 @@ CROS_TELEMETRY_TIME_OBJECTS = {'reportTime', 'lastUpdateTime', 'lastUpdateCheckT
# gam print crostelemetry [todrive <ToDriveAttribute>*] # gam print crostelemetry [todrive <ToDriveAttribute>*]
# [(ou|org|orgunit|ou_and_children <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)] # [(ou|org|orgunit|ou_and_children <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)]
# <CrOSTelemetryFieldName>* [fields <CrOSTelemetryFieldNameList>] # <CrOSTelemetryFieldName>* [fields <CrOSTelemetryFieldNameList>]
# [reverselists <CrOSTelemetryListFieldNameList>] # [reverselists <CrOSTelemetryListFieldNameList>] [oneitemperrow]
# [start <Date>] [end <Date>] [listlimit <Number>] # [start <Date>] [end <Date>] [listlimit <Number>]
# [formatjson [quotechar <Character>]] # [formatjson [quotechar <Character>]]
def doInfoPrintShowCrOSTelemetry(): def doInfoPrintShowCrOSTelemetry():
@@ -25900,13 +25942,32 @@ def doInfoPrintShowCrOSTelemetry():
def _printDevice(device): def _printDevice(device):
_cleanDevice(device) _cleanDevice(device)
if not FJQC.formatJSON: if FJQC.formatJSON:
csvPF.WriteRowTitles(flattenJSON(device, timeObjects=CROS_TELEMETRY_TIME_OBJECTS))
else:
if (not csvPF.rowFilter and not csvPF.rowDropFilter) or csvPF.CheckRowTitles(flattenJSON(device, timeObjects=CROS_TELEMETRY_TIME_OBJECTS)): if (not csvPF.rowFilter and not csvPF.rowDropFilter) or csvPF.CheckRowTitles(flattenJSON(device, timeObjects=CROS_TELEMETRY_TIME_OBJECTS)):
csvPF.WriteRowNoFilter({'deviceId': device['deviceId'], csvPF.WriteRowNoFilter({'deviceId': device['deviceId'],
'JSON': json.dumps(cleanJSON(device, timeObjects=CROS_TELEMETRY_TIME_OBJECTS), 'JSON': json.dumps(cleanJSON(device, timeObjects=CROS_TELEMETRY_TIME_OBJECTS),
ensure_ascii=False, sort_keys=True)}) ensure_ascii=False, sort_keys=True)})
return
if not oneItemPerRow:
csvPF.WriteRowTitles(flattenJSON(device, timeObjects=CROS_TELEMETRY_TIME_OBJECTS))
return
listLens = {}
maxLen = 0
for field in CROS_TELEMETRY_LIST_FIELDS_CHOICE_MAP.values():
if field in device:
listLens[field] = len(device[field])
if listLens[field] > maxLen:
maxLen = listLens[field]
baserow = {}
for field in CROS_TELEMETRY_SCALAR_FIELDS:
if field in device:
baserow[field] = device[field]
for i in range(maxLen):
row = baserow.copy()
for field, fieldLen in listLens.items():
if i < fieldLen:
flattenJSON({field: device[field][i]}, flattened=row, timeObjects=CROS_TELEMETRY_TIME_OBJECTS)
csvPF.WriteRowTitles(row)
def _showDevice(device, i=0, count=0): def _showDevice(device, i=0, count=0):
_cleanDevice(device) _cleanDevice(device)
@@ -25933,11 +25994,12 @@ def doInfoPrintShowCrOSTelemetry():
Act.Set(Act.SHOW) Act.Set(Act.SHOW)
else: else:
pfilters = [] pfilters = []
csvPF = CSVPrintFile(['deviceId'], CROS_TELEMETRY_SCALAR_FIELDS, CROS_TELEMETRY_LIST_FIELDS) if Act.csvFormat() else None csvPF = CSVPrintFile(['deviceId'], CROS_TELEMETRY_SCALAR_FIELDS) if Act.csvFormat() else None
FJQC = FormatJSONQuoteChar(csvPF) FJQC = FormatJSONQuoteChar(csvPF)
diskPercentOnly = showOrgUnitPath = False diskPercentOnly = showOrgUnitPath = False
listLimit = 0 listLimit = 0
startTime = endTime = None startTime = endTime = None
oneItemPerRow = False
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if csvPF and myarg == 'todrive': if csvPF and myarg == 'todrive':
@@ -25993,6 +26055,8 @@ def doInfoPrintShowCrOSTelemetry():
cd = buildGAPIObject(API.DIRECTORY) cd = buildGAPIObject(API.DIRECTORY)
elif myarg == 'storagepercentonly': elif myarg == 'storagepercentonly':
diskPercentOnly = True diskPercentOnly = True
elif csvPF and myarg == 'oneitemperrow':
oneItemPerRow = True
else: else:
FJQC.GetFormatJSONQuoteChar(myarg, False) FJQC.GetFormatJSONQuoteChar(myarg, False)
if fieldsList: if fieldsList:
@@ -26004,6 +26068,8 @@ def doInfoPrintShowCrOSTelemetry():
readMask = ','.join(set(fieldsList)) readMask = ','.join(set(fieldsList))
if csvPF and FJQC.formatJSON: if csvPF and FJQC.formatJSON:
csvPF.SetJSONTitles(['deviceId', 'JSON']) csvPF.SetJSONTitles(['deviceId', 'JSON'])
elif csvPF and not oneItemPerRow:
csvPF.SetIndexedTitles(CROS_TELEMETRY_LIST_FIELDS)
if not pfilters: if not pfilters:
pfilters = [(None, 'All')] pfilters = [(None, 'All')]
for pfilter in pfilters: for pfilter in pfilters:
@@ -26165,7 +26231,7 @@ def doMoveBrowsers():
elif myarg in {'csv', 'csvfile'}: elif myarg in {'csv', 'csvfile'}:
deviceIds.extend(getEntitiesFromCSVFile(False)) deviceIds.extend(getEntitiesFromCSVFile(False))
elif myarg in {'query', 'queries'}: elif myarg in {'query', 'queries'}:
queries = getQueries(myarg) queries = getDeviceQueries(myarg, Ent.CHROME_BROWSER)
elif myarg.startswith('querytime'): elif myarg.startswith('querytime'):
queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19] queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19]
elif myarg == 'browserou': elif myarg == 'browserou':
@@ -26717,7 +26783,7 @@ def doPrintShowBrowsers():
if csvPF and myarg == 'todrive': if csvPF and myarg == 'todrive':
csvPF.GetTodriveParameters() csvPF.GetTodriveParameters()
elif myarg in {'query', 'queries'}: elif myarg in {'query', 'queries'}:
queries = getQueries(myarg) queries = getDeviceQueries(myarg, Ent.CHROME_BROWSER)
elif myarg.startswith('querytime'): elif myarg.startswith('querytime'):
queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19] queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19]
elif myarg in {'ou', 'org', 'orgunit', 'browserou'}: elif myarg in {'ou', 'org', 'orgunit', 'browserou'}:
@@ -26924,7 +26990,7 @@ def doPrintShowBrowserTokens():
if csvPF and myarg == 'todrive': if csvPF and myarg == 'todrive':
csvPF.GetTodriveParameters() csvPF.GetTodriveParameters()
elif myarg in {'query', 'queries'}: elif myarg in {'query', 'queries'}:
queries = getQueries(myarg) queries = getDeviceQueries(myarg, Ent.CHROME_BROWSER)
elif myarg.startswith('querytime'): elif myarg.startswith('querytime'):
queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19] queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19]
elif myarg in {'ou', 'org', 'orgunit', 'browserou'}: elif myarg in {'ou', 'org', 'orgunit', 'browserou'}:
@@ -29140,24 +29206,37 @@ def infoChatMessage(users):
def doInfoChatMessage(): def doInfoChatMessage():
infoChatMessage([None]) infoChatMessage([None])
CHAT_MESSAGES_ORDERBY_CHOICE_MAP = {
'createtime': 'createTime'
}
# gam <UserTypeEntity> show chatmessages # gam <UserTypeEntity> show chatmessages
# <ChatSpace>+ # <ChatSpace>+
# [showdeleted [<Boolean>]] [filter <String>] # [showdeleted [<Boolean>]]
# [([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
# [thread <ChatThread>])
# [fields <ChatMessageFieldNameList>] # [fields <ChatMessageFieldNameList>]
# [orderby createtime [ascending|descending]]
# [formatjson] # [formatjson]
# gam <UserTypeEntity> print chatmessages [todrive <ToDriveAttribute>*] # gam <UserTypeEntity> print chatmessages [todrive <ToDriveAttribute>*]
# <ChatSpace>+ # <ChatSpace>+
# [showdeleted [<Boolean>]] [filter <String>] # [showdeleted [<Boolean>]] [filter <String>]
# [([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
# [thread <ChatThread>])
# [fields <ChatMessageFieldNameList>] # [fields <ChatMessageFieldNameList>]
# [orderby createtime [ascending|descending]]
# [formatjson [quotechar <Character>]] # [formatjson [quotechar <Character>]]
def printShowChatMessages(users): def printShowChatMessages(users):
cd = buildGAPIObject(API.DIRECTORY) cd = buildGAPIObject(API.DIRECTORY)
csvPF = CSVPrintFile(['User', 'space.name', 'space.displayName', 'name'] if not isinstance(users, list) else ['space.name', 'space.displayName', 'name']) if Act.csvFormat() else None csvPF = CSVPrintFile(['User', 'space.name', 'space.displayName', 'name']) if Act.csvFormat() else None
FJQC = FormatJSONQuoteChar(csvPF) FJQC = FormatJSONQuoteChar(csvPF)
OBY = OrderBy(CHAT_MESSAGES_ORDERBY_CHOICE_MAP, ascendingKeyword='ASC', descendingKeyword='DESC')
fieldsList = [] fieldsList = []
pfilter = None pfilter = None
parentList = [] parentList = []
showDeleted = False showDeleted = False
startEndTime = StartEndTime()
threadName = ''
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if csvPF and myarg == 'todrive': if csvPF and myarg == 'todrive':
@@ -29170,10 +29249,35 @@ def printShowChatMessages(users):
showDeleted = getBoolean() showDeleted = getBoolean()
elif myarg =='filter': elif myarg =='filter':
pfilter = getString(Cmd.OB_STRING) pfilter = getString(Cmd.OB_STRING)
elif myarg in {'start', 'starttime', 'end', 'endtime', 'range'}:
startEndTime.Get(myarg)
elif myarg == 'thread':
threadName = getString(Cmd.OB_CHAT_THREAD)
elif myarg == 'orderby':
OBY.GetChoice()
else: else:
FJQC.GetFormatJSONQuoteChar(myarg, True) FJQC.GetFormatJSONQuoteChar(myarg, True)
if not parentList: if not parentList:
missingArgumentExit('space') missingArgumentExit('space')
if startEndTime.startDateTime is not None or startEndTime.endDateTime is not None:
if pfilter:
pfilter += ' AND '
else:
pfilter = ''
pfilter += '('
if startEndTime.startDateTime is not None:
pfilter += f'createTime > "{startEndTime.startDateTime}"'
if startEndTime.endDateTime is not None:
pfilter += ' AND '
if startEndTime.endDateTime is not None:
pfilter += f'createTime < "{startEndTime.endDateTime}"'
pfilter += ')'
if threadName:
if pfilter:
pfilter += ' AND '
else:
pfilter = ''
pfilter += f'thread.name = {threadName}'
chatSenders = {} chatSenders = {}
fields = getItemFieldsFromFieldsList('messages', fieldsList) fields = getItemFieldsFromFieldsList('messages', fieldsList)
i, count, users = getEntityArgument(users) i, count, users = getEntityArgument(users)
@@ -29204,7 +29308,8 @@ def printShowChatMessages(users):
pageMessage=_getChatPageMessage(Ent.CHAT_MESSAGE, user, i, count, qfilter), pageMessage=_getChatPageMessage(Ent.CHAT_MESSAGE, user, i, count, qfilter),
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED], throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS, retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
pageSize=GC.Values[GC.CHAT_MAX_RESULTS], parent=parentName, filter=pfilter, showDeleted=showDeleted, pageSize=GC.Values[GC.CHAT_MAX_RESULTS], parent=parentName,
filter=pfilter, showDeleted=showDeleted, orderBy=OBY.orderBy,
fields=fields) fields=fields)
for message in messages: for message in messages:
if 'sender' in message: if 'sender' in message:
@@ -29235,6 +29340,183 @@ def printShowChatMessages(users):
if csvPF: if csvPF:
csvPF.writeCSVfile('Chat Messages') csvPF.writeCSVfile('Chat Messages')
def _getChatSpaceDisplayName(chat, space, chatSpaces):
spaceName = space['name']
if spaceName not in chatSpaces:
try:
result = callGAPI(chat.spaces(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
name=spaceName, fields='displayName')
spaceDisplayName = result.get('displayName', 'None')
except (GAPI.notFound, GAPI.invalidArgument, GAPI.internalError, GAPI.permissionDenied, GAPI.failedPrecondition):
spaceDisplayName = 'None'
chatSpaces[spaceName] = spaceDisplayName
space['displayName'] = chatSpaces[spaceName]
CHAT_SEARCHMESSAGES_ORDERBY_CHOICE_MAP = {
'createtime': 'createTime',
'relevance': 'relevance',
}
CHAT_SEARCHMESSAGES_VIEW_CHOICE_MAP = {'basic': 'SEARCH_MESSAGES_VIEW_BASIC', 'full': 'SEARCH_MESSAGES_VIEW_FULL'}
# gam <UserTypeEntity> show chatsearchmessages
# keywords <StringList>
# <ChatSpace>*
# [displaynames [all|any] <StringList>]
# [senders <EmailAddressEntity>]*
# [usermentions [all|any] <EmailAddressEntity>]*
# [([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
# [hasattachment [<Boolean>]]
# [fields <ChatMessageFieldNameList>]
# [orderby createtime|relevance]
# [basic|full]
# [formatjson]
# gam <UserTypeEntity> print chatsearchmessages [todrive <ToDriveAttribute>*]
# keywords <StringList>
# <ChatSpace>*
# [displaynames [all|any] <StringList>]
# [senders <EmailAddressEntity>]*
# [usermentions [all|any] <EmailAddressEntity>]*
# [([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
# [hasattachment [<Boolean>]]
# [fields <ChatMessageFieldNameList>]
# [orderby createtime|relevance]
# [basic|full]
# [formatjson [quotechar <Character>]]
def printShowChatSearchMessages(users):
if API.CHAT not in GM.Globals[GM.DEVELOPER_PREVIEW_APIS]:
Cmd.Backup()
usageErrorExit(Msg.DEVELOPER_PREVIEW_REQUIRED)
cd = buildGAPIObject(API.DIRECTORY)
csvPF = CSVPrintFile(['User', 'space.name', 'space.displayName', 'name']) if Act.csvFormat() else None
FJQC = FormatJSONQuoteChar(csvPF)
orderBy = None
fieldsList = []
keywordList = []
spaceList = []
displayNameConjunction = ''
displayNameList = []
senderList = []
userMentionList = []
startEndTime = StartEndTime()
hasAttachment = False
body = {'view': CHAT_SEARCHMESSAGES_VIEW_CHOICE_MAP['basic'],
'pageSize': GC.Values[GC.CHAT_MAX_RESULTS], 'pageToken': None}
parent = 'spaces/-'
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if csvPF and myarg == 'todrive':
csvPF.GetTodriveParameters()
elif myarg =='keywords':
keywordList = getString(Cmd.OB_STRING_LIST, minLen=0).replace(',', ' ').split()
elif myarg == 'space' or myarg.startswith('spaces/') or myarg.startswith('space/'):
spaceList.append(getSpaceName(myarg))
elif myarg == 'displaynames':
displayNameConjunction = getChoice(AND_OR_CONJUNCTION_MAP, mapChoice=True, defaultChoice='OR')
displayNameList = getString(Cmd.OB_STRING_LIST, minLen=0).replace(',', ' ').split()
elif myarg == 'senders':
senderList.extend(getNormalizedEmailAddressEntity(noUid=False))
elif myarg == 'usermentions':
userMentionConjunction = getChoice(AND_OR_CONJUNCTION_MAP, mapChoice=True, defaultChoice='OR')
userMentionList.extend(getNormalizedEmailAddressEntity(noUid=False))
elif myarg in {'start', 'starttime', 'end', 'endtime`', 'range'}:
startEndTime.Get(myarg)
elif myarg == 'hasattachment':
hasAttachment = True
elif myarg == 'orderby':
orderBy = getChoice(CHAT_SEARCHMESSAGES_ORDERBY_CHOICE_MAP, mapChoice=True)
elif myarg in CHAT_SEARCHMESSAGES_VIEW_CHOICE_MAP:
body['view'] = CHAT_SEARCHMESSAGES_VIEW_CHOICE_MAP[myarg]
elif getFieldsList(myarg, CHAT_MESSAGES_FIELDS_CHOICE_MAP, fieldsList, initialField='name', onlyFieldsArg=True):
pass
else:
FJQC.GetFormatJSONQuoteChar(myarg, True)
if not keywordList:
missingArgumentExit('keywords')
if orderBy is not None:
body['orderBy'] = f'{orderBy} desc'
body['filter'] = f'({" ".join(keywordList)})'
if spaceList:
body['filter'] += ' AND ('
for space in spaceList:
body['filter'] += f'space.name = "{space}" OR '
body['filter'] = body['filter'][:-4] + ')'
if displayNameList:
body['filter'] += ' AND ('
for displayName in displayNameList:
body['filter'] += f'space.display_name:{displayName}" {displayNameConjunction} '
body['filter'] = body['filter'][:-(len(displayNameConjunction)+2)] + ')'
if senderList:
body['filter'] += ' AND ('
for sender in senderList:
body['filter'] += f'sender.name = "users/{sender}" OR '
body['filter'] = body['filter'][:-4] + ')'
if userMentionList:
body['filter'] += ' AND ('
for userMention in userMentionList:
body['filter'] += f'annotations.user_mentions.user.name:"users/{userMention}" {userMentionConjunction} '
body['filter'] = body['filter'][:-(len(userMentionConjunction)+2)] + ')'
if startEndTime.startDateTime is not None or startEndTime.endDateTime is not None:
body['filter'] += ' AND ('
if startEndTime.startDateTime is not None:
body['filter'] += f'createTime >= "{startEndTime.startDateTime}"'
if startEndTime.endDateTime is not None:
body['filter'] += ' AND '
if startEndTime.endDateTime is not None:
body['filter'] += f'createTime < "{startEndTime.endDateTime}"'
body['filter'] += ')'
if hasAttachment:
body['filter'] += ' AND attachment:*'
chatSenders = {}
chatSpaces = {}
fields = getItemFieldsFromFieldsList('results(message', fieldsList)
if fields:
fields += ')'
i, count, users = getEntityArgument(users)
for user in users:
i += 1
user, chat, kvList = buildChatServiceObject(API.CHAT_MESSAGES, user, i, count, [Ent.CHAT_SPACE, None])
if not chat:
continue
_, chatsp, _ = buildChatServiceObject(API.CHAT_SPACES, user, i, count, [Ent.CHAT_SPACE, None])
if not chat:
continue
try:
results = callGAPIpages(chat.spaces().messages(), 'search', 'results',
pageMessage=_getChatPageMessage(Ent.CHAT_MESSAGE, user, i, count, body['filter']),
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
parent='spaces/-', body=body, fields=fields, pageArgsInBody=True)
for result in results:
if 'sender' in result['message']:
_getChatSenderEmail(cd, result['message']['sender'], chatSenders)
if 'space' in result['message']:
_getChatSpaceDisplayName(chatsp, result['message']['space'], chatSpaces)
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
continue
except GAPI.failedPrecondition:
userChatServiceNotEnabledWarning(user, i, count)
break
if not csvPF:
jcount = len(results)
if not FJQC.formatJSON:
entityPerformActionNumItems(kvList, jcount, Ent.CHAT_MESSAGE, i, count)
Ind.Increment()
j = 0
for result in results:
j += 1
_showChatItem(result['message'], Ent.CHAT_MESSAGE, FJQC, j, jcount)
Ind.Decrement()
elif results:
for result in results:
_printChatItem(user, result['message'], parent, Ent.CHAT_MESSAGE, csvPF, FJQC)
elif GC.Values[GC.CSV_OUTPUT_USERS_AUDIT]:
csvPF.WriteRowNoFilter({'User': user})
if csvPF:
csvPF.writeCSVfile('Chat Messages')
# gam <UserTypeEntity> info chatevent name <ChatEvent> # gam <UserTypeEntity> info chatevent name <ChatEvent>
# [formatjson] # [formatjson]
def infoChatEvent(users): def infoChatEvent(users):
@@ -29280,7 +29562,7 @@ def doInfoChatEvent():
# filter <String> # filter <String>
# [formatjson [quotechar <Character>]] # [formatjson [quotechar <Character>]]
def printShowChatEvents(users): def printShowChatEvents(users):
csvPF = CSVPrintFile(['User', 'space.name', 'space.displayName', 'name'] if not isinstance(users, list) else ['space.name', 'space.displayName', 'name']) if Act.csvFormat() else None csvPF = CSVPrintFile(['User', 'space.name', 'space.displayName', 'name']) if Act.csvFormat() else None
FJQC = FormatJSONQuoteChar(csvPF) FJQC = FormatJSONQuoteChar(csvPF)
pfilter = None pfilter = None
parentList = [] parentList = []
@@ -31030,6 +31312,7 @@ def getCIDeviceEntity():
if not name.startswith('devices/'): if not name.startswith('devices/'):
name = f'devices/{name}' name = f'devices/{name}'
return ([{'name': name}], ci, customer, True) return ([{'name': name}], ci, customer, True)
_validateDeviceQuery(Ent.DEVICE, query)
printGettingAllAccountEntities(Ent.DEVICE, query) printGettingAllAccountEntities(Ent.DEVICE, query)
pageMessage = getPageMessage() pageMessage = getPageMessage()
try: try:
@@ -31066,11 +31349,12 @@ def getCIDeviceUserEntity():
return ([{'name': name}], ci, customer, True) return ([{'name': name}], ci, customer, True)
Cmd.Backup() Cmd.Backup()
invalidArgumentExit(DEVICE_USERNAME_FORMAT_REQUIRED) invalidArgumentExit(DEVICE_USERNAME_FORMAT_REQUIRED)
_validateDeviceQuery(Ent.DEVICE_USER, query)
printGettingAllAccountEntities(Ent.DEVICE_USER, query) printGettingAllAccountEntities(Ent.DEVICE_USER, query)
pageMessage = getPageMessage() pageMessage = getPageMessage()
try: try:
deviceUsers = callGAPIpages(ci.devices().deviceUsers(), 'list', 'deviceUsers', deviceUsers = callGAPIpages(ci.devices().deviceUsers(), 'list', 'deviceUsers',
throwReasons=[GAPI.INVALID, GAPI.PERMISSION_DENIED], throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS, retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
pageMessage=pageMessage, pageMessage=pageMessage,
customer=customer, filter=query, parent='devices/-', customer=customer, filter=query, parent='devices/-',
@@ -31079,7 +31363,7 @@ def getCIDeviceUserEntity():
except GAPI.invalid: except GAPI.invalid:
Cmd.Backup() Cmd.Backup()
usageErrorExit(Msg.INVALID_QUERY) usageErrorExit(Msg.INVALID_QUERY)
except GAPI.permissionDenied as e: except (GAPI.invalidArgument, GAPI.permissionDenied) as e:
entityActionFailedWarning([Ent.DEVICE_USER, None], str(e)) entityActionFailedWarning([Ent.DEVICE_USER, None], str(e))
return ([], ci, customer, False) return ([], ci, customer, False)
@@ -31214,7 +31498,7 @@ def doSyncCIDevices():
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if myarg in ['filter', 'filters', 'query', 'queries']: if myarg in ['filter', 'filters', 'query', 'queries']:
queries = getQueries(myarg) queries = getDeviceQueries(myarg, Ent.COMPANY_DEVICE)
elif myarg.startswith('querytime'): elif myarg.startswith('querytime'):
queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19] queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19]
elif myarg in {'csv', 'csvfile'}: elif myarg in {'csv', 'csvfile'}:
@@ -31433,7 +31717,7 @@ def doInfoCIDevice():
else: else:
FJQC.GetFormatJSON(myarg) FJQC.GetFormatJSON(myarg)
fields = getFieldsFromFieldsList(fieldsList) fields = getFieldsFromFieldsList(fieldsList)
userFields = getFieldsFromFieldsList(userFieldsList) userFields = getItemFieldsFromFieldsList('deviceUsers', userFieldsList)
i = 0 i = 0
count = len(entityList) count = len(entityList)
for device in entityList: for device in entityList:
@@ -31445,7 +31729,7 @@ def doInfoCIDevice():
name=name, customer=customer, fields=fields) name=name, customer=customer, fields=fields)
if getDeviceUsers: if getDeviceUsers:
device_users = callGAPIpages(ci.devices().deviceUsers(), 'list', 'deviceUsers', device_users = callGAPIpages(ci.devices().deviceUsers(), 'list', 'deviceUsers',
throwReasons=[GAPI.INVALID, GAPI.PERMISSION_DENIED], throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
parent=name, customer=customer, fields=userFields) parent=name, customer=customer, fields=userFields)
for device_user in device_users: for device_user in device_users:
device_user['client_states'] = callGAPIpages(ci.devices().deviceUsers().clientStates(), 'list', 'clientStates', device_user['client_states'] = callGAPIpages(ci.devices().deviceUsers().clientStates(), 'list', 'clientStates',
@@ -31469,7 +31753,7 @@ def doInfoCIDevice():
Ind.Increment() Ind.Increment()
showJSON(None, device_user, timeObjects=DEVICE_TIME_OBJECTS) showJSON(None, device_user, timeObjects=DEVICE_TIME_OBJECTS)
Ind.Decrement() Ind.Decrement()
Ind.Decrement() Ind.Decrement()
except GAPI.notFound: except GAPI.notFound:
entityUnknownWarning(Ent.DEVICE, f'{name}') entityUnknownWarning(Ent.DEVICE, f'{name}')
except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied) as e: except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied) as e:
@@ -31520,7 +31804,7 @@ def doPrintCIDevices():
if csvPF and myarg == 'todrive': if csvPF and myarg == 'todrive':
csvPF.GetTodriveParameters() csvPF.GetTodriveParameters()
elif myarg in ['filter', 'filters', 'query', 'queries']: elif myarg in ['filter', 'filters', 'query', 'queries']:
queries = getQueries(myarg) queries = getDeviceQueries(myarg, entityType)
elif myarg.startswith('querytime'): elif myarg.startswith('querytime'):
queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19] queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19]
elif myarg == 'orderby': elif myarg == 'orderby':
@@ -31758,7 +32042,7 @@ def doPrintCIDeviceUsers():
if not parent.startswith('devices/'): if not parent.startswith('devices/'):
parent = f'devices/{parent}' parent = f'devices/{parent}'
elif myarg in ['filter', 'filters', 'query', 'queries']: elif myarg in ['filter', 'filters', 'query', 'queries']:
queries = getQueries(myarg) queries = getDeviceQueries(myarg, Ent.DEVICE_USER)
elif myarg.startswith('querytime'): elif myarg.startswith('querytime'):
queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19] queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19]
elif myarg == 'orderby': elif myarg == 'orderby':
@@ -31795,7 +32079,7 @@ def doPrintCIDeviceUsers():
csvPF.WriteRowNoFilter({'name': deviceUser['name'], csvPF.WriteRowNoFilter({'name': deviceUser['name'],
'JSON': json.dumps(cleanJSON(deviceUser, timeObjects=DEVICE_TIME_OBJECTS), 'JSON': json.dumps(cleanJSON(deviceUser, timeObjects=DEVICE_TIME_OBJECTS),
ensure_ascii=False, sort_keys=True)}) ensure_ascii=False, sort_keys=True)})
except (GAPI.invalid, GAPI.permissionDenied) as e: except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied) as e:
entityActionFailedWarning([Ent.DEVICE_USER, None], str(e)) entityActionFailedWarning([Ent.DEVICE_USER, None], str(e))
break break
if showItemCountOnly: if showItemCountOnly:
@@ -33406,6 +33690,7 @@ def getMobileDeviceEntity():
query = None query = None
if not query: if not query:
return ([{'resourceId': device, 'email': []} for device in getEntityList(Cmd.OB_MOBILE_ENTITY)], cd, True) return ([{'resourceId': device, 'email': []} for device in getEntityList(Cmd.OB_MOBILE_ENTITY)], cd, True)
_validateDeviceQuery(Ent.MOBILE_DEVICE, query)
try: try:
printGettingAllAccountEntities(Ent.MOBILE_DEVICE, query) printGettingAllAccountEntities(Ent.MOBILE_DEVICE, query)
devices = callGAPIpages(cd.mobiledevices(), 'list', 'mobiledevices', devices = callGAPIpages(cd.mobiledevices(), 'list', 'mobiledevices',
@@ -33716,7 +34001,7 @@ def doPrintMobileDevices():
if myarg == 'todrive': if myarg == 'todrive':
csvPF.GetTodriveParameters() csvPF.GetTodriveParameters()
elif myarg in {'query', 'queries'}: elif myarg in {'query', 'queries'}:
queries = getQueries(myarg) queries = getDeviceQueries(myarg, Ent.MOBILE_DEVICE)
elif myarg.startswith('querytime'): elif myarg.startswith('querytime'):
queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19] queryTimes[myarg] = getTimeOrDeltaFromNow()[0:19]
elif myarg == 'orderby': elif myarg == 'orderby':
@@ -46989,7 +47274,9 @@ USER_SCALAR_PROPERTY_PRINT_ORDER = [
'ipWhitelisted', 'ipWhitelisted',
'suspended', 'suspended',
'suspensionReason', 'suspensionReason',
'suspensionTime',
'archived', 'archived',
'archivalTime',
'changePasswordAtNextLogin', 'changePasswordAtNextLogin',
'id', 'id',
'customerId', 'customerId',
@@ -47080,7 +47367,7 @@ USER_FIELDS_CHOICE_MAP = {
'agreed2terms': 'agreedToTerms', 'agreed2terms': 'agreedToTerms',
'agreedtoterms': 'agreedToTerms', 'agreedtoterms': 'agreedToTerms',
'aliases': ['aliases', 'nonEditableAliases'], 'aliases': ['aliases', 'nonEditableAliases'],
'archived': 'archived', 'archived': ['archived', 'archivalTime'],
'changepassword': 'changePasswordAtNextLogin', 'changepassword': 'changePasswordAtNextLogin',
'changepasswordatnextlogin': 'changePasswordAtNextLogin', 'changepasswordatnextlogin': 'changePasswordAtNextLogin',
'creationtime': 'creationTime', 'creationtime': 'creationTime',
@@ -47150,7 +47437,7 @@ USER_FIELDS_CHOICE_MAP = {
'ssh': 'sshPublicKeys', 'ssh': 'sshPublicKeys',
'sshkeys': 'sshPublicKeys', 'sshkeys': 'sshPublicKeys',
'sshpublickeys': 'sshPublicKeys', 'sshpublickeys': 'sshPublicKeys',
'suspended': ['suspended', 'suspensionReason'], 'suspended': ['suspended', 'suspensionReason', 'suspensionTime'],
'thumbnailphotourl': 'thumbnailPhotoUrl', 'thumbnailphotourl': 'thumbnailPhotoUrl',
'username': 'primaryEmail', 'username': 'primaryEmail',
'website': 'websites', 'website': 'websites',
@@ -47186,7 +47473,7 @@ USER_MULTI_ATTR_FILTER_CHOICE_MAP = {
INFO_USER_OPTIONS = {'noaliases', 'nobuildingnames', 'nogroups', 'nolicenses', 'nolicences', 'noschemas', 'schemas', 'userview'} INFO_USER_OPTIONS = {'noaliases', 'nobuildingnames', 'nogroups', 'nolicenses', 'nolicences', 'noschemas', 'schemas', 'userview'}
USER_SKIP_OBJECTS = {'thumbnailPhotoEtag'} USER_SKIP_OBJECTS = {'thumbnailPhotoEtag'}
USER_TIME_OBJECTS = {'creationTime', 'deletionTime', 'lastLoginTime'} USER_TIME_OBJECTS = {'creationTime', 'deletionTime', 'lastLoginTime', 'suspensionTime', 'archivalTime'}
def _getUserMultiAttributeFilters(myarg, userMultiAttributeFilters): def _getUserMultiAttributeFilters(myarg, userMultiAttributeFilters):
up = getChoice(USER_MULTI_ATTR_FILTER_CHOICE_MAP, mapChoice=True) up = getChoice(USER_MULTI_ATTR_FILTER_CHOICE_MAP, mapChoice=True)
@@ -59681,7 +59968,7 @@ def printFileList(users):
(DLP.onlySharedDrives and not driveId)): (DLP.onlySharedDrives and not driveId)):
return return
if getCheckFilePermissions: if getCheckFilePermissions:
if not incrementalPrint: if buildTree and not incrementalPrint:
getSharedDriveACLsCount += 1 getSharedDriveACLsCount += 1
if getSharedDriveACLsCount % 100 == 0: if getSharedDriveACLsCount % 100 == 0:
writeStderr(f'{Msg.GOT} {getSharedDriveACLsCount} {Ent.Plural(Ent.DRIVE_FILE_OR_FOLDER_ACL)} {Msg.FOR} {gettingEntity}\n') writeStderr(f'{Msg.GOT} {getSharedDriveACLsCount} {Ent.Plural(Ent.DRIVE_FILE_OR_FOLDER_ACL)} {Msg.FOR} {gettingEntity}\n')
@@ -74571,10 +74858,10 @@ def _decodeHeader(header):
stderrWarningMsg(Msg.INVALID_CHARSET.format(mg.group(1))) stderrWarningMsg(Msg.INVALID_CHARSET.format(mg.group(1)))
return header return header
# gam <UserTypeEntity> forward message|messages recipient|to <RecipientEntity> # gam <UserTypeEntity> forward message|messages [recipient|to] <RecipientEntity>
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_forward <Number>])|(ids <MessageIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_forward <Number>])|(ids <MessageIDEntity>)
# [subject <String>] [addorigfieldstosubject [<Boolean>]] [altcharset <String>] # [subject <String>] [addorigfieldstosubject [<Boolean>]] [altcharset <String>]
# gam <UserTypeEntity> forward thread|threads recipient|to <RecipientEntity> # gam <UserTypeEntity> forward thread|threads [recipient|to] <RecipientEntity>
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>)
# [subject <String>] [addorigfieldstosubject [<Boolean>]] [altcharset <String>] # [subject <String>] [addorigfieldstosubject [<Boolean>]] [altcharset <String>]
def forwardMessagesThreads(users, entityType): def forwardMessagesThreads(users, entityType):
@@ -74677,16 +74964,16 @@ def forwardMessagesThreads(users, entityType):
msgSubject = f"Fwd: {_decodeHeader(message['Subject'])}" msgSubject = f"Fwd: {_decodeHeader(message['Subject'])}"
else: else:
msgSubject = f"Subject: {subject}" msgSubject = f"Subject: {subject}"
for header in ['To', 'Cc', 'Subject']:
if header in message:
del message[header]
message['To'] = msgTo
if addOriginalFieldsToSubject: if addOriginalFieldsToSubject:
msgSubject += ' (Original' msgSubject += ' (Original'
for header in ['From', 'To', 'Date']: for header in ['From', 'To', 'Date']:
if header in message: if header in message:
msgSubject += f' {header}: {message[header]}' msgSubject += f' {header}: {message[header]}'
msgSubject += ')' msgSubject += ')'
for header in ['To', 'Cc', 'Bcc', 'Subject']:
if header in message:
del message[header]
message['To'] = msgTo
message['Subject'] = msgSubject message['Subject'] = msgSubject
try: try:
result = callGAPI(gmail.users().messages(), 'send', result = callGAPI(gmail.users().messages(), 'send',
@@ -80144,17 +80431,12 @@ def CAABuildCondition():
unknownArgumentExit() unknownArgumentExit()
return condition return condition
CAA_COMBINING_FUNCTIONS_MAP = {
'and': 'AND',
'or': 'OR',
}
def CAABuildBasicLevel(): def CAABuildBasicLevel():
basic_level = {'conditions': []} basic_level = {'conditions': []}
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if myarg == 'combiningfunction': if myarg == 'combiningfunction':
basic_level['combiningFunction'] = getChoice(CAA_COMBINING_FUNCTIONS_MAP, mapChoice=True) basic_level['combiningFunction'] = getChoice(AND_OR_CONJUNCTION_MAP, mapChoice=True)
elif myarg == 'condition': elif myarg == 'condition':
basic_level['conditions'].append(CAABuildCondition()) basic_level['conditions'].append(CAABuildCondition())
else: else:
@@ -81675,6 +81957,7 @@ USER_COMMANDS_WITH_OBJECTS = {
Cmd.ARG_CHATEVENT: printShowChatEvents, Cmd.ARG_CHATEVENT: printShowChatEvents,
Cmd.ARG_CHATMEMBER: printShowChatMembers, Cmd.ARG_CHATMEMBER: printShowChatMembers,
Cmd.ARG_CHATMESSAGE: printShowChatMessages, Cmd.ARG_CHATMESSAGE: printShowChatMessages,
Cmd.ARG_CHATSEARCHMESSAGE: printShowChatSearchMessages,
Cmd.ARG_CHATSECTION: printShowChatSections, Cmd.ARG_CHATSECTION: printShowChatSections,
Cmd.ARG_CHATSECTIONITEM: printShowChatSectionItems, Cmd.ARG_CHATSECTIONITEM: printShowChatSectionItems,
Cmd.ARG_CHATSPACE: printShowChatSpaces, Cmd.ARG_CHATSPACE: printShowChatSpaces,
@@ -81793,6 +82076,7 @@ USER_COMMANDS_WITH_OBJECTS = {
Cmd.ARG_CHATEVENT: printShowChatEvents, Cmd.ARG_CHATEVENT: printShowChatEvents,
Cmd.ARG_CHATMEMBER: printShowChatMembers, Cmd.ARG_CHATMEMBER: printShowChatMembers,
Cmd.ARG_CHATMESSAGE: printShowChatMessages, Cmd.ARG_CHATMESSAGE: printShowChatMessages,
Cmd.ARG_CHATSEARCHMESSAGE: printShowChatSearchMessages,
Cmd.ARG_CHATSECTION: printShowChatSections, Cmd.ARG_CHATSECTION: printShowChatSections,
Cmd.ARG_CHATSECTIONITEM: printShowChatSectionItems, Cmd.ARG_CHATSECTIONITEM: printShowChatSectionItems,
Cmd.ARG_CHATSPACE: printShowChatSpaces, Cmd.ARG_CHATSPACE: printShowChatSpaces,
@@ -82021,6 +82305,7 @@ USER_COMMANDS_OBJ_ALIASES = {
Cmd.ARG_CHATEVENTS: Cmd.ARG_CHATEVENT, Cmd.ARG_CHATEVENTS: Cmd.ARG_CHATEVENT,
Cmd.ARG_CHATMEMBERS: Cmd.ARG_CHATMEMBER, Cmd.ARG_CHATMEMBERS: Cmd.ARG_CHATMEMBER,
Cmd.ARG_CHATMESSAGES: Cmd.ARG_CHATMESSAGE, Cmd.ARG_CHATMESSAGES: Cmd.ARG_CHATMESSAGE,
Cmd.ARG_CHATSEARCHMESSAGES: Cmd.ARG_CHATSEARCHMESSAGE,
Cmd.ARG_CHATSECTIONS: Cmd.ARG_CHATSECTION, Cmd.ARG_CHATSECTIONS: Cmd.ARG_CHATSECTION,
Cmd.ARG_CHATSECTIONITEMS: Cmd.ARG_CHATSECTIONITEM, Cmd.ARG_CHATSECTIONITEMS: Cmd.ARG_CHATSECTIONITEM,
Cmd.ARG_CHATSPACES: Cmd.ARG_CHATSPACE, Cmd.ARG_CHATSPACES: Cmd.ARG_CHATSPACE,

View File

@@ -846,6 +846,8 @@ class GamCLArgs():
ARG_CHATMEMBERS = 'chatmembers' ARG_CHATMEMBERS = 'chatmembers'
ARG_CHATMESSAGE = 'chatmessage' ARG_CHATMESSAGE = 'chatmessage'
ARG_CHATMESSAGES = 'chatmessages' ARG_CHATMESSAGES = 'chatmessages'
ARG_CHATSEARCHMESSAGE = 'chatsearchmessage'
ARG_CHATSEARCHMESSAGES = 'chatsearchmessages'
ARG_CHATSECTION = 'chatsection' ARG_CHATSECTION = 'chatsection'
ARG_CHATSECTIONS = 'chatsections' ARG_CHATSECTIONS = 'chatsections'
ARG_CHATSECTIONITEM = 'chatsectionitem' ARG_CHATSECTIONITEM = 'chatsectionitem'

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2025 Ross Scroggs All Rights Reserved. # Copyright (C) 2026 Ross Scroggs All Rights Reserved.
# #
# All Rights Reserved. # All Rights Reserved.
# #
@@ -312,6 +312,7 @@ INVALID_ALIAS = 'Invalid Alias'
INVALID_ATTENDEE_CHANGE = 'Invalid attendee change "{0}"' INVALID_ATTENDEE_CHANGE = 'Invalid attendee change "{0}"'
INVALID_CHARSET = 'Invalid charset "{0}"' INVALID_CHARSET = 'Invalid charset "{0}"'
INVALID_DATE_TIME_RANGE = '{0} {1} must be greater than/equal to {2} {3}' INVALID_DATE_TIME_RANGE = '{0} {1} must be greater than/equal to {2} {3}'
INVALID_DEVICE_QUERY = 'Invalid {0} query "{1}"; it must be if the form "field:value" and must not contain a "?"'
INVALID_EMOJI_NAME = '{0} does not match pattern :[0-9a-z_-]:' INVALID_EMOJI_NAME = '{0} does not match pattern :[0-9a-z_-]:'
INVALID_ENTITY = 'Invalid {0}, {1}' INVALID_ENTITY = 'Invalid {0}, {1}'
INVALID_EVENT_TIMERANGE = '{0} {1} must be less than {2}' INVALID_EVENT_TIMERANGE = '{0} {1} must be less than {2}'
@@ -474,7 +475,7 @@ REASON_ONLY_VALID_WITH_CONTENTRESTRICTIONS_READONLY_TRUE = 'reason only valid wi
REAUTHENTICATION_IS_NEEDED = 'Reauthentication is needed, please run\n\ngam oauth create' REAUTHENTICATION_IS_NEEDED = 'Reauthentication is needed, please run\n\ngam oauth create'
RECOMMEND_RUNNING_GAM_ROTATE_SAKEY = 'Recommend running "gam rotate sakey" to get a new key\n' RECOMMEND_RUNNING_GAM_ROTATE_SAKEY = 'Recommend running "gam rotate sakey" to get a new key\n'
REFUSING_TO_DEPROVISION_DEVICES = 'Refusing to deprovision {0} devices because acknowledge_device_touch_requirement not specified.\nDeprovisioning a device means the device will have to be physically wiped and re-enrolled to be managed by your domain again.\nThis requires physical access to the device and is very time consuming to perform for each device.\nPlease add "acknowledge_device_touch_requirement" to the GAM command if you understand this and wish to proceed with the deprovision.\nPlease also be aware that deprovisioning can have an effect on your device license count.\nSee https://support.google.com/chrome/a/answer/3523633 for full details.' REFUSING_TO_DEPROVISION_DEVICES = 'Refusing to deprovision {0} devices because acknowledge_device_touch_requirement not specified.\nDeprovisioning a device means the device will have to be physically wiped and re-enrolled to be managed by your domain again.\nThis requires physical access to the device and is very time consuming to perform for each device.\nPlease add "acknowledge_device_touch_requirement" to the GAM command if you understand this and wish to proceed with the deprovision.\nPlease also be aware that deprovisioning can have an effect on your device license count.\nSee https://support.google.com/chrome/a/answer/3523633 for full details.'
REFUSING_TO_DEPROVISION_N_DEVICES = 'Refusing to deprovision {0} devices due to maxtodepov {1}.' REFUSING_TO_DEPROVISION_N_DEVICES = 'Refusing to deprovision {0} devices due to maxtodepov {1}.\nSpecify "maxtodeprov 0" to deprovision all {0} devices'
REPLY_TO_CUSTOM_REQUIRES_EMAIL_ADDRESS = 'replyto REPLY_TO_CUSTOM requires customReplyTo <EmailAddress>' REPLY_TO_CUSTOM_REQUIRES_EMAIL_ADDRESS = 'replyto REPLY_TO_CUSTOM requires customReplyTo <EmailAddress>'
REQUEST_COMPLETED_NO_FILES = 'Request completed but no results/files were returned, try requesting again' REQUEST_COMPLETED_NO_FILES = 'Request completed but no results/files were returned, try requesting again'
REQUEST_NOT_COMPLETE = 'Request needs to be completed before downloading, current status is: {0}' REQUEST_NOT_COMPLETE = 'Request needs to be completed before downloading, current status is: {0}'

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2025 Ross Scroggs All Rights Reserved. # Copyright (C) 2026 Ross Scroggs All Rights Reserved.
# #
# All Rights Reserved. # All Rights Reserved.
# #
@@ -22,7 +22,7 @@
# Products/SKUs # Products/SKUs
_PRODUCTS = { _PRODUCTS = {
'101001': 'Cloud Identity', '101001': 'Cloud Identity Free',
'101005': 'Cloud Identity Premium', '101005': 'Cloud Identity Premium',
'101031': 'Google Workspace for Education', '101031': 'Google Workspace for Education',
'101033': 'Google Voice', '101033': 'Google Voice',
@@ -44,7 +44,7 @@ _PRODUCTS = {
} }
_SKUS = { _SKUS = {
'1010010001': { '1010010001': {
'product': '101001', 'aliases': ['identity', 'cloudidentity'], 'displayName': 'Cloud Identity'}, 'product': '101001', 'aliases': ['identity', 'cloudidentity', 'cloudidentityfree'], 'displayName': 'Cloud Identity Free'},
'1010050001': { '1010050001': {
'product': '101005', 'aliases': ['identitypremium', 'cloudidentitypremium'], 'displayName': 'Cloud Identity Premium'}, 'product': '101005', 'aliases': ['identitypremium', 'cloudidentitypremium'], 'displayName': 'Cloud Identity Premium'},
'1010070001': { '1010070001': {

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2023 Ross Scroggs All Rights Reserved. # Copyright (C) 2026 Ross Scroggs All Rights Reserved.
# #
# All Rights Reserved. # All Rights Reserved.
# #
@@ -145,10 +145,14 @@ PROPERTIES = {
{CLASS: PC_BOOLEAN, TITLE: 'IP Whitelisted',}, {CLASS: PC_BOOLEAN, TITLE: 'IP Whitelisted',},
'archived': 'archived':
{CLASS: PC_BOOLEAN, TITLE: 'Is Archived',}, {CLASS: PC_BOOLEAN, TITLE: 'Is Archived',},
'archivalTime':
{CLASS: PC_TIME, TITLE: 'Archival Time',},
'suspended': 'suspended':
{CLASS: PC_BOOLEAN, TITLE: 'Account Suspended',}, {CLASS: PC_BOOLEAN, TITLE: 'Account Suspended',},
'suspensionReason': 'suspensionReason':
{CLASS: PC_STRING, TITLE: 'Suspension Reason',}, {CLASS: PC_STRING, TITLE: 'Suspension Reason',},
'suspensionTime':
{CLASS: PC_TIME, TITLE: 'Suspension Time',},
'changePasswordAtNextLogin': 'changePasswordAtNextLogin':
{CLASS: PC_BOOLEAN, TITLE: 'Must Change Password',}, {CLASS: PC_BOOLEAN, TITLE: 'Must Change Password',},
'recoveryEmail': 'recoveryEmail':

View File

@@ -456,9 +456,9 @@
See: https://cloud.google.com/access-context-manager/docs/custom-access-level-spec See: https://cloud.google.com/access-context-manager/docs/custom-access-level-spec
<QueryContact> ::= <String> <QueryContact> ::= <String>
See: https://developers.google.com/google-apps/contacts/v3/reference#contacts-query-parameters-reference See: https://developers.google.com/google-apps/contacts/v3/reference#contacts-query-parameters-reference
<QueryCrOS> ::= <String> <QueryCrOS> ::= <String>:<String>
See: https://support.google.com/chrome/a/answer/1698333 See: https://support.google.com/chrome/a/answer/1698333
<QueryDevice> ::= <String> <QueryDevice> ::= <String>:<String>
See: https://support.google.com/a/answer/7549103 See: https://support.google.com/a/answer/7549103
<QueryDriveFile> ::= <String> <QueryDriveFile> ::= <String>
See: https://developers.google.com/drive/api/v3/search-files See: https://developers.google.com/drive/api/v3/search-files
@@ -471,7 +471,7 @@
<QueryItem> ::= <UniqueID>|<String> <QueryItem> ::= <UniqueID>|<String>
<QueryMemberRestrictions> ::= <String> <QueryMemberRestrictions> ::= <String>
See: https://cloud.google.com/identity/docs/reference/rest/v1beta1/SecuritySettings#MemberRestriction See: https://cloud.google.com/identity/docs/reference/rest/v1beta1/SecuritySettings#MemberRestriction
<QueryMobile> ::= <String> <QueryMobile> ::= <String>:<String>
See: https://support.google.com/a/answer/7549103 See: https://support.google.com/a/answer/7549103
<QueryTeamDrive> ::= <String> <QueryTeamDrive> ::= <String>
See: https://developers.google.com/drive/api/v3/search-parameters See: https://developers.google.com/drive/api/v3/search-parameters

View File

@@ -68,7 +68,8 @@ gam oauth create
``` ```
<OrgUnitPath> ::= /|(/<String)+ <OrgUnitPath> ::= /|(/<String)+
<QueryCrOS> ::= <String> See: https://support.google.com/chrome/a/answer/1698333 <QueryCrOS> ::= <String>:<String>
See: https://support.google.com/chrome/a/answer/1698333
<CommandID> ::= <String> <CommandID> ::= <String>
<CrOSID> ::= <String> <CrOSID> ::= <String>
<CrOSIDList> ::= "<CrOSID>(,<CrOSID>)*" <CrOSIDList> ::= "<CrOSID>(,<CrOSID>)*"
@@ -97,6 +98,7 @@ gam oauth create
autoupdateexpiration| autoupdateexpiration|
autoupdatethrough| autoupdatethrough|
backlightinfo| backlightinfo|
bluetoothadapterinfo|
bootmode| bootmode|
chromeostype| chromeostype|
cpuinfo| cpuinfo|
@@ -130,6 +132,7 @@ gam oauth create
orgunitpath|org|ou| orgunitpath|org|ou|
osupdatestatus| osupdatestatus|
osversion| osversion|
osversioncompliance|
platformversion| platformversion|
recentusers| recentusers|
screenshotfiles| screenshotfiles|
@@ -184,25 +187,30 @@ gam oauth create
<CrOSActivityListFieldNameList> ::= "<CrOSActivityListFieldName>(,<CrOSActivityListFieldName>)*" <CrOSActivityListFieldNameList> ::= "<CrOSActivityListFieldName>(,<CrOSActivityListFieldName>)*"
<CrOSTelemetryFieldName> ::= <CrOSTelemetryFieldName> ::=
appreport|
audiostatusreport| audiostatusreport|
batteryinfo| batteryinfo|
batterystatusreport| batterystatusreport|
bootPerformancereport| bootperformancereport|
cpuinfo| cpuinfo|
cpustatusreport| cpustatusreport|
customer| customer|
deviceid| deviceid|
graphicsinfo| graphicsinfo|
graphicsstatusreport| graphicsstatusreport|
heartbeatstatusreport|
kioskappstatusreport|
memoryinfo| memoryinfo|
memorystatusreport| memorystatusreport|
name| name|
networkbandwidthreport|
networkdiagnosticsreport| networkdiagnosticsreport|
networkinfo| networkinfo|
networkstatusreport| networkstatusreport|
orgunitid| orgunitid|
osupdatestatus| osupdatestatus|
peripheralsreport| peripheralsreport|
runtimecountersreport|
serialnumber| serialnumber|
storageinfo| storageinfo|
storagestatusreport| storagestatusreport|
@@ -210,20 +218,22 @@ gam oauth create
<CrOSTelemetryFieldNameList> ::= "<CrOSTelemetryFieldName>(,<CrOSTelemetryFieldName>)*" <CrOSTelemetryFieldNameList> ::= "<CrOSTelemetryFieldName>(,<CrOSTelemetryFieldName>)*"
<CrOSTelemetryListFieldName> ::= <CrOSTelemetryListFieldName> ::=
appreport|
audiostatusreport| audiostatusreport|
batteryinfo|
batterystatusreport| batterystatusreport|
bootperformancereport| bootperformancereport|
cpuinfo|
cpustatusreport| cpustatusreport|
graphicsstatusreport| graphicsstatusreport|
heartbeatstatusreport|
kioskappstatusreport|
memorystatusreport| memorystatusreport|
networkbandwidthreport|
networkdiagnosticsreport| networkdiagnosticsreport|
networkstatusreport| networkstatusreport|
osupdatestatus| osupdatestatus|
peripheralsreport| peripheralsreport|
storagestatusreport| runtimecountersreport|
thunderboltinfo storagestatusreport
<CrOSTelemetryListFieldNameList> ::= "<CrOSTelemetryListFieldName>(,<CrOSTelemetryLIstFieldName>)*" <CrOSTelemetryListFieldNameList> ::= "<CrOSTelemetryListFieldName>(,<CrOSTelemetryLIstFieldName>)*"
``` ```
@@ -409,11 +419,13 @@ gam update ou csvkmd cros.csv keyfield OU datafield deviceId add croscsvdata dev
reenable reenable
gam <CrOSTypeEntity> update action <CrOSAction> [acknowledge_device_touch_requirement] gam <CrOSTypeEntity> update action <CrOSAction> [acknowledge_device_touch_requirement]
[actionbatchsize <Integer>] [actionbatchsize <Integer>] [maxtodeprov <Integer>]
``` ```
ChromeOS devices are now processed in batches. ChromeOS devices are now processed in batches.
The batch size defaults to 10, the `actionbatchsize <Integer>` option can be used to set a batch size between 10 and 250. The batch size defaults to 10, the `actionbatchsize <Integer>` option can be used to set a batch size between 10 and 250.
### Deprovisioning
As deprovisioning ChromeOS devices is not reversible, you must enter `acknowledge_device_touch_requirement` As deprovisioning ChromeOS devices is not reversible, you must enter `acknowledge_device_touch_requirement`
when `<CrOSAction>` is `deprovision_same_model_replace`, `deprovision_different_model_replace`, when `<CrOSAction>` is `deprovision_same_model_replace`, `deprovision_different_model_replace`,
`deprovision_retiring_device` or `deprovision_upgrade_transfer`. `deprovision_retiring_device` or `deprovision_upgrade_transfer`.
@@ -424,6 +436,20 @@ each device. Please also be aware that deprovisioning can have an effect on your
See https://support.google.com/chrome/a/answer/3523633 for full details. See https://support.google.com/chrome/a/answer/3523633 for full details.
Prior to version 7.43.05, all devices in `<CrOSEntity>` would be deprovisioned. When `<CrOSEntity>`
was derived from an OU, this was desirable. However, if `<CrOSEntity>` was derived from a query,
more devices than desired may have been deprovisioned. In version 7.43.05 and higher,
GAM defaults to not deprovisioning devices if the number of devices exceeds one.
The option `max_to_deprov <Integer>` can be used to verify the number of devices to be deprovisioned;
no deprovisions are processed if the number of devices in `<CrOSEntity>` exceeds `<Integer>`;
the default value is one; set `<Number>` to 0 for no limit.
When `<CrOSEntity>` is derived from an OU, set `max_to_deprov 0` and all devices will be deprovisioned.
When `<CrOSEntity>` is derived from a query, e.g., `cros_sn <SerialNumber>`, the default `max_to_deprov 1`
protects you from accidentally deprovisioning more devices than desired.
## Send remote commands to ChromeOS devices ## Send remote commands to ChromeOS devices
Thanks to Jay for most of the following. Thanks to Jay for most of the following.
@@ -947,19 +973,21 @@ By default, Gam displays the information as an indented list of keys and values:
gam print crostelemetry [todrive <ToDriveAttribute>*] gam print crostelemetry [todrive <ToDriveAttribute>*]
[(ou|org|orgunit|ou_and_children <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)] [(ou|org|orgunit|ou_and_children <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)]
<CrOSTelemetryFieldName>* [fields <CrOSTelemetryFieldNameList>] <CrOSTelemetryFieldName>* [fields <CrOSTelemetryFieldNameList>]
[reverselists <CrOSTelemetryListFieldNameList>] [reverselists <CrOSTelemetryListFieldNameList>] [oneitemperrow]
[start <Date>] [end <Date>] [listlimit <Number>] [start <Date>] [end <Date>] [listlimit <Number>]
[formatjson [quotechar <Character>]] [formatjson [quotechar <Character>]]
``` ```
Use these options to select CrOS devices; if none are chosen, all CrOS devices in the account are selected. Use these options to select CrOS devices; if none are chosen, all CrOS devices in the account are selected.
- `ou|org|orgunit <OrgUnitItem>` - Select CrOS devices directly in the OU `<OrgUnitItem>` - `ou|org|orgunit <OrgUnitItem>` - Select CrOS devices directly in the OU `<OrgUnitItem>`
- `ou_and_children <OrgUnitItem>` - Select CrOS devices in the OU `<OrgUnitItem>` and its sub OUs - `ou_and_children <OrgUnitItem>` - Select CrOS devices in the OU `<OrgUnitItem>` and its sub OUs
- `cros_sn <SerialNumber>` - Select the CrOS device with serial number `<SerialNumber>`. - `cros_sn <SerialNumber>` - Select the CrOS device with serial number `<SerialNumber>`.
- `filter <String>` - Select the CrOS device with a filter. - `filter <String>` - Select the CrOS device with a filter.
Use these options to limit/modify the displayed lists.
- `listlimit <Number>` - Limits the number of repetitions to `<Number>`; if not specified or `<Number>` equals zero, there is no limit. - `listlimit <Number>` - Limits the number of repetitions to `<Number>`; if not specified or `<Number>` equals zero, there is no limit.
- `start <Date>` and `end <Date>` - Constrain list `reportTime` to fall within the specified `<Dates>`. If a `<Date>` isn't specified, there is no filtering in that range. - `start <Date>` and `end <Date>` - Constrain list `reportTime` to fall within the specified `<Dates>`. If a `<Date>` isn't specified, there is no filtering in that range.
- `reverselists <CrOSTelemetryListFieldNameList>` - For each list, change order from ascending (oldest to newest) to descending (newest to oldest); this makes it easy to get the `N` most recent values with `listlimit N reverselists cpustatusreport,memorystatusreport` - `reverselists <CrOSTelemetryListFieldNameList>` - For each list, change order from descending (newest to oldest) to ascending (oldest to newest)
- `oneitemrerrow` - Display each instance of a list item on a separate row; by default, all list items are displayed on a single row
By default, all telemetry data is displayed, use the following to select specific fields: By default, all telemetry data is displayed, use the following to select specific fields:
- `<CrOSTelemetryFieldName>*` - Specify fields individually - `<CrOSTelemetryFieldName>*` - Specify fields individually

View File

@@ -56,7 +56,7 @@ Use this table to filter/query for specific device types:
``` ```
<AssetTag> ::= <String> <AssetTag> ::= <String>
<AssetTagList> ::= "<AssetTag>(,<AssetTag>)*" <AssetTagList> ::= "<AssetTag>(,<AssetTag>)*"
<QueryDevice> ::= <String> <QueryDevice> ::= <String>:<String>
See: https://support.google.com/a/answer/7549103 See: https://support.google.com/a/answer/7549103
<QueryDeviceList> ::= "<QueryDevice>(,<QueryDevice>)*" <QueryDeviceList> ::= "<QueryDevice>(,<QueryDevice>)*"
<DeviceID> ::= devices/<String> <DeviceID> ::= devices/<String>
@@ -133,6 +133,8 @@ Use this table to filter/query for specific device types:
``` ```
## Create a company device ## Create a company device
This method is available only to customers who have one of the following SKUs: Enterprise Standard, Enterprise Plus, Enterprise for Education, and Cloud Identity Premium.
Adds a new device to the Google company-owned inventory. Once a user is assigned and enrolled on the device the device will be considered company-owned for management purposes. Adds a new device to the Google company-owned inventory. Once a user is assigned and enrolled on the device the device will be considered company-owned for management purposes.
The device will also register as company-owned with Google services like [Context-Aware Access (CAA)](https://support.google.com/a/answer/9275380). The device will also register as company-owned with Google services like [Context-Aware Access (CAA)](https://support.google.com/a/answer/9275380).
``` ```

View File

@@ -16,12 +16,12 @@ In zsh, if an argument contains a `~`, `|`, `!`, `>`, or `<`, you must enclose t
To embed a `'` in a string enclosed in `"`, enter `'`; `name "Test'Group"`. To embed a `'` in a string enclosed in `"`, enter `'`; `name "Test'Group"`.
To embed a `"` in a string enclosed in `"`, enter `\"`; `name "Test\"Group"`.
To embed a `"` in a string enclosed in `'`, enter `"`; `name 'Test"Group'`. To embed a `"` in a string enclosed in `'`, enter `"`; `name 'Test"Group'`.
To embed a `'` in a string enclosed in `'`, enter `'\''`; `name 'Test'\''Group'`. To embed a `'` in a string enclosed in `'`, enter `'\''`; `name 'Test'\''Group'`.
To embed a `"` in a string enclosed in `"`, enter `\"`; `name "Test\"Group"`.
Linux and MacOS do not recognize smart or curly quotes, `“` and `”`, they can not be used to enclose arguments. Linux and MacOS do not recognize smart or curly quotes, `“` and `”`, they can not be used to enclose arguments.
## Windows Command Prompt ## Windows Command Prompt

View File

@@ -37,7 +37,7 @@ gam info domain [<DomainName>]
gam show domains gam show domains
[formatjson] [formatjson]
``` ```
For `info`, if `<DomainName>` is omitted, information about the primary domain will be displayed. For `info`, if `<DomainName>` is omitted, customer information about the primary domain will be displayed.
By default, Gam displays the information as an indented list of keys and values. By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format. * `formatjson` - Display the fields in JSON format.

View File

@@ -10,6 +10,94 @@ 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 See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation
### 7.44.02
Added fields `bluetoothadapterinfo` and `osversioncompliance` to `<CrOSFieldName>` for use
in `gam info|print cros`.
### 7.44.01
Added option `oneitemperrow` to `gam print crostelemetry` to have each of a device's
report field entries displayed on a separate row with all of the other device fields.
Added additional fields to `<CrOSTelemetryFieldName>`and `<CrOSTelemetryListFieldName>`:
```
appreport
heartbeatstatusreport
kioskappstatusreport
networkbandwidthreport
runtimecountersreport
```
### 7.44.00
Added support for User data `archivalTime` and `suspensionTime` that is available
when fields `archived` and `suspended` are requested in `gam info user` and `gam print users`.
Added the following options to `gam <UserTypeEntity> show chatmessages` to simplify specifying a filter.
```
start|starttime <Date>|<Time>
end|endtime <Date>|<Time>
range <Date>|<Time> <Date>|<Time>
thread <ChatThread>
```
Added commands to search for and display chat messages.
* See: https://github.com/GAM-team/GAM/wiki/Users-Chat#display-chat-messages-by-searching
These commands are in Developer Preview; to use them you must have these values set in `gam.cfg`.
```
developer_preview_apis = chat
developer_preview_api_key = <DeveloperPreviewKey>
```
Upgraded to Python 3.14.5.
### 7.43.10
Updated `gam <UserTypeEntity> forward message|thread [recipient|to] <RecipientEntity>` to not forward messages
to the `Bcc` recipients of the original message.
Fixed bug in `gam <UserTypeEntity> forward message|thread [recipient|to] <RecipientEntity> addorigfieldstosubject`
where the recipient of the forwarded message was added to the subject line instead of the recipient of the original message.
### 7.43.09
Fixed bug in `gam <UserTypeEntity> print filelist` that caused a trap.
### 7.43.08
Fixed bug and formatting issues in `gam info device <DeviceEntity>`.
### 7.43.07
Improved validation of `<QueryCrOS>`, `<QueryDevice>` and `<QueryMobile>`.
### 7.43.06
Updated commands that use `<QueryCrOS>`, `<QueryDevice>` or `<QueryMobile>` to validate
that it is of the form `field:value` and that `value` does not contain a '?'.
Without validation, Google can return many more devices than are expected.
### 7.43.05
Added option `matchfield attendeesorganizer <Boolean> <EmailAddressEntity>` to `<EventMatchProperty>`
that is used in commands that process events. The match is true if all of the addresses in `<EmailAddressEntity>`
are present as attendees in the event and are an organizer or not based on `<Boolean>`.
Added option `max_to_deprov <Integer>` to `gam update cros <CrOSEntity> action <CrOSAction>`
that is used when `<CrOSAction>` is any of the following:
```
deprovision_different_model_replace|
deprovision_different_model_replacement|
deprovision_retiring_device|
deprovision_same_model_replace|
deprovision_same_model_replacement|
deprovision_upgrade_transfer
```
`max_to_deprov <Integer>` - No deprovisions are processed if the number of devices in `<CrOSEntity>` exceeds `<Integer>`;
the default value is one; set `<Integer>` to 0 for no limit.
### 7.43.04 ### 7.43.04
Added option `include_suspended_zeros [<Boolean>]` to `gam print vaultcounts` that causes Added option `include_suspended_zeros [<Boolean>]` to `gam print vaultcounts` that causes
@@ -28,7 +116,7 @@ gam <UserTypeEntity> print filelist ... filepath|fullpath
### 7.43.02 ### 7.43.02
Added option `maxactivities <Number>` to `gam <UserTypeEntity> print driveactivity` to limit Added option `maxactivities <Integer>` to `gam <UserTypeEntity> print driveactivity` to limit
the number of activities displayed; the default is 0, no limit. the number of activities displayed; the default is 0, no limit.
### 7.43.01 ### 7.43.01

View File

@@ -251,10 +251,10 @@ writes the credentials into the file oauth2.txt.
``` ```
gamteam@server:/Users/gamteam$ rm -f /Users/gamteam/GAMConfig/oauth2.txt gamteam@server:/Users/gamteam$ rm -f /Users/gamteam/GAMConfig/oauth2.txt
gamteam@server:/Users/gamteam$ gam version gamteam@server:/Users/gamteam$ gam version
GAM 7.43.04 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.44.02 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.4 64-bit final Python 3.14.5 64-bit final
macOS Tahoe 26.4.1 arm64 macOS Tahoe 26.5 arm64
Path: /Users/gamteam/bin/gam7 Path: /Users/gamteam/bin/gam7
Config File: /Users/gamteam/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/gamteam/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
@@ -1034,9 +1034,9 @@ writes the credentials into the file oauth2.txt.
``` ```
C:\>del C:\GAMConfig\oauth2.txt C:\>del C:\GAMConfig\oauth2.txt
C:\>gam version C:\>gam version
GAM 7.43.04 - https://github.com/GAM-team/GAM - pythonsource GAM 7.44.02 - https://github.com/GAM-team/GAM - pythonsource
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.14.4 64-bit final Python 3.14.5 64-bit final
Windows 11 10.0.26200 AMD64 Windows 11 10.0.26200 AMD64
Path: C:\GAM7 Path: C:\GAM7
Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com

View File

@@ -50,7 +50,7 @@
| Assured Controls | 1010390001 | assuredcontrols | | Assured Controls | 1010390001 | assuredcontrols |
| Assured Controls Plus | 1010390002 | assuredcontrolsplus | | Assured Controls Plus | 1010390002 | assuredcontrolsplus |
| Chrome Enterprise Premium | 1010400001 | cep | chromeenterprisepremium | | Chrome Enterprise Premium | 1010400001 | cep | chromeenterprisepremium |
| Cloud Identity | 1010010001 | cloudidentity | | Cloud Identity Free | 1010010001 | cloudidentity |
| Cloud Identity Premium | 1010050001 | cloudidentitypremium | | Cloud Identity Premium | 1010050001 | cloudidentitypremium |
| Cloud Search | 1010350001 | cloudsearch | | Cloud Search | 1010350001 | cloudsearch |
| Colab Pro | 1010500001 | colabpro | | Colab Pro | 1010500001 | colabpro |
@@ -163,7 +163,7 @@
assuredcontrolsplus | 1010390002 | Assured Controls Plus | assuredcontrolsplus | 1010390002 | Assured Controls Plus |
bce | beyondcorp | beyondcorpenterprise | cep | chromeenterprisepremium | 1010400001 | Chrome Enterprise Premium | bce | beyondcorp | beyondcorpenterprise | cep | chromeenterprisepremium | 1010400001 | Chrome Enterprise Premium |
cdm | chrome | googlechromedevicemanagement | Google-Chrome-Device-Management | cdm | chrome | googlechromedevicemanagement | Google-Chrome-Device-Management |
cloudidentity | identity | 1010010001 | Cloud Identity | cloudidentityfree| cloudidentity | identity | 1010010001 | Cloud Identity Free |
cloudidentitypremium | identitypremium | 1010050001 | Cloud Identity Premium | cloudidentitypremium | identitypremium | 1010050001 | Cloud Identity Premium |
cloudsearch | 1010350001 | Cloud Search | cloudsearch | 1010350001 | Cloud Search |
colabpro | 1010500001 | Colab Pro | colabpro | 1010500001 | Colab Pro |

View File

@@ -16,7 +16,7 @@
## Definitions ## Definitions
``` ```
<QueryMobile> ::= <String> <QueryMobile> ::= <String>:<String>
See: https://support.google.com/a/answer/7549103 See: https://support.google.com/a/answer/7549103
<QueryMobileList> ::= "<QueryMobile>(,<QueryMobile>)*" <QueryMobileList> ::= "<QueryMobile>(,<QueryMobile>)*"
<ResourceID> ::= <String> <ResourceID> ::= <String>

View File

@@ -12,6 +12,7 @@ Thank you.
* James Seymour - https://sites.google.com/view/gam--commands/ * James Seymour - https://sites.google.com/view/gam--commands/
* Kevin Melillo - https://github.com/KevinMelilloIEEE/gam-script * Kevin Melillo - https://github.com/KevinMelilloIEEE/gam-script
* Korey Rideout - https://chatgpt.com/g/g-PTxxnVPMG-gam-assist-now-turbocharged-with-gam7 * Korey Rideout - https://chatgpt.com/g/g-PTxxnVPMG-gam-assist-now-turbocharged-with-gam7
* Paul Ogier (Taming.Tech) - GAM Scripts https://github.com/PaulOgier/GAMScripts
* Paul Ogier (Taming.Tech) - GAM7 Course on Udemy https://taming.tech/GAMCourse * 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) - GAM7 Tutorials https://www.youtube.com/watch?v=g9LDeyXQNLI&list=PL_dLiK09pJVhKJxZHNk9CHK0q5hkZ856w
* Paul Ogier (Taming.Tech) - Installation videos * Paul Ogier (Taming.Tech) - Installation videos

View File

@@ -277,6 +277,7 @@
<EventMatchProperty> ::= <EventMatchProperty> ::=
(matchfield attendees <EmailAddressEntity>)| (matchfield attendees <EmailAddressEntity>)|
(matchfield attendeesorganizer <Boolean> <EmailAddressEntity>)|
(matchfield attendeesonlydomainlist <DomainNameList>)| (matchfield attendeesonlydomainlist <DomainNameList>)|
(matchfield attendeesdomainlist <DomainNameList>)| (matchfield attendeesdomainlist <DomainNameList>)|
(matchfield attendeesnotdomainlist <DomainNameList>)| (matchfield attendeesnotdomainlist <DomainNameList>)|
@@ -460,8 +461,11 @@ The Google Calendar API processes `<EventSelectProperty>*`; you may specify none
* `singleevents` - Whether to expand recurring events into instances and only return single one-off events and instances of recurring events, but not the underlying recurring events themselves * `singleevents` - Whether to expand recurring events into instances and only return single one-off events and instances of recurring events, but not the underlying recurring events themselves
* `updatedmin <Time>` - Lower bound for an event's last modification time (as a RFC3339 timestamp) to filter by. When specified, entries deleted since this time will always be included regardless of showdeletedevents * `updatedmin <Time>` - Lower bound for an event's last modification time (as a RFC3339 timestamp) to filter by. When specified, entries deleted since this time will always be included regardless of showdeletedevents
GAM processes `<EventMatchProperty>*`; you may specify none or multiple properties. GAM processes `<EventMatchProperty>*`
* `matchfield attendees <EmailAddressEntity>` - All of the attendees in `<EmailAddressEntity>` must be present ; you may specify none or multiple properties.
* `matchfield attendees <EmailAddressEntity>` - All of the addresses in `<EmailAddressEntity>` must be present as attendees
* `matchfield attendeesorganizer <Boolean> <EmailAddressEntity>` - All of the addressed in `<EmailAddressEntity>` must be present
as attendees and are an organizer or not based on `<Boolean>`
* `matchfield attendeesonlydomainlist <DomainNameList>` - All attendee's email addresses must be in a domain in `<DomainNameList>` * `matchfield attendeesonlydomainlist <DomainNameList>` - All attendee's email addresses must be in a domain in `<DomainNameList>`
* For example, this lets you look for events with all attendees in your internal domains. You should include `resource.calendar.google.com` * For example, this lets you look for events with all attendees in your internal domains. You should include `resource.calendar.google.com`
in `<DomainNameList>` if the events use resources. in `<DomainNameList>` if the events use resources.

View File

@@ -16,6 +16,7 @@
- [Display Chat Members](#display-chat-members) - [Display Chat Members](#display-chat-members)
- [Manage Chat Messages](#manage-chat-messages) - [Manage Chat Messages](#manage-chat-messages)
- [Display Chat Messages](#display-chat-messages) - [Display Chat Messages](#display-chat-messages)
- [Display Chat Messages by Searching](#display-chat-messages-by-searching)
- [Display Chat Events](#display-chat-events) - [Display Chat Events](#display-chat-events)
- [Manage Chat Emojis](#manage-chat-emojis) - [Manage Chat Emojis](#manage-chat-emojis)
- [Display Chat Emojis](#display-chat-emojis) - [Display Chat Emojis](#display-chat-emojis)
@@ -65,6 +66,7 @@ Google requires that you have a Chat Bot configured in order to use the Chat API
* [Chat API - Custom Emojis](https://developers.google.com/workspace/chat/api/reference/rest/v1/customEmojis) * [Chat API - Custom Emojis](https://developers.google.com/workspace/chat/api/reference/rest/v1/customEmojis)
* [Chat API - Members](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.members/list) * [Chat API - Members](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.members/list)
* [Chat API - Messages](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.messages/list) * [Chat API - Messages](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.messages/list)
* [Chat API - Search Messages](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.messages/search)
* [Chat API - Events](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.spaceEvents/list) * [Chat API - Events](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.spaceEvents/list)
* [Chat API - User Sections](https://developers.google.com/workspace/chat/api/reference/rest/v1/users.sections) * [Chat API - User Sections](https://developers.google.com/workspace/chat/api/reference/rest/v1/users.sections)
* [Apps in Google Chat](https://support.google.com/chat/answer/7655820) * [Apps in Google Chat](https://support.google.com/chat/answer/7655820)
@@ -109,8 +111,8 @@ Google requires that you have a Chat Bot configured in order to use the Chat API
<ChatThread> ::= spaces/<String>/threads/<String> <ChatThread> ::= spaces/<String>/threads/<String>
<ChatSpaceType> ::= <ChatSpaceType> ::=
space| space|
groupchat| groupchat|
directmessage directmessage
<ChatSpaceTypeList> ::= "<ChatSpaceType>(,<ChatSpaceType>)*" <ChatSpaceTypeList> ::= "<ChatSpaceType>(,<ChatSpaceType>)*"
<ChatMessageID> ::= client-<String> <ChatMessageID> ::= client-<String>
<String> must contain only lowercase letters, numbers, and hyphens up to 56 characters in length. <String> must contain only lowercase letters, numbers, and hyphens up to 56 characters in length.
@@ -908,7 +910,7 @@ gam user user@domain.com delete chatmessage name spaces/AAAADi-pvqc/messages/PKJ
``` ```
## Display Chat Messages ## Display Chat Messages
Display a specific Chat message. Display a specific chat message.
``` ```
gam <UserTypeEntity> info chatmessage name <ChatMessage> gam <UserTypeEntity> info chatmessage name <ChatMessage>
@@ -923,12 +925,15 @@ By default, Gam displays the information as an indented list of keys and values.
gam user user@domain.com info chatmessage name spaces/AAAADi-pvqc/messages/PKJrx90ooIU.PKJrx90ooIU gam user user@domain.com info chatmessage name spaces/AAAADi-pvqc/messages/PKJrx90ooIU.PKJrx90ooIU
``` ```
### Display information about all chat messages in a chat space ### Display information about chat messages in a chat space
``` ```
gam <UserTypeEntity> show chatmessages gam <UserTypeEntity> show chatmessages
<ChatSpace>+ <ChatSpace>+
[showdeleted [<Boolean>]] [filter <String>] [showdeleted [<Boolean>]]
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
[thread <ChatThread>])
[fields <ChatMessageFieldNameList>] [fields <ChatMessageFieldNameList>]
[orderby createtime [ascending|descending]]
[formatjson] [formatjson]
``` ```
By default, Gam displays the information as an indented list of keys and values. By default, Gam displays the information as an indented list of keys and values.
@@ -937,8 +942,11 @@ By default, Gam displays the information as an indented list of keys and values.
``` ```
gam <UserTypeEntity> print chatmessages [todrive <ToDriveAttribute>*] gam <UserTypeEntity> print chatmessages [todrive <ToDriveAttribute>*]
<ChatSpace>+ <ChatSpace>+
[showdeleted [<Boolean>]] [filter <String>] [showdeleted [<Boolean>]]
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
[thread <ChatThread>])
[fields <ChatMessageFieldNameList>] [fields <ChatMessageFieldNameList>]
[orderby createtime [ascending|descending]]
[formatjson [quotechar <Character>]] [formatjson [quotechar <Character>]]
``` ```
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format, By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
@@ -952,38 +960,76 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
By default, deleted messages are not displayed; use `showdeleted` to also display deleted messages. By default, deleted messages are not displayed; use `showdeleted` to also display deleted messages.
Use `filter <String>` to filter messages by `createTime` and `thread.name`. To filter messages by the time they were created:
* `start|starttime <Date>|<Time>` - Display messages created on or after the `<Date>|<Time>`
* `end|endtime <Date>|<Time>` - Display messages created before the `<Date>|<Time>`
* `range <Date>|<Time> <Date>|<Time>` - Display messages created on or after the first `<Date>|<Time>` and before the second `<Date>|<Time>`
To filter messages by the date they were created, specify the createTime with a timestamp in RFC-3339 format and double quotation marks. For example, "2023-04-21T11:30:00-04:00". Use `thread <String>` to filter messages by their thread name, e.g., `spaces/AAAAAAAAAAA/threads/123`.
* Use the greater than operator `>` to list messages that were created after a timestamp.
* Use the less than operator `<` to list messages that were created before a timestamp.
* To filter messages within a time interval, use the AND operator between two timestamps.
* To filter by thread, specify the thread.name, formatted as spaces/{space}/threads/{thread}. You can only specify one thread.name per query.
* To filter by both thread and date, use the AND operator in your query.
For example, the following queries are valid on Linux/MacOS: ## Display Chat Messages by Searching
These commands are in Developer Preview; to use them you must have these values set in `gam.cfg`.
``` ```
filter 'createTime > "2012-04-21T11:30:00-04:00"' developer_preview_apis = chat
filter 'createTime > "2012-04-21T11:30:00-04:00" AND thread.name = spaces/AAAAAAAAAAA/threads/123' developer_preview_api_key = <DeveloperPreviewKey>
filter 'createTime > "2012-04-21T11:30:00+00:00" AND createTime < "2013-01-01T00:00:00+00:00" AND thread.name = spaces/AAAAAAAAAAA/threads/123'
filter 'thread.name = spaces/AAAAAAAAAAA/threads/123'
``` ```
See the following for search option details:
https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.messages/search
For example, the following queries are valid on Windows Command Prompt: You must specify `keywords <StringList>`; messages that match any word|phrase in `<StringList>` are displayed.
``` Phrases must be enclosed in `"`.
filter "createTime > \"2012-04-21T11:30:00-04:00\"" * Linux, macOS, Windows Command Prompt - `keywords "\"things to do\" urgent"`
filter "createTime > \"2012-04-21T11:30:00-04:00\" AND thread.name = spaces/AAAAAAAAAAA/threads/123" * Windows Power Shell - ```keywords "`"things to do`" urgent"```
filter "createTime > \"2012-04-21T11:30:00+00:00\" AND createTime < \"2013-01-01T00:00:00+00:00\" AND thread.name = spaces/AAAAAAAAAAA/threads/123"
filter "thread.name = spaces/AAAAAAAAAAA/threads/123"
```
For example, the following queries are valid on Windows PowerShell: By default, all spaces the user has access to are searched; use the following options to limit the search.
* `<ChatSpace>*` - Specific chat spaces
* `displaynames [all|any] <StringList>` - Spaces with display names with partial matches of `all|any` of the words in `<StringList>`
Use the following to limit the search to messages with specific characteristics.
* `senders <EmailAddressEntity>` - Messages with any sender in `<EmailAddressEntity>`
* `usermentions [all|any] <EmailAddressEntity>` - Messages with mentions of `all|any` users in `<EmailAddressEntity>`
* `start|starttime <Date>|<Time>` - Messages created on or after the `<Date>|<Time>`
* `end|endtime <Date>|<Time>` - Messages created before the `<Date>|<Time>`
* `range <Date>|<Time> <Date>|<Time>` - Messages created on or after the first `<Date>|<Time>` and before the second `<Date>|<Time>`
* `hasattachment` - Messages with at least one attachment
``` ```
filter 'createTime > \"2012-04-21T11:30:00-04:00\"' gam <UserTypeEntity> show chatsearchmessages
filter 'createTime > \"2012-04-21T11:30:00-04:00\" AND thread.name = spaces/AAAAAAAAAAA/threads/123"' keywords <StringList>
filter 'createTime > \"2012-04-21T11:30:00+00:00\" AND createTime < \"2013-01-01T00:00:00+00:00\" AND thread.name = spaces/AAAAAAAAAAA/threads/123' <ChatSpace>*
filter 'thread.name = spaces/AAAAAAAAAAA/threads/123' [displaynames [all|any] <StringList>]
[senders <EmailAddressEntity>]*
[usermentions [all|any] <EmailAddressEntity>]*
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
[hasattachment]
[fields <ChatMessageFieldNameList>]
[orderby createtime|relevance]
[formatjson]
``` ```
By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format.
```
gam <UserTypeEntity> print chatsearchmessages [todrive <ToDriveAttribute>*]
keywords <StringList>
<ChatSpace>*
[displaynames [all|any] <StringList>]
[senders <EmailAddressEntity>]*
[usermentions [all|any] <EmailAddressEntity>]*
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
[hasattachment]
[fields <ChatMessageFieldNameList>]
[orderby createtime|relevance]
[formatjson [quotechar <Character>]]
```
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
* `formatjson` - Display the fields in JSON format.
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
## Display Chat Events ## Display Chat Events
Display a specific Chat event. Display a specific Chat event.

View File

@@ -477,12 +477,12 @@ When `matchlabel <LabelName>` is specified, the following characters are replace
## Forward messages/threads ## Forward messages/threads
``` ```
gam <UserTypeEntity> forward message|messages recipient|to <RecipientEntity> gam <UserTypeEntity> forward message|messages [recipient|to] <RecipientEntity>
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[labelids <LabelIDList>] [labelids <LabelIDList>]
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <MessageIDEntity>) [quick|notquick] [doit] [max_to_forward <Number>])|(ids <MessageIDEntity>)
[subject <String>] [addorigfieldstosubject] [subject <String>] [addorigfieldstosubject]
gam <UserTypeEntity> forward thread|threads recipient|to <RecipientEntity> gam <UserTypeEntity> forward thread|threads [recipient|to] <RecipientEntity>
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[labelids <LabelIDList>] [labelids <LabelIDList>]
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>) [quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>)

View File

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