How to retrieve all Okta groups including their members using Powershell

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.

  1. First, you will need an Okta token to use with Powershell’s REST functions, this is the easiest part.
  2. Okta’s API’s are customer specific, so your $OktaAPIBaseURL parameter should be something like “https://companyname.okta.com”
  3. Run the retrieveAllOktaGroupsAndMembers function below with the token as a parameter
  4. 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
}

6
Leave a Reply

avatar
2 Comment threads
4 Thread replies
2 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
harryJosProvisioning Exchange Online / Office 365 Custom Roles automatically from Okta | Liebensraum Recent comment authors

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
newest oldest most voted
Notify of
harry
Guest
harry

Hi Jos, how can we edit the script to look for single group. Can you please help me there

trackback

[…] To use this script, you’ll need an Okta token […]