Public/Get-InforcerUser.ps1
|
function Get-InforcerUser { <# .SYNOPSIS Retrieves users from an Inforcer tenant. .DESCRIPTION Gets a list of users or a single user by ID from the Inforcer API. When called without -UserId, returns all users (UserSummary objects) with optional search filtering and auto-pagination. When called with -UserId, returns the full user detail (User object) including groups, roles, devices, and risk information. .PARAMETER Format Output format. Currently only 'Raw' is supported. .PARAMETER TenantId The Inforcer tenant ID. Accepts numeric ID, GUID, or tenant name. Supports pipeline input. .PARAMETER Search Server-side search filter for the user list. Only available in the List parameter set. .PARAMETER MaxResults Maximum number of users to return. 0 (default) means no limit. Only available in the List parameter set. .PARAMETER UserId The user ID (GUID) to retrieve full details for. Only available in the ById parameter set. .PARAMETER OutputType Output type: 'PowerShellObject' (default) or 'JsonObject'. .EXAMPLE Get-InforcerUser -TenantId 139 Lists all users in tenant 139. .EXAMPLE Get-InforcerUser -TenantId 139 -Search "Adele" Searches for users matching "Adele" in tenant 139. .EXAMPLE Get-InforcerUser -TenantId 139 -UserId "8e61ce11-a45b-42a6-8ca4-1d881781566d" Gets full detail for a specific user. .EXAMPLE Get-InforcerTenant -TenantId 139 | Get-InforcerUser Lists all users in the piped tenant. .LINK https://github.com/royklo/InforcerCommunity/blob/main/docs/CMDLET-REFERENCE.md#get-inforceruser .LINK Connect-Inforcer #> [CmdletBinding(DefaultParameterSetName = 'List')] param( [Parameter(ParameterSetName = 'List')] [Parameter(ParameterSetName = 'ById')] [ValidateSet('Raw')] [string]$Format = 'Raw', [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'List')] [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'ById')] [Alias('ClientTenantId')] [object]$TenantId, [Parameter(ParameterSetName = 'List')] [string]$Search, [Parameter(ParameterSetName = 'List')] [int]$MaxResults = 0, [Parameter(Mandatory, ParameterSetName = 'ById')] [string]$UserId, [Parameter(ParameterSetName = 'List')] [Parameter(ParameterSetName = 'ById')] [ValidateSet('PowerShellObject', 'JsonObject')] [string]$OutputType = 'PowerShellObject' ) process { if (-not (Test-InforcerSession)) { Write-Error -Message "Not connected to Inforcer. Use Connect-Inforcer first." -ErrorId 'NotConnected' -Category ConnectionError return } try { $resolvedTenantId = Resolve-InforcerTenantId -TenantId $TenantId } catch { Write-Error -Message $_.Exception.Message -ErrorId 'InvalidTenantId' -Category InvalidArgument return } if ($PSCmdlet.ParameterSetName -eq 'ById') { # --- ById: single user detail --- $endpoint = "/beta/tenants/$resolvedTenantId/users/$UserId" $err = $null $response = Invoke-InforcerApiRequest -Endpoint $endpoint -Method GET -OutputType PowerShellObject -ErrorVariable err -ErrorAction SilentlyContinue if ($null -eq $response) { # Only emit UserNotFound if API returned 404; otherwise the API helper already wrote the real error if ($err -and $err[0].FullyQualifiedErrorId -like 'ApiRequestFailed_404*') { Write-Error -Message "User '$UserId' not found in tenant '$resolvedTenantId'." -ErrorId 'UserNotFound' -Category ObjectNotFound } elseif (-not $err) { Write-Error -Message "User '$UserId' not found in tenant '$resolvedTenantId'." -ErrorId 'UserNotFound' -Category ObjectNotFound } return } if ($OutputType -eq 'JsonObject') { return $response | ConvertTo-Json -Depth 100 } $null = Add-InforcerPropertyAliases -InputObject $response -ObjectType User $response.PSObject.TypeNames.Insert(0, 'InforcerCommunity.User') return $response } # --- List: paginated user list --- $jsonBuffer = if ($OutputType -eq 'JsonObject') { [System.Collections.ArrayList]::new() } else { $null } $continuationToken = $null $pageCount = 0 $itemCount = 0 do { $pageCount++ $endpoint = "/beta/tenants/$resolvedTenantId/users" $queryParams = @() if ($Search) { $queryParams += "search=$([System.Uri]::EscapeDataString($Search))" } if ($continuationToken) { $queryParams += "continuationToken=$([System.Uri]::EscapeDataString($continuationToken))" } if ($queryParams.Count -gt 0) { $endpoint += '?' + ($queryParams -join '&') } Write-Verbose "Fetching page $pageCount..." $response = Invoke-InforcerApiRequest -Endpoint $endpoint -Method GET -OutputType PowerShellObject -PreserveFullResponse if ($null -eq $response) { break } # continuationToken is at the response root level (sibling of .data), not inside .data $items = if ($null -ne $response.PSObject.Properties['data']) { $response.data } else { $null } $newToken = if ($null -ne $response.PSObject.Properties['continuationToken']) { $response.continuationToken } else { $null } # Guard against infinite loop: if API returns the same token, stop if ($newToken -and $newToken -eq $continuationToken) { Write-Verbose "API returned duplicate continuationToken. Stopping pagination." break } $continuationToken = $newToken if ($null -ne $items) { $itemArray = @($items) Write-Verbose "Page $pageCount returned $($itemArray.Count) items." foreach ($item in $itemArray) { if ($null -eq $item) { continue } if ($MaxResults -gt 0 -and $itemCount -ge $MaxResults) { $continuationToken = $null break } $itemCount++ if ($OutputType -eq 'JsonObject') { # Buffer raw items without aliases for clean JSON [void]$jsonBuffer.Add($item) } else { # Stream to pipeline immediately $null = Add-InforcerPropertyAliases -InputObject $item -ObjectType UserSummary $item.PSObject.TypeNames.Insert(0, 'InforcerCommunity.UserSummary') $item } } } } while ($continuationToken) if ($OutputType -eq 'JsonObject') { return $jsonBuffer | ConvertTo-Json -Depth 100 } } } |