Okta exposes a very useful API, with which I’ve been working for a while to ensure business fit for certain scenario’s that Okta and/or Office 365/Azure don’t fully support yet.
One of those scenario’s requires information about certain groups and their members. I’m narrowing the selection down to just pure Okta groups, but any groups (e.g. AD Synced) can be returned with below code by adjusting the filter in the retrieveAllOktaGroups function.
- First, you will need an Okta token to use with Powershell’s REST functions, this is the easiest part.
- Okta’s API’s are customer specific, so your $OktaAPIBaseURL parameter should be something like “https://companyname.okta.com”
- Run the retrieveAllOktaGroupsAndMembers function below with the token as a parameter
- Remember that Okta tokens expire if not used for a while
function Invoke-PagedMethod { Param( $url, $authHeader ) try{ $response = Invoke-WebRequest $url -Method GET -Headers $authHeader -ErrorAction Stop $links = @{} if ($response.Headers.Link) { foreach ($header in $response.Headers.Link.split(",")) { if ($header -match '<(.*)>; rel="(.*)"') { $links[$matches[2]] = $matches[1] } } } @{objects = ConvertFrom-Json $response.content; nextUrl = $links.next} }catch{ Throw $_ } } function buildOktaAuthHeader{ Param( [Parameter(Mandatory=$true)]$oktaToken ) $authHeader = @{ 'Content-Type'='application/json' 'Accept'='application/json' 'Authorization'= 'SSWS '+$oktaToken } return $authHeader } function retrieveAllOktaGroups{ Param( [Parameter(Mandatory=$true)]$oktaToken, [Parameter(Mandatory=$true)]$oktaAPIBaseURL ) $authHeader = buildOktaAuthHeader -oktaToken $oktaToken $groups = @() $res = @{"nextURL"="$oktaAPIBaseURL/api/v1/groups?limit=200&filter=type eq `"OKTA_GROUP`""} while($true){ try{ if($res.nextURL -eq $Null){ write-verbose "finished retireveAllOktaUsers function" break; } $res = Invoke-PagedMethod –Url $res.nextURL -authHeader $authHeader -Method GET if($res.objects){ $groups += $res.objects } write-verbose "retrieved $($groups.Count) groups..." }catch{ Throw "failed to retrieve groups from Okta: $_" } } return $groups } function retrieveOktaGroupMembers{ Param( $oktaToken, $groupHref ) $authHeader = buildOktaAuthHeader -oktaToken $oktaToken $members = @() $res = @{"nextURL"="$($groupHref)?limit=200"} while($true){ try{ if($res.nextURL -eq $Null){ write-verbose "finished paged function" break; } $res = Invoke-PagedMethod –Url $res.nextURL -authHeader $authHeader -Method GET if($res.objects){ $members += $res.objects } write-verbose "retrieved $($members.Count) members..." }catch{ Throw "failed to retrieve members from Okta: $_" } } return $members } function retrieveAllOktaGroupsAndMembers{ Param( $oktaToken, $oktaAPIBaseURL ) $groupsAndMembers = @() foreach($group in (retrieveAllOktaGroups -oktaToken $oktaToken -oktaAPIBaseURL $oktaAPIBaseURL)){ $groupMembers = retrieveOktaGroupMembers -oktaToken $oktaToken -groupHref $group._links.users.href if($groupMembers){ Write-Verbose "Adding $($groupMembers.Count) members to group" $group | Add-Member -MemberType NoteProperty -Name "Members" -Value $groupMembers } $groupsAndMembers+=$group } return $groupsAndMembers }
this was a really good script. I would love to see an example on how you pass the parameter and how the values return. overall a quality share
Hi Jos, how can we edit the script to look for single group. Can you please help me there
[…] To use this script, you’ll need an Okta token […]