Created
January 22, 2021 20:24
-
-
Save kevinblumenfeld/2e28951fe3035e3ee9b80f547ebe08ec to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function Get-OktaUserReport { | |
| <# | |
| .SYNOPSIS | |
| Searches for specific or all Okta Users | |
| .DESCRIPTION | |
| Searches for specific or all Okta Users. Use no parameters to return all users. e.g Get-OktaUserReport | |
| .PARAMETER SearchString | |
| Queries firstName, lastName, and email for a match to the -SearchString value specified. | |
| Partial matches can be searched for. For example, the search for "J" will Return users with the firstName Joe, John and lastName Hajib | |
| .PARAMETER ID | |
| Search by ID | |
| .PARAMETER Filter | |
| List Users with a Filter | |
| Filters against the most up-to-date data. For example, if you create a user or change an attribute and then issue a filter request, the changes are reflected in your results. | |
| Requires URL encoding. For example, filter=lastUpdated gt "2013-06-01T00:00:00.000Z" is encoded as filter=lastUpdated%20gt%20%222013-06-01T00:00:00.000Z%22. | |
| Examples use cURL-style escaping instead of URL encoding to make them easier to read. | |
| Supports only a limited number of properties: status, lastUpdated, id, profile.login, profile.email, profile.firstName, and profile.lastName. | |
| Filter Description | |
| status eq "STAGED" Users that have a status of STAGED | |
| status eq "PROVISIONED" Users that have a status of PROVISIONED | |
| status eq "ACTIVE" Users that have a status of ACTIVE | |
| status eq "RECOVERY" Users that have a status of RECOVERY | |
| status eq "PASSWORD_EXPIRED" Users that have a status of PASSWORD_EXPIRED | |
| status eq "LOCKED_OUT" Users that have a status of LOCKED_OUT | |
| status eq "DEPROVISIONED" Users that have a status of DEPROVISIONED | |
| lastUpdated lt "yyyy-MM-dd'T'HH:mm:ss.SSSZ" Users last updated before a specific timestamp | |
| lastUpdated eq "yyyy-MM-dd'T'HH:mm:ss.SSSZ" Users last updated at a specific timestamp | |
| lastUpdated gt "yyyy-MM-dd'T'HH:mm:ss.SSSZ" Users last updated after a specific timestamp | |
| id eq "00u1ero7vZFVEIYLWPBN" Users with a specified id | |
| profile.login eq "[email protected]" Users with a specified login | |
| profile.email eq "[email protected]" Users with a specified email* | |
| profile.firstName eq "John" Users with a specified firstName* | |
| profile.lastName eq "Smith" Users with a specified lastName* | |
| .EXAMPLE | |
| Get-OktaUserReport | |
| .EXAMPLE | |
| Get-OktaUserReport -Filter 'profile.firstName eq "Jennifer"' | |
| .EXAMPLE | |
| Get-OktaUserReport -SearchString kevin | |
| .EXAMPLE | |
| Get-OktaUserReport -Id 00u4m2pk9NMihnsWJ356 | |
| #> | |
| Param ( | |
| [Parameter()] | |
| [string] $SearchString, | |
| [Parameter()] | |
| [string] $Filter, | |
| [Parameter()] | |
| [string] $Id, | |
| [Parameter()] | |
| [string] $Login | |
| ) | |
| if ($SearchString -and $filter -or ($SearchString -and $Id) -or ($Filter -and $Id)) { | |
| Write-Warning "Choose between zero and one parameters only" | |
| Write-Warning "Please try again" | |
| break | |
| } | |
| # $Url = $OKTACredential.GetNetworkCredential().username | |
| # $Token = $OKTACredential.GetNetworkCredential().Password | |
| $Headers = @{ | |
| "Authorization" = "SSWS $Token" | |
| "Accept" = "application/json" | |
| "Content-Type" = "application/json" | |
| } | |
| if (-not $SearchString -and -not $id -and -not $Filter -and -not $Login) { | |
| $RestSplat = @{ | |
| Uri = "$Domain/api/v1/users/?limit=200" | |
| Headers = $Headers | |
| Method = 'Get' | |
| } | |
| } | |
| else { | |
| if ($SearchString) { | |
| $RestSplat = @{ | |
| Uri = "$Domain/api/v1/users/?limit=200&q=$SearchString" | |
| Headers = $Headers | |
| Method = 'Get' | |
| } | |
| } | |
| if ($Filter) { | |
| $RestSplat = @{ | |
| Uri = "$Domain/api/v1/users/?limit=200&filter=$Filter" | |
| Headers = $Headers | |
| Method = 'Get' | |
| } | |
| } | |
| if ($Id) { | |
| $RestSplat = @{ | |
| Uri = '{0}/api/v1/users/?limit=200&filter=id eq "{1}"' -f $Domain, $id | |
| Headers = $Headers | |
| Method = 'Get' | |
| } | |
| } | |
| if ($Login) { | |
| $RestSplat = @{ | |
| Uri = "$Domain/api/v1/users/$Login" | |
| Headers = $Headers | |
| Method = 'Get' | |
| } | |
| } | |
| } | |
| do { | |
| [int]$NumberLimit = $Response.Headers.'x-rate-limit-remaining' | |
| [long][string]$UnixTime = $Response.Headers.'x-rate-limit-reset' | |
| if ($NumberLimit -and $NumberLimit -eq 1) { | |
| $ApiTime = $Response.Headers.'Date' | |
| $SleepTime = Convert-OktaRateLimitToSleep -UnixTime $UnixTime -ApiTime $ApiTime | |
| Start-Sleep -Seconds $SleepTime | |
| } | |
| $Response = Invoke-WebRequest @RestSplat -Verbose:$false | |
| $Headers = $Response.Headers | |
| $User = $Response.Content | ConvertFrom-Json | |
| if ($Response.Headers['link'] -match '<([^>]+?)>;\s*rel="next"') { | |
| $Next = $matches[1] | |
| } | |
| else { | |
| $Next = $null | |
| } | |
| $Headers = @{ | |
| "Authorization" = "SSWS $Token" | |
| "Accept" = "application/json" | |
| "Content-Type" = "application/json" | |
| } | |
| $RestSplat = @{ | |
| Uri = $Next | |
| Headers = $Headers | |
| Method = 'Get' | |
| } | |
| foreach ($CurUser in $User) { | |
| $Id = $CurUser.Id | |
| $ProfileDetail = ($CurUser).Profile | |
| $CredDetail = ($CurUser).Credentials | |
| [PSCustomObject]@{ | |
| FirstName = $ProfileDetail.FirstName | |
| LastName = $ProfileDetail.LastName | |
| Login = $ProfileDetail.Login | |
| Email = $ProfileDetail.Email | |
| Id = $Id | |
| ProviderType = $CredDetail.Provider.Type | |
| ProviderName = $CredDetail.Provider.Name | |
| Status = $CurUser.Status | |
| Created = $CurUser.Created | |
| Activated = $CurUser.Activated | |
| StatusChanged = $CurUser.StatusChanged | |
| LastLogin = $CurUser.LastLogin | |
| LastUpdated = $CurUser.LastUpdated | |
| PasswordChanged = $CurUser.PasswordChanged | |
| RecoveryQuestion = $CredDetail.RecoveryQuestion.Question | |
| } | |
| } | |
| } until (-not $next) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment