Get-DropboxTeamMember.ps1
|
<#PSScriptInfo .VERSION 1.0.0 .GUID 7f64782b-37be-46e7-b66b-4a4c4c318021 .AUTHOR Giovanni Solone .TAGS powershell dropbox dropboxbusiness team members memberid dbmid .LICENSEURI https://opensource.org/licenses/MIT .PROJECTURI https://github.com/gioxx/Nebula.Scripts/blob/main/Dropbox/Get-DropboxTeamMember.ps1 #> #Requires -Version 7.0 <# .SYNOPSIS Retrieves Dropbox Business team members and their team member IDs (dbmid). .DESCRIPTION This script searches Dropbox Business team members by e-mail address or display name, or lists all members. It follows pagination automatically using the Dropbox Team API and returns one object per member (Name, Email, MemberID, Status), so the output can be piped to other commands. Requires a Dropbox team-scoped access token with the members.read permission. No external modules are required. .PARAMETER Email Exact e-mail address of a team member (case-insensitive). .PARAMETER Name Partial display name to search (case-insensitive). .PARAMETER All Returns every member of the team. .PARAMETER AccessToken Dropbox team access token as a SecureString. If omitted, the script prompts for it securely. .EXAMPLE .\Get-DropboxTeamMember.ps1 -Email 'alice@contoso.com' Returns the team member with the given e-mail address. .EXAMPLE .\Get-DropboxTeamMember.ps1 -Name 'Alice' Returns all team members whose display name contains "Alice". .EXAMPLE $token = Read-Host 'Dropbox team access token' -AsSecureString .\Get-DropboxTeamMember.ps1 -All -AccessToken $token Lists every team member, reusing a token already stored in a SecureString. .EXAMPLE .\Get-DropboxTeamMember.ps1 -Email 'alice@contoso.com' | Select-Object -ExpandProperty MemberID Returns only the team member ID (dbmid:...) of the given user. .NOTES Dropbox API reference: https://www.dropbox.com/developers/documentation/http/teams Modification History: v1.0.0 (2026-10-09): Initial release. #> [CmdletBinding(DefaultParameterSetName = 'Email')] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Email')] [ValidateNotNullOrEmpty()] [string] $Email, [Parameter(Mandatory = $true, ParameterSetName = 'Name')] [ValidateNotNullOrEmpty()] [string] $Name, [Parameter(Mandatory = $true, ParameterSetName = 'All')] [switch] $All, [Parameter()] [ValidateNotNull()] [securestring] $AccessToken ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' if (-not $PSBoundParameters.ContainsKey('AccessToken')) { $AccessToken = Read-Host 'Dropbox team access token' -AsSecureString } # Convert the secret only for the HTTP Authorization header; never log it. $plainToken = [System.Net.NetworkCredential]::new('', $AccessToken).Password if ([string]::IsNullOrWhiteSpace($plainToken)) { throw 'The Dropbox access token must not be empty.' } $headers = @{ Authorization = "Bearer $plainToken" 'Content-Type' = 'application/json' } $plainToken = $null function Invoke-DropboxTeamApi { param ( [Parameter(Mandatory = $true)] [string] $Endpoint, [Parameter(Mandatory = $true)] [object] $Payload ) $uri = "https://api.dropboxapi.com/2/$Endpoint" try { Invoke-RestMethod -Method Post -Uri $uri -Headers $headers ` -Body ($Payload | ConvertTo-Json -Depth 8 -Compress) -ErrorAction Stop } catch { $statusCode = $null if ($_.Exception -is [Microsoft.PowerShell.Commands.HttpResponseException]) { $statusCode = [int]$_.Exception.Response.StatusCode } # Dropbox returns a JSON body with an error_summary field on API errors. $apiError = $_.Exception.Message if ($_.ErrorDetails) { $apiError = $_.ErrorDetails.Message try { $errorBody = $apiError | ConvertFrom-Json -ErrorAction Stop if ($errorBody.PSObject.Properties['error_summary']) { $apiError = $errorBody.error_summary } } catch { # Not JSON (e.g. plain-text 400 response): keep the raw message. } } $hint = switch ($statusCode) { 401 { 'Check whether the access token is valid and not expired.' } 403 { 'Check that the app is team-scoped and has the members.read permission.' } 429 { 'Dropbox rate limit reached. Retry after the indicated delay.' } default { 'Check the Dropbox API response and network connectivity.' } } throw "Dropbox API request failed (HTTP $statusCode) at $Endpoint. $hint $apiError" } } try { $page = Invoke-DropboxTeamApi -Endpoint 'team/members/list' -Payload @{ limit = 100 } while ($true) { foreach ($member in $page.members) { $memberProfile = $member.profile if ($null -eq $memberProfile) { continue } $displayName = [string]$memberProfile.name.display_name $memberEmail = [string]$memberProfile.email $isMatch = switch ($PSCmdlet.ParameterSetName) { 'Email' { $memberEmail.Equals($Email, [System.StringComparison]::OrdinalIgnoreCase) } 'Name' { $displayName.Contains($Name, [System.StringComparison]::OrdinalIgnoreCase) } 'All' { $true } } if ($isMatch) { [PSCustomObject]@{ Name = $displayName Email = $memberEmail MemberID = [string]$memberProfile.team_member_id Status = [string]$memberProfile.status.'.tag' } # E-mail addresses are unique within a team: no need to read further pages. if ($PSCmdlet.ParameterSetName -eq 'Email') { return } } } if (-not $page.has_more) { break } if ([string]::IsNullOrWhiteSpace([string]$page.cursor)) { throw 'Dropbox reported additional pages but returned no cursor.' } $page = Invoke-DropboxTeamApi -Endpoint 'team/members/list/continue' ` -Payload @{ cursor = $page.cursor } } } finally { # Clear local references; the runtime controls actual memory lifetime. # Remove-Variable instead of assigning $null: [ValidateNotNull()] still applies to the parameter variable. $headers.Remove('Authorization') Remove-Variable -Name AccessToken -ErrorAction SilentlyContinue } |