|
#! /usr/bin/pwsh -nop |
|
|
|
# This is PowerShell implementation of 2LO per https://developers.google.com/identity/protocols/OAuth2ServiceAccount |
|
# Inputs: GCP service account with credentials, user to impersonate, and permissions to request |
|
# Output: the access token for subsequent requests |
|
|
|
# Using New-JWT function from the JWT module - "Install-Module JWT" if you don't have it |
|
|
|
Import-Module JWT |
|
|
|
# Forming the JWT claim set |
|
|
|
$cert = Get-PfxCertificate -FilePath "./pfx696553.p12" -Password (ConvertTo-SecureString "notasecret" -AsPlainText -Force) # The service account credentials |
|
|
|
$now = (Get-Date).ToUniversalTime() |
|
$createDate = [Math]::Floor([decimal](Get-Date($now) -UFormat "%s")) |
|
$expiryDate = [Math]::Floor([decimal](Get-Date($now.AddHours(1)) -UFormat "%s")) |
|
|
|
$rawclaims = [Ordered]@{ |
|
iss = "sa@gsuite-data-survey.iam.gserviceaccount.com" # Your service account |
|
scope = "https://www.googleapis.com/auth/admin.directory.user" # Requested permissions |
|
aud = "https://www.googleapis.com/oauth2/v4/token" |
|
sub = "admin@example.com" # The user to impersonate |
|
iat = $createDate |
|
exp = $expiryDate |
|
} | ConvertTo-Json |
|
|
|
# Encoding the JWT claim set |
|
|
|
$jwt = New-Jwt -PayloadJson $rawclaims -Cert $cert -Verbose |
|
|
|
# Making the access token request |
|
|
|
$apiendpoint = "https://www.googleapis.com/oauth2/v4/token" |
|
|
|
$splat = @{ |
|
Method = "POST" |
|
Uri = $apiendpoint |
|
ContentType = "application/x-www-form-urlencoded" |
|
Body = "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=$jwt" |
|
} |
|
|
|
$res = Invoke-RestMethod @splat -Verbose |
|
|
|
$accesstoken = $res.access_token |
|
|
|
# Calling Google APIs - list of users |
|
|
|
$usersapiendpoint = "https://www.googleapis.com/admin/directory/v1/users?list&customer=my_customer" |
|
|
|
$splat = @{ |
|
Method = "GET" |
|
Uri = $usersapiendpoint |
|
Headers = @{authorization = "Bearer $accesstoken"} |
|
} |
|
|
|
$userlistres = Invoke-RestMethod @splat -Verbose |
|
$users = $userlistres.Users |
|
|
|
# Paging through the results |
|
while ($userlistres.nextPageToken -ne $null) { |
|
$splat.Uri += "&pageToken=$($userListres.nextpagetoken)" |
|
$userlistres = Invoke-RestMethod @splat -Verbose |
|
$users += $userlistres.Users |
|
} |
|
|
|
$users | Format-Table primaryEmail,lastLoginTime |
|
|
|
# List groups |
|
|
|
$groupsapiendpoint = "https://www.googleapis.com/admin/directory/v1/groups?customer=my_customer&maxResults=50000" |
|
|
|
$splat = @{ |
|
Method="GET" |
|
Uri=$groupsapiendpoint |
|
Headers = @{authorization = "Bearer $accesstoken"} |
|
} |
|
|
|
$groupsres = Invoke-RestMethod @splat -Verbose |
|
$groupsres |
|
$groupsres | Export-CliXML "./groups.xml" |
|
|
|
# List group members |
|
|
|
$groups = $groupsres.groups |
|
$allmembers = @() |
|
|
|
foreach ($g in $groups) { |
|
|
|
$id = $g.id |
|
|
|
$memberendpoint = "https://www.googleapis.com/admin/directory/v1/groups/$id/members?maxResults=50000" |
|
|
|
$splat = @{ |
|
Method="GET" |
|
Uri=$memberendpoint |
|
Headers = @{authorization = "Bearer $accesstoken"} |
|
} |
|
|
|
$gres = Invoke-RestMethod @splat -Verbose |
|
$allmembers += $gres |
|
} |
|
|
|
$allmembers | Export-CliXML "./group-members.xml" |
|
$allmembers |
|
|
You are seriously a rock star! I looked all over for examples of how to do this and there is so little out there for how to do this in Powershell. Thank you! Stumbling upon this was so helpful!