Example Script
WORD OF WARNING
This script is meant as an example. I take no responsibility if you somehow manage to break anything with it.
While you should probably be able to use the script as-is, I highly recommend that you take a look at what you need and write your own code. Again, this is meant as an example.
Also, please be aware that this script exports way more than you probably need, so don’t expect it to be fast.
Script
Note that this script uses the GSM PowerShell Module to demontrate its usage. The same functionality can be achieved without it and it is entirely optional!
param(
[Parameter(Mandatory = $true)][String]$ExportPath,
[Parameter(Mandatory = $true)][String]$Config,
[Parameter(Mandatory = $false, ParameterSetName = "Single")][Switch]$UserData,
[Parameter(Mandatory = $false, ParameterSetName = "Single")][Switch]$GroupData,
[Parameter(Mandatory = $false, parametersetname = "Single")][Switch]$ResourceData,
[Parameter(Mandatory = $false, parametersetname = "Single")][Switch]$DomainData,
[Parameter(Mandatory = $false, ParameterSetName = "Single")][Switch]$SharedDriveData,
[Parameter(Mandatory = $false, ParameterSetName = "Single")][Switch]$OrgUnitData,
[Parameter(Mandatory = $false, ParameterSetName = "All")][Switch]$All,
[Parameter(Mandatory = $false)][Switch]$CreateOrUpdateSheet,
[Parameter(Mandatory = $false)][String]$SheetId
)
function Get-Multivalues {
param(
$multivalues
)
$returnArray = @()
foreach ($multivalue in $multivalues) {
$m = @()
foreach ($property in $multivalue.psobject.properties) {
if ([String]::IsNullOrEmpty($property.value) -eq $false) {
$m += ($property.name + "=" + $property.value)
}
}
$returnArray += ($m -join ";")
}
return ($returnArray -join ",")
}
$exportFiles = @{
orgUnits = $ExportPath + "/orgUnits.csv"
users = $ExportPath + "/users.csv"
userAliases = $ExportPath + "/userAliases.csv"
groups = $ExportPath + "/groups.csv"
groupMembers = $ExportPath + "/groupMembers.csv"
groupAliases = $ExportPath + "/groupAliases.csv"
groupSettings = $ExportPath + "/groupSettings.csv"
delegates = $ExportPath + "/delegates.csv"
driveUsage = $ExportPath + "/driveUsage.csv"
domains = $ExportPath + "/domains.csv"
domainAliases = $ExportPath + "/domainAliases.csv"
buildings = $ExportPath + "/buildings.csv"
resourceCalendars = $ExportPath + "/resourceCalendars.csv"
features = $ExportPath + "/features.csv"
drives = $ExportPath + "/drives.csv"
gmailProfiles = $ExportPath + "/gmailProfiles.csv"
}
function Get-UserData {
List-GSMUsers -Fields "users(primaryEmail,name,gender,orgUnitPath,recoveryEmail,recoveryPhone,addresses),nextPageToken" | Foreach-Object {
$user = $_.primaryEmail
New-Object PSObject -Property ([Ordered]@{
primaryEmail = $user
familyName = $_.name.familyName
givenName = $_.name.givenName
genderType = $_.gender.type
orgUnitPath = $_.orgUnitPath
recoveryEmail = $_.recoveryEmail
recoveryPhone = $_.recoveryPhone
addresses = Get-Multivalues -multivalues $_.addresses
}) | Export-Csv -Path $exportFiles.users -Delimiter ',' -NoClobber -Append -Force
List-GSMDelegates -DwdSubject $user | Foreach-Object {
New-Object PSObject -Property ([Ordered]@{
primaryEmail = $user
delegateEmail = $_.delegateEmail
verificationStatus = $_.verificationStatus
}) | Export-Csv -Path $exportFiles.delegates -Delimiter ',' -NoClobber -Append -Force
}
$gmailProfile = GetProfile-GSMGmailUsers -DwdSubject $user
New-Object PSObject -Property ([Ordered]@{
emailAddress = $user
messagesTotal = $gmailProfile.messagesTotal
threadsTotal = $gmailProfile.threadsTotal
historyId = $gmailProfile.historyId
}) | Export-Csv -Path $exportFiles.gmailProfiles -Delimiter ',' -NoClobber -Append -Force
$about = Get-GSMAbout -DwdSubject $user -Fields "storageQuota(usage,usageInDrive)"
$fileCount = 0
List-GSMFiles -DwdSubject $user -Fields "files(id),nextPageToken" -Corpora user -Spaces drive -Q ("'" + $user + "' in owners and trashed = false") | ForEach-Object {$fileCount++}
New-Object PSObject -Property ([Ordered]@{
userId = $user
'usageInDrive (GB)' = [Math]::Round((($about.storageQuota).usageInDrive / 1GB), 2)
files = $fileCount
'usageInOthers (GB)' = [Math]::Round(((($about.storageQuota).usage - ($about.storageQuota).usageInDrive) / 1GB), 2)
}) | Export-Csv -Path $exportFiles.driveUsage -Delimiter ',' -NoClobber -Append -Force
}
List-GSMUserAliasesBatch -Path $exportFiles.users -Delimiter "," -UserKey 1 -SkipHeader | ForEach-Object {
foreach ($userAlias in $_.aliases) {
New-Object PSObject -Property ([Ordered]@{
primaryEmail = $userAlias.primaryEmail
alias = $userAlias.alias
}) | Export-Csv -Path $exportFiles.userAliases -Delimiter ',' -NoClobber -Append -Force
}
}
}
function Get-GroupData {
List-GSMGroups -Fields "groups(email,name,description),nextPageToken" | ForEach-Object {
New-Object PSObject -Property ([Ordered]@{
email = $_.email
name = $_.name
description = $_.description
}) | Export-Csv -Path $exportFiles.groups -Delimiter ',' -NoClobber -Append -Force
}
List-GSMMembersBatch -Path $exportFiles.groups -Delimiter "," -GroupKey 1 -SkipHeader | ForEach-Object {
foreach ($member in $_.members) {
New-Object PSObject -Property ([Ordered]@{
groupKey = $_.groupKey
email = $member.email
role = $member.role
}) | Export-Csv -Path $exportFiles.groupMembers -Delimiter ',' -NoClobber -Append -Force
}
}
List-GSMGroupAliasesBatch -Path $exportFiles.groups -GroupKey 1 -Delimiter "," -SkipHeader | ForEach-Object {
foreach ($groupAlias in $_.aliases) {
New-Object PSObject -Property ([Ordered]@{
groupKey = $_.groupKey
alias = $groupAlias.alias
}) | Export-Csv -Path $exportFiles.groupAliases -Delimiter ',' -NoClobber -Append -Force
}
}
Get-GSMGroupSettingsBatch -Path $exportFiles.groups -GroupUniqueId 1 -Delimiter "," -SkipHeader -Fields_ALL "allowExternalMembers,allowWebPosting,archiveOnly,email,enableCollaborativeInbox,favoriteRepliesOnTop,includeCustomFooter,includeInGlobalAddressList,isArchived,membersCanPostAsTheGroup,messageModerationLevel,name,replyTo,sendMessageDenyNotification,spamModerationLevel,whoCanApproveMembers,whoCanAssistContent,whoCanBanUsers,whoCanContactOwner,whoCanDiscoverGroup,whoCanJoin,whoCanLeaveGroup,whoCanModerateContent,whoCanModerateMembers,whoCanPostMessage,whoCanViewGroup,whoCanViewMembership" | Foreach-Object {
$_ | Export-Csv -Path $exportFiles.groupSettings -Delimiter ',' -NoClobber -Append -Force
}
}
function Get-ResourceData {
List-GSMBuildings -Fields "buildings(buildingId,buildingName,description,floorNames)" | Foreach-Object {
New-Object PSObject -Property ([Ordered]@{
buildingId = $_.buildingId
buildingName = $_.buildingName
description = $_.description
floorNames = $_.floorNames -join ","
}) | Export-Csv -Path $exportFiles.buildings -Delimiter ',' -NoClobber -Append -Force
}
List-GSMCalendarResources -Fields "items(buildingId,capacity,floorName,generatedResourceName,resourceCategory,resourceEmail,resourceId,resourceName)" | Foreach-Object {
$_ | Export-Csv -Path $exportFiles.resourceCalendars -Delimiter ',' -NoClobber -Append -Force
}
List-GSMFeatures -Fields "features(name)" | Foreach-Object {
$_ | Export-Csv -Path $exportFiles.features -Delimiter ',' -NoClobber -Append -Force
}
}
function Get-DomainData {
List-GSMDomains -Fields "domains(domainName,verified,isPrimary)" | Foreach-Object {
$_ | Export-Csv -Path $exportFiles.domains -Delimiter ',' -NoClobber -Append -Force
}
List-GSMDomainAliases -Fields "domainAliases(domainAliasName,parentDomainName,verified)" | Foreach-Object {
$_ | Export-Csv -Path $exportFiles.domainAliases -Delimiter ',' -NoClobber -Append -Force
}
}
function Get-SharedDriveData {
$admin = (Get-GSMAbout -Fields "user(emailAddress)").user.emailAddress
List-GSMDrives -UseDomainAdminAccess | Foreach-Object {
$adminPermission = Create-GSMPermissions -EmailAddress $admin -UseDomainAdminAccess -Role reader -FileId $_.id -SendNotificationEmail:$false -Type user
$driveSize = GetSize-GSMDrives -DriveId $_.id
$null = Delete-GSMPermissions -PermissionId $adminPermission.id -FileId $_.id -UseDomainAdminAccess
New-Object PSObject -Property ([Ordered]@{
driveId = $_.id
driveName = $_.name
files = $driveSize.files
folders = $driveSize.folders
'size (GB)' = [Math]::Round($driveSize.size / 1GB, 2)
}) | Export-Csv -Path $exportFiles.drives -Delimiter ',' -NoClobber -Append -Force
}
}
function Get-OrgUnitData {
List-GSMOrgUnits -Type all -Fields "organizationUnits(name,orgUnitPath,parentOrgUnitPath)" | Foreach-Object {
$_ | Export-Csv -Path $exportFiles.orgUnits -Delimiter ',' -NoClobber -Append -Force
}
}
function Export-Sheet {
param (
[Parameter(Mandatory = $false)][String]$SheetId
)
$sheets = @()
foreach ($exportFile in $exportFiles.Keys) {
if (Test-Path $exportFiles.$exportFile) {
$sheets += "title=" + $exportFile + ";path=" + $exportFiles.$exportFile
}
}
if ([String]::IsNullOrEmpty($SheetId)) {
Create-GSMSpreadsheets -Title $Config -Fields "spreadsheetUrl,spreadsheetId" -CsvFileToUpload ($sheets -join ",")
}
else {
$null = BatchUpdate-GSMSpreadsheets -SpreadsheetId $SheetId -Fields "spreadsheetId" -CsvFileToUpload ($sheets -join ",")
Get-GSMSpreadsheets -SpreadsheetId $SheetId -Fields "spreadsheetUrl,spreadsheetId"
}
}
Load-GSMConfigs -Name $Config
if ($UserData -or $All) {
Get-UserData
}
if ($GroupData -or $All) {
Get-GroupData
}
if ($ResourceData -or $All) {
Get-ResourceData
}
if ($DomainData -or $All) {
Get-DomainData
}
if ($SharedDriveData -or $All) {
Get-SharedDriveData
}
if ($OrgUnitData -or $All) {
Get-OrgUnitData
}
if ($CreateOrUpdateSheet) {
Export-Sheet -SheetId $SheetId
}
Save the script as a .ps1 file and use it like this:
./Export-Stuff.ps1 -ExportPath ./exports -Config myConfig -UserData -GroupData
This will create CSV files for user data and group data in ./exports for the domain speficied in myConfig
./Export-Stuff.ps1 -ExportPath ./exports -Config myConfig -All -CreateOrUpdateSheet
This will create CSV files for all data in ./exports for the domain speficied in myConfig and create a Google Sheet file in the drive of the subject specified in myConfig.
SEE ALSO
- gsm - Command overview
- batch commands - How to use batch commands
- scripting - Examples for data exports
- exporting data - Examples for data exports
- examples - See some examples
- PowerShell module - Auto-generated PowerShell module