0D50Z00008G7VQRSA3Okta Classic EngineAdministrationAnswered2024-09-15T09:01:14.000Z2015-09-21T20:43:10.000Z2020-05-14T21:52:02.000Z
  • svcV.75126 (Customer)

    Hi Tae,

     

    There isn't currently a way to do this through the GUI.

     

    Leveraging the okta API you can do it pretty easily. The API is documented here (http://developer.okta.com/docs/api/getting_started/design_principles.html" target="_blank(http://developer.okta.com/docs/api/getting_started/design_principles.html)).

     

    If you are working on or have access to a windows system and want to leverage some prior work i've built a powershell module that can be used to do it. The powershell module can be found here (https://github.com/mbegan/Okta-PSModule)along with some basic documentation on getting it setup.

     

    The resulting script to download and export basic information about your users would look something like this.

     
    1.  $users = oktaListUsers -oOrg prod $toexport = New-Object System.Collections.ArrayList foreach ($u in $users) {  $line = @{  oktaid = $u.id  login = $u.profile.login  firstName = $u.profile.firstName   lastName = $u.profile.lastName   email = $u.profile.email  }  $obj = New-Object psobject -Property $line  $_c = $toexport.Add($obj) } $toexport | Export-Csv -Path c:\temp\exp1.csv -NoTypeInformation
     

    -Matt
    Expand Post
  • j5v7c (j5v7c)

    Hi Tae,

     

    Can you try this? Head to your Reports section in your Admin Console.

     

    Download the "Okta Password Health" report.  That might do the trick.

     

    Madhu Mahadevan, Sr. Sales Engineer, Okta

     

    fK7hz4m
    Expand Post
  • elnsf (elnsf)

    Hi Matt -

     

    Above powershell script works for me but it is limiting to 120 user limit. Can you suggest how to open the pagination limit to retieve all accounts with this query?

     

    Thanks,
    Expand Post
  • mw5qr (mw5qr)

    Hi,

     

    I realise this case is old, but we developed a Python script that can keep making API calls until it retrieves all the people data.

     

    Here is the script code. Hopefully it is useful.

    ====================================================================================

    import requests

    import json

    from pathlib import Path

    import csv

     

    # Define Okta API base URL

    base_okta_url = "https://YOUR-OKTA-NAME.okta.com"

     

    # Define the API token required by Okta

    okta_apikey = "PUT-YOUR-OKTA-API-TOKEN-HERE"

     

    # Define record limit (200 is the maximum accepted by Okta)

    limit = 200

     

    # If get_all_data is True, then the script will call Get User until all data is retrieved.

    get_all_data = True

    #get_all_data = False

     

    # Define the Okta Users endpoint

    url = base_okta_url + "/api/v1/users" + "?limit=" + str(limit)

     

    # CSV - JSON Response Mapping

    # ADD OTHER OKTA ATTRIBUTES OR CHANGE THE ORDER OF COLUMNS FOR THE CSV BELOW

    column_list = ["firstName","lastName","displayName","manager","title","login","email","department"]

     

    # Construct the headers

    headers = {

      'content-type': 'application/json',

    'Authorization': 'SSWS ' + okta_apikey

    }

     

    # Setup path for current directory and file name for the Export file

    data_folder = Path(".")

    export_file = data_folder / "okta_user_export.csv"

    exportfile = open(export_file,"w+")

    # Join the values from the column list to build a CSV title row, with delimeters

    col_headings = '"' + '", "'.join(column_list) + '"'

    exportfile.write(col_headings)

    csv_delim = '","'

     

    # Set conditions for while loop. Used with pagination.

    next = False

    first = True

    next_url = ""

     

    # While loop use to control first and subsequent requests

    while (next or first):

    # If next_url is defined, this is not the first time through the loop,

    # and we should have the next_url generated from Okta

    response_json = []

    # If this is the second (or greater) call to Get Users

    if next:

    # Make the API call

    response = requests.request("GET", next_url, headers=headers)

    response_json = response.json()

    # Parse the LINK headers from the response.

    response_links = requests.utils.parse_header_links(response.headers['Link'].rstrip('>').replace('>,<', ',<'))

    next_url = ""

    # Look for the 'next' url in the response links.

    for linkobj in response_links:

    if linkobj['rel'] == 'next':

    next_url = linkobj['url']

    next = True

    else:

    next = False

    # If this is the first call to Get Users

    if first:

    # Make the request to Okta and record the response

    response = requests.request("GET", url, headers=headers)

    response_json = response.json()

    # Parse the LINK headers from the response.

    if (response.status_code == 200):

    response_links = requests.utils.parse_header_links(response.headers['Link'].rstrip('>').replace('>,<', ',<'))

    next_url = ""

    for linkobj in response_links:

    #print(linkobj['rel'])

    if linkobj['rel'] == 'next':

    next_url = linkobj['url']

    next = True

     

    # Turn off first flag so that the next option is selected on subsequent loops

    first = False

    else:

    print(response.status_code)

    print(response_json)

    exit(1)

    # write the response to file

    for entry in response_json:

    # Build the CSV row

    csv_record = []

    # Loop through in column in the column list

    for col in column_list:

    # If we can find column in profile object append it

    if col in entry['profile']:

    csv_record.append(entry['profile'][col])

    # Else if we can find column in root object append it

    elif col in entry:

    csv_record.append(entry[col])

    # Else if we can't find, write a dash to preserve column format

    else:

    csv_record.append("-")

    # Write the CSV row to the file

    csv_line = '"' + csv_delim.join( csv_record ) + '"'

    exportfile.write("%s\n" % (csv_line))

    # If we don't want to get all data (i,e we only want 'limit' records), exit the loop.

    if get_all_data == False:

    break

    exportfile.close

    print("Done.")

    =====================================================================================

     

    Expand Post
  • 1xm7h (1xm7h)

    Wow. For the price we're paying and you can't export a simple list of users (which basically EVERY OTHER APP IN THE WORLD HAS AS THEIR FIRST OPTION FOR REPORTS) - it's just mind-boggling! Add that to the "upgrades" you've made so I can't even view all my users anymore under People, and I'd say Okta is on it's way out the door in a big fat hurry...

  • kristie.garafola (Okta, Inc.)

    I'm really sorry to hear you're frustrated Deb. I reached out to our product team to share your feedback and they let me know this functionality is on our long term roadmap. I'll be sure to share more when we have more specific delivery timeline.

     

    In the meantime, they recommended the following as a workaround:

     

    The exportable Password Health report provides a list of all users (as well as their logins, current status, activation date, auth source, last login date and last password change date). Depending on what you want to do with the user data, this report may cover your needs for the time being

     

    Hope this is helpful and again- we'll update everyone as we have more info on timing.

    Expand Post
  • wylvh (wylvh)

    I'll second Deb's request. I've had to report on Okta users and suffer the same problem. I use an API script to do this, but Deb is right that for an enterprise product like Okta that is meant to scale to thousands of users, a simple user export function should not be missing. We need to routinely audit and report on Okta users. Please, improve the reporting in general in Okta. Too simplistic for a product of this sort.

    Expand Post
  • ajhstn (Customer)

    Another dirty python example. If you need to pull more than 200 users, borrow code from the previous comments and integrate.

     

    import requests

    api_token = '<your token>'

    headers = {

    'Accept': 'application/json',

    'Content-Type': 'application/json',

    'Authorization': f"SSWS {api_token}"

    }

     

    url = 'https://<your okta domain>.okta.com/api/v1/users'

    while len(url) > 0:

    r = requests.get(url, headers=headers)

    print(r.content)

    links = r.links

    url = links['next']['url']

     

    Expand Post
  • ajhstn (Customer)

    And here's the PowerShell version if needed. This will automatically keep looping until the entire directory is downloaded. I then create a custom PS object to hold the properties i want and then spit it out to CSV.

     

    Feel free to contribute and use the code.

    https://github.com/ajhstn/okta-tools/blob/master/Export-AllOktaUsers.ps1

     

    # Use TLS 1.2

    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

     

    # Setup Auth Header

    $header = @{

    Authorization = "SSWS <your token here>"

    }

     

    # API Resource Endpoint

    $url = "https://<your okta domain here>.okta.com/api/v1/users"

     

    $Users = @()

     

    do {

    $result = Invoke-WebRequest -Uri $url -Headers $header -UseBasicParsing

    $json = $result.Content | convertfrom-json

    $Users += $json

    $next = (($result.Headers.Link -split "`n")[1] -replace "[\<\>]" -split ";")[0]

    $url = $next

    }

    while ($result.Headers.Link[1] -match "next")

     

    $Users | Foreach-object {

    [pscustomobject]@{

    FirstName = $_.profile.firstName

    LastName = $_.profile.lastName

    DisplayName = if ($_){$_.profile.displayName}else{$_}

    login = $_.profile.login

    email = $_.profile.email

    Description = $_.profile.Description

    Department = $_.profile.department

    State = $_.status

    StatusChanged = $_.statusChanged

    Created = $_.created

    LastLogin = $_.lastLogin

    PasswordChanged = $_.passwordChanged

    Error = if ($_ -eq $null){"Something wrong"}else{}

    }

    } | Export-Csv ./AllUsers-Feb2019.csv -Force

     

    #Write-Output "($Users).count:OK"

     

     

     

    Expand Post
  • Hi Andrew,

     

    I tried your PowerShell code but still only get 200 users to download (I have 350 or so total). There must be a way to get all 350 users to download isn't there?

     

    Thanks!

     

    Expand Post
10 of 47
This question is closed.

Recommended content