gam7 7.27.4__tar.gz → 7.28.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of gam7 might be problematic. Click here for more details.

Files changed (303) hide show
  1. {gam7-7.27.4 → gam7-7.28.0}/.github/workflows/build.yml +22 -15
  2. {gam7-7.27.4 → gam7-7.28.0}/PKG-INFO +1 -1
  3. {gam7-7.27.4 → gam7-7.28.0}/src/GamCommands.txt +3 -0
  4. {gam7-7.27.4 → gam7-7.28.0}/src/GamUpdate.txt +19 -0
  5. {gam7-7.27.4 → gam7-7.28.0}/src/gam/__init__.py +63 -19
  6. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/glapi.py +0 -6
  7. {gam7-7.27.4 → gam7-7.28.0}/wiki/Classroom-Courses.md +4 -1
  8. {gam7-7.27.4 → gam7-7.28.0}/wiki/Cloud-Identity-Groups.md +1 -10
  9. {gam7-7.27.4 → gam7-7.28.0}/wiki/GamUpdates.md +8 -0
  10. {gam7-7.27.4 → gam7-7.28.0}/wiki/How-to-Upgrade-Legacy-GAM-to-GAM7.md +2 -2
  11. {gam7-7.27.4 → gam7-7.28.0}/wiki/Reports.md +4 -0
  12. {gam7-7.27.4 → gam7-7.28.0}/wiki/Version-and-Help.md +6 -6
  13. {gam7-7.27.4 → gam7-7.28.0}/.github/ISSUE_TEMPLATE/aa-question.md +0 -0
  14. {gam7-7.27.4 → gam7-7.28.0}/.github/ISSUE_TEMPLATE/za-bug-report.md +0 -0
  15. {gam7-7.27.4 → gam7-7.28.0}/.github/ISSUE_TEMPLATE/zz-feature-request.md +0 -0
  16. {gam7-7.27.4 → gam7-7.28.0}/.github/ISSUE_TEMPLATE.txt +0 -0
  17. {gam7-7.27.4 → gam7-7.28.0}/.github/actions/decrypt.sh +0 -0
  18. {gam7-7.27.4 → gam7-7.28.0}/.github/actions/entitlements.plist +0 -0
  19. {gam7-7.27.4 → gam7-7.28.0}/.github/actions/package_exclusions.txt +0 -0
  20. {gam7-7.27.4 → gam7-7.28.0}/.github/stale.yml +0 -0
  21. {gam7-7.27.4 → gam7-7.28.0}/.github/workflows/codeql-analysis.yml +0 -0
  22. {gam7-7.27.4 → gam7-7.28.0}/.github/workflows/get-cacerts.yml +0 -0
  23. {gam7-7.27.4 → gam7-7.28.0}/.github/workflows/pushwiki.yml +0 -0
  24. {gam7-7.27.4 → gam7-7.28.0}/.github/workflows/pypi.yml +0 -0
  25. {gam7-7.27.4 → gam7-7.28.0}/LICENSE +0 -0
  26. {gam7-7.27.4 → gam7-7.28.0}/README.md +0 -0
  27. {gam7-7.27.4 → gam7-7.28.0}/pyproject.toml +0 -0
  28. {gam7-7.27.4 → gam7-7.28.0}/src/.gitignore +0 -0
  29. {gam7-7.27.4 → gam7-7.28.0}/src/LICENSE +0 -0
  30. {gam7-7.27.4 → gam7-7.28.0}/src/README.md +0 -0
  31. {gam7-7.27.4 → gam7-7.28.0}/src/callgam.py +0 -0
  32. {gam7-7.27.4 → gam7-7.28.0}/src/gam/__main__.py +0 -0
  33. {gam7-7.27.4 → gam7-7.28.0}/src/gam/atom/__init__.py +0 -0
  34. {gam7-7.27.4 → gam7-7.28.0}/src/gam/atom/auth.py +0 -0
  35. {gam7-7.27.4 → gam7-7.28.0}/src/gam/atom/client.py +0 -0
  36. {gam7-7.27.4 → gam7-7.28.0}/src/gam/atom/core.py +0 -0
  37. {gam7-7.27.4 → gam7-7.28.0}/src/gam/atom/data.py +0 -0
  38. {gam7-7.27.4 → gam7-7.28.0}/src/gam/atom/http.py +0 -0
  39. {gam7-7.27.4 → gam7-7.28.0}/src/gam/atom/http_core.py +0 -0
  40. {gam7-7.27.4 → gam7-7.28.0}/src/gam/atom/http_interface.py +0 -0
  41. {gam7-7.27.4 → gam7-7.28.0}/src/gam/atom/mock_http.py +0 -0
  42. {gam7-7.27.4 → gam7-7.28.0}/src/gam/atom/mock_http_core.py +0 -0
  43. {gam7-7.27.4 → gam7-7.28.0}/src/gam/atom/mock_service.py +0 -0
  44. {gam7-7.27.4 → gam7-7.28.0}/src/gam/atom/service.py +0 -0
  45. {gam7-7.27.4 → gam7-7.28.0}/src/gam/atom/token_store.py +0 -0
  46. {gam7-7.27.4 → gam7-7.28.0}/src/gam/atom/url.py +0 -0
  47. {gam7-7.27.4 → gam7-7.28.0}/src/gam/cacerts.pem +0 -0
  48. {gam7-7.27.4 → gam7-7.28.0}/src/gam/cbcm-v1.1beta1.json +0 -0
  49. {gam7-7.27.4 → gam7-7.28.0}/src/gam/contactdelegation-v1.json +0 -0
  50. {gam7-7.27.4 → gam7-7.28.0}/src/gam/datastudio-v1.json +0 -0
  51. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/__init__.py +0 -0
  52. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/glaction.py +0 -0
  53. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/glcfg.py +0 -0
  54. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/glclargs.py +0 -0
  55. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/glentity.py +0 -0
  56. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/glgapi.py +0 -0
  57. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/glgdata.py +0 -0
  58. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/glglobals.py +0 -0
  59. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/glindent.py +0 -0
  60. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/glmsgs.py +0 -0
  61. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/glskus.py +0 -0
  62. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/gluprop.py +0 -0
  63. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/glverlibs.py +0 -0
  64. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gamlib/yubikey.py +0 -0
  65. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gdata/__init__.py +0 -0
  66. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gdata/alt/__init__.py +0 -0
  67. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gdata/alt/app_engine.py +0 -0
  68. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gdata/alt/appengine.py +0 -0
  69. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gdata/apps/__init__.py +0 -0
  70. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gdata/apps/audit/__init__.py +0 -0
  71. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gdata/apps/audit/service.py +0 -0
  72. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gdata/apps/contacts/__init__.py +0 -0
  73. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gdata/apps/contacts/service.py +0 -0
  74. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gdata/apps/service.py +0 -0
  75. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gdata/service.py +0 -0
  76. {gam7-7.27.4 → gam7-7.28.0}/src/gam/gdata/urlfetch.py +0 -0
  77. {gam7-7.27.4 → gam7-7.28.0}/src/gam/meet-v2beta.json +0 -0
  78. {gam7-7.27.4 → gam7-7.28.0}/src/gam/serviceaccountlookup-v1.json +0 -0
  79. {gam7-7.27.4 → gam7-7.28.0}/src/gam-install.sh +0 -0
  80. {gam7-7.27.4 → gam7-7.28.0}/src/gam-setup.bat +0 -0
  81. {gam7-7.27.4 → gam7-7.28.0}/src/gam.exe.manifest +0 -0
  82. {gam7-7.27.4 → gam7-7.28.0}/src/gam.py +0 -0
  83. {gam7-7.27.4 → gam7-7.28.0}/src/gam.spec +0 -0
  84. {gam7-7.27.4 → gam7-7.28.0}/src/gam.wxs +0 -0
  85. {gam7-7.27.4 → gam7-7.28.0}/src/license.rtf +0 -0
  86. {gam7-7.27.4 → gam7-7.28.0}/src/tools/a_atleast_b.py +0 -0
  87. {gam7-7.27.4 → gam7-7.28.0}/src/tools/gen-wix-xml-filelist.py +0 -0
  88. {gam7-7.27.4 → gam7-7.28.0}/src/tools/hooks/hook-googleapiclient.model.py +0 -0
  89. {gam7-7.27.4 → gam7-7.28.0}/src/tools/hooks/hook-httplib2.py +0 -0
  90. {gam7-7.27.4 → gam7-7.28.0}/src/tools/mkGamRef.py +0 -0
  91. {gam7-7.27.4 → gam7-7.28.0}/src/tools/openssl.props +0 -0
  92. {gam7-7.27.4 → gam7-7.28.0}/src/tools/ssd.mjs +0 -0
  93. {gam7-7.27.4 → gam7-7.28.0}/src/version_info.txt.in +0 -0
  94. {gam7-7.27.4 → gam7-7.28.0}/wiki/00scratch.md +0 -0
  95. {gam7-7.27.4 → gam7-7.28.0}/wiki/Addresses.md +0 -0
  96. {gam7-7.27.4 → gam7-7.28.0}/wiki/Administrators.md +0 -0
  97. {gam7-7.27.4 → gam7-7.28.0}/wiki/Alert-Center.md +0 -0
  98. {gam7-7.27.4 → gam7-7.28.0}/wiki/Aliases.md +0 -0
  99. {gam7-7.27.4 → gam7-7.28.0}/wiki/Authorization.md +0 -0
  100. {gam7-7.27.4 → gam7-7.28.0}/wiki/BNF-Syntax.md +0 -0
  101. {gam7-7.27.4 → gam7-7.28.0}/wiki/Basic-Items.md +0 -0
  102. {gam7-7.27.4 → gam7-7.28.0}/wiki/Bulk-Processing.md +0 -0
  103. {gam7-7.27.4 → gam7-7.28.0}/wiki/Business-Account-Management.md +0 -0
  104. {gam7-7.27.4 → gam7-7.28.0}/wiki/CSV-Input-Filtering.md +0 -0
  105. {gam7-7.27.4 → gam7-7.28.0}/wiki/CSV-Output-Filtering.md +0 -0
  106. {gam7-7.27.4 → gam7-7.28.0}/wiki/CSV-Special-Characters.md +0 -0
  107. {gam7-7.27.4 → gam7-7.28.0}/wiki/Calendars-Access.md +0 -0
  108. {gam7-7.27.4 → gam7-7.28.0}/wiki/Calendars-Events.md +0 -0
  109. {gam7-7.27.4 → gam7-7.28.0}/wiki/Calendars.md +0 -0
  110. {gam7-7.27.4 → gam7-7.28.0}/wiki/Chat-Bot-Setup-Use.md +0 -0
  111. {gam7-7.27.4 → gam7-7.28.0}/wiki/Chrome-AUE-Counts.md +0 -0
  112. {gam7-7.27.4 → gam7-7.28.0}/wiki/Chrome-Browser-Cloud-Management.md +0 -0
  113. {gam7-7.27.4 → gam7-7.28.0}/wiki/Chrome-Installed-Apps.md +0 -0
  114. {gam7-7.27.4 → gam7-7.28.0}/wiki/Chrome-Needs-Attention-Counts.md +0 -0
  115. {gam7-7.27.4 → gam7-7.28.0}/wiki/Chrome-Policies.md +0 -0
  116. {gam7-7.27.4 → gam7-7.28.0}/wiki/Chrome-Printers.md +0 -0
  117. {gam7-7.27.4 → gam7-7.28.0}/wiki/Chrome-Profile-Management.md +0 -0
  118. {gam7-7.27.4 → gam7-7.28.0}/wiki/Chrome-Version-Counts.md +0 -0
  119. {gam7-7.27.4 → gam7-7.28.0}/wiki/Chrome-Version-History.md +0 -0
  120. {gam7-7.27.4 → gam7-7.28.0}/wiki/ChromeOS-Devices.md +0 -0
  121. {gam7-7.27.4 → gam7-7.28.0}/wiki/Classroom-Guardians.md +0 -0
  122. {gam7-7.27.4 → gam7-7.28.0}/wiki/Classroom-Invitations.md +0 -0
  123. {gam7-7.27.4 → gam7-7.28.0}/wiki/Classroom-Membership.md +0 -0
  124. {gam7-7.27.4 → gam7-7.28.0}/wiki/Classroom-StudentGroups.md +0 -0
  125. {gam7-7.27.4 → gam7-7.28.0}/wiki/Cloud-Channel.md +0 -0
  126. {gam7-7.27.4 → gam7-7.28.0}/wiki/Cloud-Identity-Devices.md +0 -0
  127. {gam7-7.27.4 → gam7-7.28.0}/wiki/Cloud-Identity-Groups-Membership.md +0 -0
  128. {gam7-7.27.4 → gam7-7.28.0}/wiki/Cloud-Identity-Policies.md +0 -0
  129. {gam7-7.27.4 → gam7-7.28.0}/wiki/Cloud-Storage.md +0 -0
  130. {gam7-7.27.4 → gam7-7.28.0}/wiki/Collections-of-ChromeOS-Devices.md +0 -0
  131. {gam7-7.27.4 → gam7-7.28.0}/wiki/Collections-of-Items.md +0 -0
  132. {gam7-7.27.4 → gam7-7.28.0}/wiki/Collections-of-Users.md +0 -0
  133. {gam7-7.27.4 → gam7-7.28.0}/wiki/Command-Data-From-Google-Docs-Sheets-Storage.md +0 -0
  134. {gam7-7.27.4 → gam7-7.28.0}/wiki/Command-Line-Parsing.md +0 -0
  135. {gam7-7.27.4 → gam7-7.28.0}/wiki/Command-Logging-Progress.md +0 -0
  136. {gam7-7.27.4 → gam7-7.28.0}/wiki/Context-Aware-Access-Levels.md +0 -0
  137. {gam7-7.27.4 → gam7-7.28.0}/wiki/Customer.md +0 -0
  138. {gam7-7.27.4 → gam7-7.28.0}/wiki/Domain-People-Contacts-Profiles.md +0 -0
  139. {gam7-7.27.4 → gam7-7.28.0}/wiki/Domain-SharedContacts.md +0 -0
  140. {gam7-7.27.4 → gam7-7.28.0}/wiki/Domains-Verification.md +0 -0
  141. {gam7-7.27.4 → gam7-7.28.0}/wiki/Domains.md +0 -0
  142. {gam7-7.27.4 → gam7-7.28.0}/wiki/Downloads-Installs.md +0 -0
  143. {gam7-7.27.4 → gam7-7.28.0}/wiki/Drive-File-Selection.md +0 -0
  144. {gam7-7.27.4 → gam7-7.28.0}/wiki/Drive-Items.md +0 -0
  145. {gam7-7.27.4 → gam7-7.28.0}/wiki/Drive-REST-API-v3.md +0 -0
  146. {gam7-7.27.4 → gam7-7.28.0}/wiki/Email-Audit-Monitor.md +0 -0
  147. {gam7-7.27.4 → gam7-7.28.0}/wiki/Find-File-Owner.md +0 -0
  148. {gam7-7.27.4 → gam7-7.28.0}/wiki/GAM-Public-Chat-Room.md +0 -0
  149. {gam7-7.27.4 → gam7-7.28.0}/wiki/GAM-Release-Process.md +0 -0
  150. {gam7-7.27.4 → gam7-7.28.0}/wiki/GAM-Return-Codes.md +0 -0
  151. {gam7-7.27.4 → gam7-7.28.0}/wiki/GAM-with-minimal-GCP-rights.md +0 -0
  152. {gam7-7.27.4 → gam7-7.28.0}/wiki/GAM7-FAQ.md +0 -0
  153. {gam7-7.27.4 → gam7-7.28.0}/wiki/GAM7-on-Android-Devices.md +0 -0
  154. {gam7-7.27.4 → gam7-7.28.0}/wiki/GAM7-on-Chrome-OS-Devices.md +0 -0
  155. {gam7-7.27.4 → gam7-7.28.0}/wiki/Global-Address-List.md +0 -0
  156. {gam7-7.27.4 → gam7-7.28.0}/wiki/Google-Data-Transfers.md +0 -0
  157. {gam7-7.27.4 → gam7-7.28.0}/wiki/Google-Network-Addresses.md +0 -0
  158. {gam7-7.27.4 → gam7-7.28.0}/wiki/Groups-Membership.md +0 -0
  159. {gam7-7.27.4 → gam7-7.28.0}/wiki/Groups.md +0 -0
  160. {gam7-7.27.4 → gam7-7.28.0}/wiki/HTTPS-Proxy.md +0 -0
  161. {gam7-7.27.4 → gam7-7.28.0}/wiki/Home.md +0 -0
  162. {gam7-7.27.4 → gam7-7.28.0}/wiki/How-to-Install-GAM7.md +0 -0
  163. {gam7-7.27.4 → gam7-7.28.0}/wiki/How-to-Uninstall-GAM7.md +0 -0
  164. {gam7-7.27.4 → gam7-7.28.0}/wiki/How-to-Update-GAM7.md +0 -0
  165. {gam7-7.27.4 → gam7-7.28.0}/wiki/How-to-Upgrade-GAMADV-XTD3-to-GAM7.md +0 -0
  166. {gam7-7.27.4 → gam7-7.28.0}/wiki/Inbound-SSO.md +0 -0
  167. {gam7-7.27.4 → gam7-7.28.0}/wiki/Install-GAM-as-Python-Library.md +0 -0
  168. {gam7-7.27.4 → gam7-7.28.0}/wiki/Licenses.md +0 -0
  169. {gam7-7.27.4 → gam7-7.28.0}/wiki/List-Items.md +0 -0
  170. {gam7-7.27.4 → gam7-7.28.0}/wiki/List.md +0 -0
  171. {gam7-7.27.4 → gam7-7.28.0}/wiki/Meta-Commands-and-File-Redirection.md +0 -0
  172. {gam7-7.27.4 → gam7-7.28.0}/wiki/Mobile-Devices.md +0 -0
  173. {gam7-7.27.4 → gam7-7.28.0}/wiki/Organizational-Units.md +0 -0
  174. {gam7-7.27.4 → gam7-7.28.0}/wiki/Other-Resources.md +0 -0
  175. {gam7-7.27.4 → gam7-7.28.0}/wiki/Permission-Matches.md +0 -0
  176. {gam7-7.27.4 → gam7-7.28.0}/wiki/Python-Regular-Expressions.md +0 -0
  177. {gam7-7.27.4 → gam7-7.28.0}/wiki/README.md +0 -0
  178. {gam7-7.27.4 → gam7-7.28.0}/wiki/Rclone.md +0 -0
  179. {gam7-7.27.4 → gam7-7.28.0}/wiki/Reseller.md +0 -0
  180. {gam7-7.27.4 → gam7-7.28.0}/wiki/Resources.md +0 -0
  181. {gam7-7.27.4 → gam7-7.28.0}/wiki/Running-GAM7-securely-on-a-Google-Compute-Engine.md +0 -0
  182. {gam7-7.27.4 → gam7-7.28.0}/wiki/SSL-Root-CA-Certificates.md +0 -0
  183. {gam7-7.27.4 → gam7-7.28.0}/wiki/Schemas.md +0 -0
  184. {gam7-7.27.4 → gam7-7.28.0}/wiki/Scripts.md +0 -0
  185. {gam7-7.27.4 → gam7-7.28.0}/wiki/Send-Email.md +0 -0
  186. {gam7-7.27.4 → gam7-7.28.0}/wiki/Shared-Drives.md +0 -0
  187. {gam7-7.27.4 → gam7-7.28.0}/wiki/Sites.md +0 -0
  188. {gam7-7.27.4 → gam7-7.28.0}/wiki/Tag-Replace.md +0 -0
  189. {gam7-7.27.4 → gam7-7.28.0}/wiki/Todrive.md +0 -0
  190. {gam7-7.27.4 → gam7-7.28.0}/wiki/Unmanaged-Accounts.md +0 -0
  191. {gam7-7.27.4 → gam7-7.28.0}/wiki/Upgrade-Benefits.md +0 -0
  192. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Analytics-Admin.md +0 -0
  193. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Application-Specific-Passwords.md +0 -0
  194. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Backup-Verification-Codes.md +0 -0
  195. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Calendars-Access.md +0 -0
  196. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Calendars-Events.md +0 -0
  197. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Calendars.md +0 -0
  198. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Chat.md +0 -0
  199. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Classification-Labels.md +0 -0
  200. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Classroom-Profile.md +0 -0
  201. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Contacts-Delegates.md +0 -0
  202. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Contacts.md +0 -0
  203. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Deprovision.md +0 -0
  204. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Drive-Activity-Settings.md +0 -0
  205. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Drive-Cleanup.md +0 -0
  206. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Drive-Comments.md +0 -0
  207. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Drive-Copy-Move.md +0 -0
  208. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Drive-Files-Display.md +0 -0
  209. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Drive-Files-Manage.md +0 -0
  210. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Drive-Orphans.md +0 -0
  211. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Drive-Ownership.md +0 -0
  212. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Drive-Permissions.md +0 -0
  213. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Drive-Query.md +0 -0
  214. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Drive-Revisions.md +0 -0
  215. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Drive-Shortcuts.md +0 -0
  216. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Drive-Transfer.md +0 -0
  217. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Forms.md +0 -0
  218. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Gmail-CSE.md +0 -0
  219. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Gmail-Delegates.md +0 -0
  220. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Gmail-Filters.md +0 -0
  221. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Gmail-Forwarding.md +0 -0
  222. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Gmail-Labels.md +0 -0
  223. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Gmail-Messages-Threads.md +0 -0
  224. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Gmail-Profile.md +0 -0
  225. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Gmail-S-MIME.md +0 -0
  226. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Gmail-Send-As-Signature-Vacation.md +0 -0
  227. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Gmail-Settings.md +0 -0
  228. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Group-Membership.md +0 -0
  229. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Keep-Notes.md +0 -0
  230. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Looker-Studio.md +0 -0
  231. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Meet.md +0 -0
  232. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-People-Contacts-Profiles.md +0 -0
  233. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Photo.md +0 -0
  234. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Profile-Photo.md +0 -0
  235. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Profile-Sharing.md +0 -0
  236. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Shared-Drives.md +0 -0
  237. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Signout-Turnoff2SV.md +0 -0
  238. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Spreadsheets.md +0 -0
  239. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Tag-Manager.md +0 -0
  240. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Tasks.md +0 -0
  241. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Tokens.md +0 -0
  242. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-Web-Resources-and-Sites.md +0 -0
  243. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users-YouTube.md +0 -0
  244. {gam7-7.27.4 → gam7-7.28.0}/wiki/Users.md +0 -0
  245. {gam7-7.27.4 → gam7-7.28.0}/wiki/Using-GAM7-with-a-YubiKey.md +0 -0
  246. {gam7-7.27.4 → gam7-7.28.0}/wiki/Using-GAM7-with-a-delegated-admin-service-account.md +0 -0
  247. {gam7-7.27.4 → gam7-7.28.0}/wiki/Using-GAM7-with-keyless-authentication-Workload-Identity-Federation.md +0 -0
  248. {gam7-7.27.4 → gam7-7.28.0}/wiki/Vault-Takeout.md +0 -0
  249. {gam7-7.27.4 → gam7-7.28.0}/wiki/Verifying-a-GAM7-Build-is-Legitimate-and-Official.md +0 -0
  250. {gam7-7.27.4 → gam7-7.28.0}/wiki/_Sidebar.md +0 -0
  251. {gam7-7.27.4 → gam7-7.28.0}/wiki/gam.cfg.md +0 -0
  252. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-AdminSettingsExamples.md +0 -0
  253. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Android-Installation.md +0 -0
  254. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-BulkOperations.md +0 -0
  255. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-CalendarExamples.md +0 -0
  256. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Chat-Bot.md +0 -0
  257. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Chrome-Browser-Management.md +0 -0
  258. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Chrome-OS-Installation.md +0 -0
  259. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Chrome-Policy-Settings.md +0 -0
  260. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Cloud-Identity-Groups.md +0 -0
  261. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Command-Reference-Calendar-Resources.md +0 -0
  262. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Command-Reference-Calendars.md +0 -0
  263. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Command-Reference-Definitions.md +0 -0
  264. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Command-Reference-Drive.md +0 -0
  265. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Command-Reference-Email.md +0 -0
  266. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Command-Reference-Group-Attributes.md +0 -0
  267. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Command-Reference-Groups.md +0 -0
  268. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Command-Reference-Users.md +0 -0
  269. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Context-Aware-Access-Levels.md +0 -0
  270. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Creating-client_secrets.json-and-oauth2service.json.md +0 -0
  271. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-CreatingClientSecretsFile.md +0 -0
  272. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Custom-Schemas.md +0 -0
  273. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Data-Transfers.md +0 -0
  274. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-DomainVerification.md +0 -0
  275. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-ExamplesAccountAuditing.md +0 -0
  276. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-ExamplesCSV.md +0 -0
  277. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-ExamplesEmailSettings.md +0 -0
  278. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-ExamplesOrganizations.md +0 -0
  279. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-GAM-Discussion-Group.md +0 -0
  280. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-GAM-on-Android-and-Chrome-OS.md +0 -0
  281. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-GAM-options-files.md +0 -0
  282. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-GAM-with--minimal-GCP-rights.md +0 -0
  283. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-GAM3CSVListings.md +0 -0
  284. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-GAM3DirectoryCommands.md +0 -0
  285. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-GAM3GroupSettings.md +0 -0
  286. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Google-Vault---Takeout-Commands.md +0 -0
  287. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-GoogleDriveManagement.md +0 -0
  288. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Grouping-18-or-Older-Users.md +0 -0
  289. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Home.md +0 -0
  290. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-How-to-upgrade-from-Standard-GAM.md +0 -0
  291. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Inbound-SSO-Settings.md +0 -0
  292. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-LicenseExamples.md +0 -0
  293. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Managing-Admins.md +0 -0
  294. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Managing-CloudPrint-Printers.md +0 -0
  295. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Managing-Devices.md +0 -0
  296. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Managing-Google-Classroom.md +0 -0
  297. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-OAuthKeyManagement.md +0 -0
  298. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Printers.md +0 -0
  299. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-ResellerCommands.md +0 -0
  300. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-SecurityExamples.md +0 -0
  301. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-UnmanagedUsersExamples.md +0 -0
  302. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-Using-GAM-with-a-delegated-admin-service-account-(DASA).md +0 -0
  303. {gam7-7.27.4 → gam7-7.28.0}/wiki/legacy/l-_Footer.md +0 -0
@@ -158,7 +158,7 @@ jobs:
158
158
  with:
159
159
  path: |
160
160
  cache.tar.xz
161
- key: gam-${{ matrix.jid }}-20251007
161
+ key: gam-${{ matrix.jid }}-20251031
162
162
 
163
163
  - name: Untar Cache archive
164
164
  if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true'
@@ -479,24 +479,16 @@ jobs:
479
479
  "${PYTHON}" -V
480
480
  "${PYTHON}" -c "import ssl; print(f'Using {ssl.OPENSSL_VERSION}')"
481
481
 
482
- - name: Upgrade pip, wheel, etc
483
- run: |
484
- curl $curl_retry -O https://bootstrap.pypa.io/get-pip.py
485
- "$PYTHON" get-pip.py
486
- "$PYTHON" -m pip install --upgrade pip
487
- "$PYTHON" -m pip install --upgrade wheel
488
- "$PYTHON" -m pip install --upgrade setuptools
489
- "$PYTHON" -m pip install --upgrade importlib-metadata
490
- "$PYTHON" -m pip install --upgrade setuptools-scm
491
- "$PYTHON" -m pip list
492
-
493
482
  - name: Create and use Python venv
494
483
  run: |
495
484
  cd "$GITHUB_WORKSPACE"
485
+ curl -o get-pip.py https://bootstrap.pypa.io/get-pip.py
486
+ "$PYTHON" get-pip.py
496
487
  "$PYTHON" -m venv venv
497
488
  if [[ "$RUNNER_OS" == "Windows" ]]; then
498
- # hack till pyscard has a wheel for win arm64
499
- "$PYTHON" -m pip install --upgrade --force-reinstall pyscard
489
+ # pyscard seems to build outside venv but not in it.
490
+ # build it so it's cached.
491
+ "$PYTHON" -m pip install --upgrade pyscard
500
492
  export PYTHON="${GITHUB_WORKSPACE}/venv/scripts/python.exe"
501
493
  else
502
494
  export PYTHON="${GITHUB_WORKSPACE}/venv/bin/python3"
@@ -507,6 +499,18 @@ jobs:
507
499
  echo "gam=${gam}" >> $GITHUB_ENV
508
500
  fi
509
501
 
502
+ - name: Upgrade pip, wheel, etc
503
+ run: |
504
+ curl $curl_retry -O https://bootstrap.pypa.io/get-pip.py
505
+ "$PYTHON" get-pip.py
506
+ "$PYTHON" -m pip install --upgrade pip
507
+ "$PYTHON" -m pip install --upgrade wheel
508
+ "$PYTHON" -m pip install --upgrade setuptools
509
+ "$PYTHON" -m pip install --upgrade importlib-metadata
510
+ "$PYTHON" -m pip install --upgrade setuptools-scm
511
+ "$PYTHON" -m pip install --upgrade packaging
512
+ "$PYTHON" -m pip list
513
+
510
514
  - name: Install pip requirements
511
515
  run: |
512
516
  echo "before anything..."
@@ -515,7 +519,10 @@ jobs:
515
519
  "$PYTHON" -m pip cache info
516
520
  echo "--list--"
517
521
  "$PYTHON" -m pip cache list
518
- "$PYTHON" -m pip install --upgrade ..[yubikey]
522
+ echo "--pip debug verbose--"
523
+ "$PYTHON" -m pip debug --verbose
524
+ echo "--------"
525
+ "$PYTHON" -m pip install -vvv --upgrade ..[yubikey]
519
526
  echo "after everything..."
520
527
  "$PYTHON" -m pip list
521
528
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gam7
3
- Version: 7.27.4
3
+ Version: 7.28.0
4
4
  Summary: CLI tool to manage Google Workspace
5
5
  Project-URL: Homepage, https://github.com/GAM-team/GAM
6
6
  Project-URL: Issues, https://github.com/GAM-team/GAM/issues
@@ -3279,6 +3279,7 @@ gam print courses [todrive <ToDriveAttribute>*]
3279
3279
  [show all|students|teachers] [countsonly]
3280
3280
  [timefilter creationtime|updatetime] [start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>]
3281
3281
  [fields <CourseFieldNameList>] [skipfields <CourseFieldNameList>]
3282
+ (addcsvdata <FieldName> <String>)*
3282
3283
  [formatjson [quotechar <Character>]]
3283
3284
  [showitemcountonly]
3284
3285
 
@@ -4650,6 +4651,7 @@ gam report customers|customer|domain [todrive <ToDriveAttribute>*]
4650
4651
  [(nodatechange | limitdatechanges <Integer>) | (fulldatarequired all|<CustomerServiceNameList>)]
4651
4652
  [(fields|parameters <String>)|(services <CustomerServiceNameList>)] [noauthorizedapps]
4652
4653
  [convertmbtogb]
4654
+ (addcsvdata <FieldName> <String>)*
4653
4655
 
4654
4656
  <UserServiceName> ::=
4655
4657
  accounts|
@@ -4672,6 +4674,7 @@ gam report users|user [todrive <ToDriveAttribute>*]
4672
4674
  [aggregatebydate|aggregatebyuser [Boolean]]
4673
4675
  [maxresults <Number>]
4674
4676
  [convertmbtogb]
4677
+ (addcsvdata <FieldName> <String>)*
4675
4678
 
4676
4679
  # Reseller
4677
4680
 
@@ -1,3 +1,22 @@
1
+ 7.28.00
2
+
3
+ Added option `addcsvdata <FieldName> <String>` to `gam report [usage] customers|users`
4
+ that adds additional columns of data to the CSV file output. This will be most useful
5
+ when reading a CSV of user information and you want to include some of the user information,
6
+ e.g., orgUnitPath, in the output.
7
+ ```
8
+ gam redirect csv ./Users.csv print users fields ou
9
+ gam redirect csv ./UserStorageInfo.csv multiprocess csv Users.csv gam report users user "~primaryEmail" parameters accounts:drive_used_quota_in_mb,accounts:gmail_used_quota_in_mb,accounts:gplus_photos_used_quota_in_mb,accounts:total_quota_in_mb,accounts:used_quota_in_mb,accounts:used_quota_in_percentage addcsvdata orgUnitPath "~orgUnitPath"
10
+ ```
11
+
12
+ 7.27.05
13
+
14
+ Added option `addcsvdata <FieldName> <String>` to `gam print courses`
15
+ that adds additional columns of data to the CSV file output.
16
+
17
+ The following scope is no longer necessary: `Cloud Identity API - Groups Beta (Enables group locking/unlocking)`
18
+ as this scope `Cloud Identity API - Groups` now provides group locking/unlocking.
19
+
1
20
  7.27.04
2
21
 
3
22
  Added options to `gam <UserTypeEntity> create delegate` that support
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
25
25
  """
26
26
 
27
27
  __author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
28
- __version__ = '7.27.04'
28
+ __version__ = '7.28.00'
29
29
  __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
30
30
 
31
31
  #pylint: disable=wrong-import-position
@@ -13411,12 +13411,14 @@ REPORTS_PARAMETERS_SIMPLE_TYPES = ['intValue', 'boolValue', 'datetimeValue', 'st
13411
13411
  # [skipdates <Date>[:<Date>](,<Date>[:<Date>])*] [skipdaysofweek <DayOfWeek>(,<DayOfWeek>)*]
13412
13412
  # [fields|parameters <String>)]
13413
13413
  # [convertmbtogb]
13414
+ # (addcsvdata <FieldName> <String>)*
13414
13415
  # gam report usage customer [todrive <ToDriveAttribute>*]
13415
13416
  # [([start|startdate <Date>] [end|enddate <Date>])|(range <Date> <Date>)|
13416
13417
  # thismonth|(previousmonths <Integer>)]
13417
13418
  # [skipdates <Date>[:<Date>](,<Date>[:<Date>])*] [skipdaysofweek <DayOfWeek>(,<DayOfWeek>)*]
13418
13419
  # [fields|parameters <String>)]
13419
13420
  # [convertmbtogb]
13421
+ # (addcsvdata <FieldName> <String>)*
13420
13422
  def doReportUsage():
13421
13423
  def usageEntitySelectors():
13422
13424
  selectorChoices = Cmd.USER_ENTITY_SELECTORS+Cmd.USER_CSVDATA_ENTITY_SELECTORS
@@ -13468,6 +13470,7 @@ def doReportUsage():
13468
13470
  startEndTime = StartEndTime('startdate', 'enddate', 'date')
13469
13471
  skipDayNumbers = []
13470
13472
  skipDates = set()
13473
+ addCSVData = {}
13471
13474
  while Cmd.ArgumentsRemaining():
13472
13475
  myarg = getArgument()
13473
13476
  if csvPF and myarg == 'todrive':
@@ -13522,6 +13525,9 @@ def doReportUsage():
13522
13525
  select = True
13523
13526
  elif myarg == 'convertmbtogb':
13524
13527
  convertMbToGb = True
13528
+ elif myarg == 'addcsvdata':
13529
+ k = getString(Cmd.OB_STRING)
13530
+ addCSVData[k] = getString(Cmd.OB_STRING, minLen=0)
13525
13531
  else:
13526
13532
  unknownArgumentExit()
13527
13533
  if startEndTime.endDateTime is None:
@@ -13555,6 +13561,8 @@ def doReportUsage():
13555
13561
  titles.append('orgUnitPath')
13556
13562
  else:
13557
13563
  pageMessage = None
13564
+ if addCSVData:
13565
+ titles.extend(sorted(addCSVData.keys()))
13558
13566
  csvPF.SetTitles(titles)
13559
13567
  csvPF.SetSortAllTitles()
13560
13568
  parameters = ','.join(parameters) if parameters else None
@@ -13589,6 +13597,8 @@ def doReportUsage():
13589
13597
  row['orgUnitPath'] = userOrgUnits.get(row['user'], UNKNOWN)
13590
13598
  else:
13591
13599
  row['user'] = UNKNOWN
13600
+ if addCSVData:
13601
+ row.update(addCSVData)
13592
13602
  for item in entity.get('parameters', []):
13593
13603
  if 'name' not in item:
13594
13604
  continue
@@ -13720,12 +13730,14 @@ REPORT_ACTIVITIES_TIME_OBJECTS = {'time'}
13720
13730
  # [aggregatebydate|aggregatebyuser [Boolean]]
13721
13731
  # [maxresults <Number>]
13722
13732
  # [convertmbtogb]
13733
+ # (addcsvdata <FieldName> <String>)*
13723
13734
  # gam report customers|customer|domain [todrive <ToDriveAttribute>*]
13724
13735
  # [(date <Date>)|(range <Date> <Date>)|
13725
13736
  # yesterday|today|thismonth|(previousmonths <Integer>)]
13726
13737
  # [nodatechange | (fulldatarequired all|<CustomerServiceNameList>)]
13727
13738
  # [(fields|parameters <String>)|(services <CustomerServiceNameList>)] [noauthorizedapps]
13728
13739
  # [convertmbtogb]
13740
+ # (addcsvdata <FieldName> <String>)*
13729
13741
  def doReport():
13730
13742
  def processUserUsage(usage, lastDate):
13731
13743
  if not usage:
@@ -13743,6 +13755,8 @@ def doReport():
13743
13755
  row['orgUnitPath'] = userOrgUnits.get(row['email'], UNKNOWN)
13744
13756
  else:
13745
13757
  row['email'] = UNKNOWN
13758
+ if addCSVData:
13759
+ row.update(addCSVData)
13746
13760
  for item in user_report.get('parameters', []):
13747
13761
  if 'name' not in item:
13748
13762
  continue
@@ -13834,6 +13848,8 @@ def doReport():
13834
13848
  return (False, lastDate)
13835
13849
  lastDate = usage[0]['date']
13836
13850
  row = {'date': lastDate}
13851
+ if addCSVData:
13852
+ row.update(addCSVData)
13837
13853
  for item in usage[0].get('parameters', []):
13838
13854
  if 'name' not in item:
13839
13855
  continue
@@ -13908,12 +13924,16 @@ def doReport():
13908
13924
  continue
13909
13925
  for ptype in REPORTS_PARAMETERS_SIMPLE_TYPES:
13910
13926
  if ptype in item:
13927
+ row = {'date': lastDate}
13928
+ if addCSVData:
13929
+ row.update(addCSVData)
13911
13930
  if ptype != 'datetimeValue':
13912
13931
  if convertMbToGb and name.endswith('_in_mb'):
13913
13932
  name = convertReportMBtoGB(name, item)
13914
- csvPF.WriteRow({'date': lastDate, 'name': name, 'value': item[ptype]})
13933
+ row.update({'name': name, 'value': item[ptype]})
13915
13934
  else:
13916
- csvPF.WriteRow({'date': lastDate, 'name': name, 'value': formatLocalTime(item[ptype])})
13935
+ row.update({'name': name, 'value': formatLocalTime(item[ptype])})
13936
+ csvPF.WriteRow(row)
13917
13937
  break
13918
13938
  else:
13919
13939
  if 'msgValue' in item:
@@ -13922,6 +13942,8 @@ def doReport():
13922
13942
  continue
13923
13943
  for subitem in item['msgValue']:
13924
13944
  app = {'date': lastDate}
13945
+ if addCSVData:
13946
+ app.update(addCSVData)
13925
13947
  for an_item in subitem:
13926
13948
  if an_item == 'client_name':
13927
13949
  app['name'] = f'App: {escapeCRsNLs(subitem[an_item])}'
@@ -13934,7 +13956,11 @@ def doReport():
13934
13956
  values = []
13935
13957
  for subitem in item['msgValue']:
13936
13958
  values.append(f'{subitem["version_number"]}:{subitem["num_devices"]}')
13937
- csvPF.WriteRow({'date': lastDate, 'name': name, 'value': ' '.join(sorted(values, reverse=True))})
13959
+ row = {'date': lastDate}
13960
+ if addCSVData:
13961
+ row.update(addCSVData)
13962
+ row.update({'name': name, 'value': ' '.join(sorted(values, reverse=True))})
13963
+ csvPF.WriteRow(row)
13938
13964
  else:
13939
13965
  values = []
13940
13966
  for subitem in item['msgValue']:
@@ -13949,7 +13975,11 @@ def doReport():
13949
13975
  values.append(f'{myvalue}:{mycount}')
13950
13976
  else:
13951
13977
  continue
13952
- csvPF.WriteRow({'date': lastDate, 'name': name, 'value': ' '.join(sorted(values, reverse=True))})
13978
+ row = {'date': lastDate}
13979
+ if addCSVData:
13980
+ row.update(addCSVData)
13981
+ row.update({'name': name, 'value': ' '.join(sorted(values, reverse=True))})
13982
+ csvPF.WriteRow(row)
13953
13983
  csvPF.SortRowsTwoTitles('date', 'name', False)
13954
13984
  if authorizedApps:
13955
13985
  csvPF.AddTitle('client_id')
@@ -14099,7 +14129,7 @@ def doReport():
14099
14129
  eventRowFilter = True
14100
14130
  elif activityReports and myarg == 'groupidfilter':
14101
14131
  groupIdFilter = getString(Cmd.OB_STRING)
14102
- elif activityReports and myarg == 'addcsvdata':
14132
+ elif myarg == 'addcsvdata':
14103
14133
  k = getString(Cmd.OB_STRING)
14104
14134
  addCSVData[k] = getString(Cmd.OB_STRING, minLen=0)
14105
14135
  elif activityReports and myarg == 'shownoactivities':
@@ -14164,6 +14194,8 @@ def doReport():
14164
14194
  titles = ['email'] if not showOrgUnit else ['email', 'orgUnitPath']
14165
14195
  else:
14166
14196
  titles = ['email', 'date'] if not showOrgUnit else ['email', 'orgUnitPath', 'date']
14197
+ if addCSVData:
14198
+ titles.extend(sorted(addCSVData.keys()))
14167
14199
  csvPF.SetTitles(titles)
14168
14200
  csvPF.SetSortAllTitles()
14169
14201
  i = 0
@@ -14250,6 +14282,8 @@ def doReport():
14250
14282
  if aggregateByDate:
14251
14283
  for usageDate, events in eventCounts.items():
14252
14284
  row = {'date': usageDate}
14285
+ if addCSVData:
14286
+ row.update(addCSVData)
14253
14287
  for event, count in events.items():
14254
14288
  if convertMbToGb and event.endswith('_in_gb'):
14255
14289
  count = f'{count/1024:.2f}'
@@ -14262,6 +14296,8 @@ def doReport():
14262
14296
  row = {'email': email}
14263
14297
  if showOrgUnit:
14264
14298
  row['orgUnitPath'] = userOrgUnits.get(email, UNKNOWN)
14299
+ if addCSVData:
14300
+ row.update(addCSVData)
14265
14301
  for event, count in events.items():
14266
14302
  if convertMbToGb and event.endswith('_in_gb'):
14267
14303
  count = f'{count/1024:.2f}'
@@ -14276,6 +14312,8 @@ def doReport():
14276
14312
  if startEndTime.startDateTime is None:
14277
14313
  startEndTime.startDateTime = startEndTime.endDateTime = todaysDate()
14278
14314
  csvPF.SetTitles('date')
14315
+ if addCSVData:
14316
+ csvPF.AddTitles(sorted(addCSVData.keys()))
14279
14317
  if not userCustomerRange or (startEndTime.startDateTime == startEndTime.endDateTime):
14280
14318
  csvPF.AddTitles(['name', 'value'])
14281
14319
  authorizedApps = []
@@ -24227,6 +24265,7 @@ CROS_LIST_FIELDS_CHOICE_MAP = {
24227
24265
 
24228
24266
  CROS_TIME_OBJECTS = {
24229
24267
  'createTime',
24268
+ 'extendedSupportStart',
24230
24269
  'firstEnrollmentTime',
24231
24270
  'lastDeprovisionTimestamp',
24232
24271
  'lastEnrollmentTime',
@@ -35921,7 +35960,7 @@ def doPrintShowGroupTree():
35921
35960
  # gam create cigroup <EmailAddress>
35922
35961
  # [copyfrom <GroupItem>] <GroupAttribute>
35923
35962
  # [makeowner] [alias|aliases <CIGroupAliasList>]
35924
- # [security|makesecuritygroup]
35963
+ # [security|makesecuritygroup] [locked]
35925
35964
  # [dynamic <QueryDynamicGroup>]
35926
35965
  def doCreateCIGroup():
35927
35966
  doCreateGroup(ciGroupsAPI=True)
@@ -36105,7 +36144,6 @@ def doUpdateCIGroups():
36105
36144
 
36106
36145
  cd = buildGAPIObject(API.DIRECTORY)
36107
36146
  ci = buildGAPIObject(API.CLOUDIDENTITY_GROUPS)
36108
- cib = None
36109
36147
  entityType = Ent.CLOUD_IDENTITY_GROUP
36110
36148
  csvPF = None
36111
36149
  getBeforeUpdate = preview = False
@@ -36214,7 +36252,6 @@ def doUpdateCIGroups():
36214
36252
  _, name, _ = convertGroupEmailToCloudID(ci, group, i, count)
36215
36253
  if not name:
36216
36254
  continue
36217
- cipl = ci
36218
36255
  twoUpdates = False
36219
36256
  if 'labels' in ci_body or lockGroup is not None:
36220
36257
  try:
@@ -36243,20 +36280,16 @@ def doUpdateCIGroups():
36243
36280
  else:
36244
36281
  if CIGROUP_LOCKED_LABEL in ci_body['labels']:
36245
36282
  ci_body['labels'].pop(CIGROUP_LOCKED_LABEL)
36246
- if CIGROUP_LOCKED_LABEL in ci_body['labels']:
36247
- if cib is None:
36248
- cib = buildGAPIObject(API.CLOUDIDENTITY_GROUPS_BETA)
36249
- cipl = cib
36250
36283
  if ci_body:
36251
36284
  try:
36252
36285
  if twoUpdates:
36253
36286
  ci_body['labels'].pop(CIGROUP_LOCKED_LABEL)
36254
- callGAPI(cipl.groups(), 'patch',
36287
+ callGAPI(ci.groups(), 'patch',
36255
36288
  throwReasons=GAPI.CIGROUP_UPDATE_THROW_REASONS,
36256
36289
  retryReasons=GAPI.CIGROUP_RETRY_REASONS,
36257
36290
  name=name, body=ci_body, updateMask=','.join(list(ci_body.keys())))
36258
36291
  ci_body['labels'][CIGROUP_LOCKED_LABEL] = ''
36259
- callGAPI(cipl.groups(), 'patch',
36292
+ callGAPI(ci.groups(), 'patch',
36260
36293
  throwReasons=GAPI.CIGROUP_UPDATE_THROW_REASONS,
36261
36294
  retryReasons=GAPI.CIGROUP_RETRY_REASONS,
36262
36295
  name=name, body=ci_body, updateMask=','.join(list(ci_body.keys())))
@@ -37240,20 +37273,17 @@ def doPrintCIGroups():
37240
37273
  else:
37241
37274
  getFullFieldsList = list(CIGROUP_FULL_FIELDS)
37242
37275
  getFullFields = ','.join(getFullFieldsList)#
37243
- cipl = ci
37244
37276
  if query:
37245
37277
  method = 'search'
37246
37278
  if 'parent' not in query:
37247
37279
  query += f" && parent == '{parent}'"
37248
37280
  kwargs = {'query': query}
37249
- if CIGROUP_LOCKED_LABEL in query:
37250
- cipl = buildGAPIObject(API.CLOUDIDENTITY_GROUPS_BETA)
37251
37281
  else:
37252
37282
  method = 'list'
37253
37283
  kwargs = {'parent': parent}
37254
37284
  printGettingAllAccountEntities(Ent.CLOUD_IDENTITY_GROUP, query)
37255
37285
  try:
37256
- entityList = callGAPIpages(cipl.groups(), method, 'groups',
37286
+ entityList = callGAPIpages(ci.groups(), method, 'groups',
37257
37287
  pageMessage=getPageMessage(showFirstLastItems=True), messageAttribute=['groupKey', 'id'],
37258
37288
  throwReasons=GAPI.CIGROUP_LIST_THROW_REASONS, retryReasons=GAPI.CIGROUP_RETRY_REASONS,
37259
37289
  view='FULL', fields=fieldsnp, pageSize=pageSize, **kwargs)
@@ -49166,6 +49196,7 @@ def _getCoursesInfo(croom, courseSelectionParameters, courseShowProperties, getO
49166
49196
  # [show none|all|students|teachers] [countsonly]
49167
49197
  # [fields <CourseFieldNameList>] [skipfields <CourseFieldNameList>]
49168
49198
  # [timefilter creationtime|updatetime] [start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>]
49199
+ # (addcsvdata <FieldName> <String>)*
49169
49200
  # [showitemcountonly] [formatjson [quotechar <Character>]]
49170
49201
  def doPrintCourses():
49171
49202
  def _saveParticipants(course, participants, role, rtitles):
@@ -49209,6 +49240,7 @@ def doPrintCourses():
49209
49240
  delimiter = GC.Values[GC.CSV_OUTPUT_FIELD_DELIMITER]
49210
49241
  showItemCountOnly = False
49211
49242
  useOwnerAccess = GC.Values[GC.USE_COURSE_OWNER_ACCESS]
49243
+ addCSVData = {}
49212
49244
  while Cmd.ArgumentsRemaining():
49213
49245
  myarg = getArgument()
49214
49246
  if myarg == 'todrive':
@@ -49223,6 +49255,9 @@ def doPrintCourses():
49223
49255
  pass
49224
49256
  elif myarg == 'showitemcountonly':
49225
49257
  showItemCountOnly = True
49258
+ elif myarg == 'addcsvdata':
49259
+ k = getString(Cmd.OB_STRING)
49260
+ addCSVData[k] = getString(Cmd.OB_STRING, minLen=0)
49226
49261
  else:
49227
49262
  FJQC.GetFormatJSONQuoteChar(myarg, True)
49228
49263
  applyCourseItemFilter = _setApplyCourseItemFilter(courseItemFilter, None)
@@ -49234,6 +49269,11 @@ def doPrintCourses():
49234
49269
  if showItemCountOnly:
49235
49270
  writeStdout('0\n')
49236
49271
  return
49272
+ if addCSVData:
49273
+ csvPF.AddTitles(sorted(addCSVData.keys()))
49274
+ if FJQC.formatJSON:
49275
+ csvPF.AddJSONTitles(sorted(addCSVData.keys()))
49276
+ csvPF.MoveJSONTitlesToEnd(['JSON'])
49237
49277
  if courseShowProperties['aliases']:
49238
49278
  if FJQC.formatJSON:
49239
49279
  csvPF.AddJSONTitles('JSON-aliases')
@@ -49291,11 +49331,15 @@ def doPrintCourses():
49291
49331
  if courseShowProperties['members'] != 'teachers':
49292
49332
  _saveParticipants(course, students, 'students', stitles)
49293
49333
  row = flattenJSON(course, timeObjects=COURSE_TIME_OBJECTS, noLenObjects=COURSE_NOLEN_OBJECTS)
49334
+ if addCSVData:
49335
+ row.update(addCSVData)
49294
49336
  if not FJQC.formatJSON:
49295
49337
  csvPF.WriteRowTitles(row)
49296
49338
  elif csvPF.CheckRowTitles(row):
49297
49339
  row = {'id': courseId, 'JSON': json.dumps(cleanJSON(course, timeObjects=COURSE_TIME_OBJECTS),
49298
49340
  ensure_ascii=False, sort_keys=True)}
49341
+ if addCSVData:
49342
+ row.update(addCSVData)
49299
49343
  if courseShowProperties['aliases']:
49300
49344
  row['JSON-aliases'] = json.dumps(list(aliases))
49301
49345
  if courseShowProperties['members'] != 'none':
@@ -46,7 +46,6 @@ CLASSROOM = 'classroom'
46
46
  CLOUDCHANNEL = 'cloudchannel'
47
47
  CLOUDIDENTITY_DEVICES = 'cloudidentitydevices'
48
48
  CLOUDIDENTITY_GROUPS = 'cloudidentitygroups'
49
- CLOUDIDENTITY_GROUPS_BETA = 'cloudidentitygroupsbeta'
50
49
  CLOUDIDENTITY_INBOUND_SSO = 'cloudidentityinboundsso'
51
50
  CLOUDIDENTITY_ORGUNITS = 'cloudidentityorgunits'
52
51
  CLOUDIDENTITY_ORGUNITS_BETA = 'cloudidentityorgunitsbeta'
@@ -242,7 +241,6 @@ _INFO = {
242
241
  CLOUDCHANNEL: {'name': 'Cloud Channel API', 'version': 'v1', 'v2discovery': True},
243
242
  CLOUDIDENTITY_DEVICES: {'name': 'Cloud Identity API - Devices', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
244
243
  CLOUDIDENTITY_GROUPS: {'name': 'Cloud Identity API - Groups', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
245
- CLOUDIDENTITY_GROUPS_BETA: {'name': 'Cloud Identity API - Groups Beta', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
246
244
  CLOUDIDENTITY_INBOUND_SSO: {'name': 'Cloud Identity API - Inbound SSO Settings', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
247
245
  CLOUDIDENTITY_ORGUNITS: {'name': 'Cloud Identity API - OrgUnits', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
248
246
  CLOUDIDENTITY_ORGUNITS_BETA: {'name': 'Cloud Identity API - OrgUnits Beta', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
@@ -387,10 +385,6 @@ _CLIENT_SCOPES = [
387
385
  'api': CLOUDIDENTITY_GROUPS,
388
386
  'subscopes': READONLY,
389
387
  'scope': 'https://www.googleapis.com/auth/cloud-identity.groups'},
390
- {'name': 'Cloud Identity API - Groups Beta (Enables group locking/unlocking)',
391
- 'api': CLOUDIDENTITY_GROUPS_BETA,
392
- 'subscopes': [],
393
- 'scope': 'https://www.googleapis.com/auth/cloud-identity.groups'},
394
388
  {'name': 'Cloud Identity API - Inbound SSO Settings',
395
389
  'api': CLOUDIDENTITY_INBOUND_SSO,
396
390
  'subscopes': READONLY,
@@ -441,8 +441,10 @@ gam print courses [todrive <ToDriveAttribute>*]
441
441
  [owneremail] [owneremailmatchpattern <REMatchPattern>]
442
442
  [alias|aliases|aliasesincolumns [delimiter <Character>]]
443
443
  [show all|students|teachers] [countsonly]
444
- [fields <CourseFieldNameList>] [skipfields <CourseFieldNameList>] [formatjson [quotechar <Character>]]
445
444
  [timefilter creationtime|updatetime] [start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>]
445
+ [fields <CourseFieldNameList>] [skipfields <CourseFieldNameList>] [formatjson [quotechar <Character>]]
446
+ (addcsvdata <FieldName> <String>)*
447
+ [formatjson [quotechar <Character>]]
446
448
  ```
447
449
  By default, the `print courses` command displays information about all courses.
448
450
 
@@ -477,6 +479,7 @@ By default, all basic course fields are displayed; use the following options to
477
479
  * `countsonly` - Eliminates the student/teacher profile information and outputs only the student/teacher counts.
478
480
  * `fields <CourseFieldNameList>` - Select specific basic fields to display.
479
481
  * `skipfields <CourseFieldNameList>` - Select specific basic fields to eliminate from display; typically used with `coursematerialsets`.
482
+ * `addcsvdata <FieldName> <String>` - Add additional columns of data from the command line to the output
480
483
 
481
484
  By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
482
485
  * `formatjson` - Display the fields in JSON format.
@@ -11,7 +11,7 @@
11
11
 
12
12
  ## API documentation
13
13
  * [Cloud Identity Groups Overview](https://cloud.google.com/identity/docs/groups)
14
- * [Create and Manage Groups uning API](https://support.google.com/a/answer/10427204)
14
+ * [Create and Manage Groups using API](https://support.google.com/a/answer/10427204)
15
15
  * [Cloud Identity Groups API - Groups](https://cloud.google.com/identity/docs/reference/rest/v1/groups)
16
16
  * [Restrict Group Membership](https://support.google.com/a/answer/11192679)
17
17
  * [Lock Groups Beta](https://workspaceupdates.googleblog.com/2024/12/locked-groups-open-beta.html)
@@ -26,15 +26,6 @@
26
26
 
27
27
  ## Notes
28
28
 
29
- In version 7.02.01 options `locked` and `unlocked` wre added to `gam update cigroups` that allow locking groups.
30
-
31
- * See: https://workspaceupdates.googleblog.com/2024/12/locked-groups-open-beta.html
32
-
33
- You'll have to do a `gam oauth create` and enable the following scope to use these options:
34
- ```
35
- [*] 22) Cloud Identity Groups API Beta (Enables group locking/unlocking)
36
- ```
37
-
38
29
  In the Admin Directory API a group has the following characteristics:
39
30
  * `id` - The unique ID of a group
40
31
  * `email` - The group's email address
@@ -10,6 +10,14 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
10
10
 
11
11
  See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation
12
12
 
13
+ ### 7.27.05
14
+
15
+ Added option `addcsvdata <FieldName> <String>` to `gam print courses`
16
+ that adds additional columns of data to the CSV file output.
17
+
18
+ The following scope is no longer necessary: `Cloud Identity API - Groups Beta (Enables group locking/unlocking)`
19
+ as this scope `Cloud Identity API - Groups` now provides group locking/unlocking.
20
+
13
21
  ### 7.27.04
14
22
 
15
23
  Added options to `gam <UserTypeEntity> create delegate` that support
@@ -252,7 +252,7 @@ writes the credentials into the file oauth2.txt.
252
252
  admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt
253
253
  admin@server:/Users/admin$ gam version
254
254
  WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
255
- GAM 7.27.04 - https://github.com/GAM-team/GAM - pyinstaller
255
+ GAM 7.27.05 - https://github.com/GAM-team/GAM - pyinstaller
256
256
  GAM Team <google-apps-manager@googlegroups.com>
257
257
  Python 3.14.0 64-bit final
258
258
  macOS Tahoe 26.0.1 x86_64
@@ -990,7 +990,7 @@ writes the credentials into the file oauth2.txt.
990
990
  C:\>del C:\GAMConfig\oauth2.txt
991
991
  C:\>gam version
992
992
  WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
993
- GAM 7.27.04 - https://github.com/GAM-team/GAM - pythonsource
993
+ GAM 7.27.05 - https://github.com/GAM-team/GAM - pythonsource
994
994
  GAM Team <google-apps-manager@googlegroups.com>
995
995
  Python 3.14.0 64-bit final
996
996
  Windows-10-10.0.17134 AMD64
@@ -12,6 +12,10 @@
12
12
  - [User reports](#user-reports)
13
13
 
14
14
  ## API documentation
15
+ Changes starting 2025-10-29.
16
+
17
+ * [Reports API - Admin log event changes]https://support.google.com/a/answer/16601511
18
+
15
19
  These pages show event/parameter names; scroll down in the left column to: Reports.
16
20
 
17
21
  * [Reports API - Activities](https://developers.google.com/admin-sdk/reports/v1/reference/activities)
@@ -3,7 +3,7 @@
3
3
  Print the current version of Gam with details
4
4
  ```
5
5
  gam version
6
- GAM 7.27.04 - https://github.com/GAM-team/GAM - pyinstaller
6
+ GAM 7.27.05 - https://github.com/GAM-team/GAM - pyinstaller
7
7
  GAM Team <google-apps-manager@googlegroups.com>
8
8
  Python 3.14.0 64-bit final
9
9
  macOS Tahoe 26.0.1 x86_64
@@ -15,7 +15,7 @@ Time: 2023-06-02T21:10:00-07:00
15
15
  Print the current version of Gam with details and time offset information
16
16
  ```
17
17
  gam version timeoffset
18
- GAM 7.27.04 - https://github.com/GAM-team/GAM - pyinstaller
18
+ GAM 7.27.05 - https://github.com/GAM-team/GAM - pyinstaller
19
19
  GAM Team <google-apps-manager@googlegroups.com>
20
20
  Python 3.14.0 64-bit final
21
21
  macOS Tahoe 26.0.1 x86_64
@@ -27,7 +27,7 @@ Your system time differs from www.googleapis.com by less than 1 second
27
27
  Print the current version of Gam with extended details and SSL information
28
28
  ```
29
29
  gam version extended
30
- GAM 7.27.04 - https://github.com/GAM-team/GAM - pyinstaller
30
+ GAM 7.27.05 - https://github.com/GAM-team/GAM - pyinstaller
31
31
  GAM Team <google-apps-manager@googlegroups.com>
32
32
  Python 3.14.0 64-bit final
33
33
  macOS Tahoe 26.0.1 x86_64
@@ -68,7 +68,7 @@ MacOS High Sierra 10.13.6 x86_64
68
68
  Path: /Users/Admin/bin/gam7
69
69
  Version Check:
70
70
  Current: 5.35.08
71
- Latest: 7.27.04
71
+ Latest: 7.27.05
72
72
  echo $?
73
73
  1
74
74
  ```
@@ -76,7 +76,7 @@ echo $?
76
76
  Print the current version number without details
77
77
  ```
78
78
  gam version simple
79
- 7.27.04
79
+ 7.27.05
80
80
  ```
81
81
  In Linux/MacOS you can do:
82
82
  ```
@@ -86,7 +86,7 @@ echo $VER
86
86
  Print the current version of Gam and address of this Wiki
87
87
  ```
88
88
  gam help
89
- GAM 7.27.04 - https://github.com/GAM-team/GAM
89
+ GAM 7.27.05 - https://github.com/GAM-team/GAM
90
90
  GAM Team <google-apps-manager@googlegroups.com>
91
91
  Python 3.14.0 64-bit final
92
92
  macOS Tahoe 26.0.1 x86_64
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes