Giter VIP home page Giter VIP logo

oktaapi.psm1's Introduction

OktaAPI.psm1

Call the Okta API from PowerShell -- unofficial code.

This module provides a thin wrapper around the Okta API. It converts to/from JSON. It supports pagination of objects and allows you to check rate limits.

It assumes you are familiar with the Okta API and using REST.

Contents

Usage

# Connect to Okta. Do this before making any other calls.
Connect-Okta "YOUR_API_TOKEN" "https://YOUR_ORG.oktapreview.com"

# Show info about the current user.
Get-OktaUser "me"

# Add a user to a group.
$user = Get-OktaUser "me" # or "login" or "id"
$group = Get-OktaGroups "PowerShell" 'type eq "OKTA_GROUP"'
Add-OktaGroupMember $group.id $user.id

# Create a user.
$profile = @{login = $login; email = $email; firstName = $firstName; lastName = $lastName}
$user = New-OktaUser @{profile = $profile}

# Create a group.
$profile = @{name = $name; description = $description}
$group = New-OktaGroup @{profile = $profile}

# Get all users. If you have more than 200 users, you have to use pagination.
# See this page for more info:
# https://developer.okta.com/docs/reference/api-overview/#pagination
$params = @{filter = 'status eq "ACTIVE"'}
do {
    $page = Get-OktaUsers @params
    $users = $page.objects
    foreach ($user in $users) {
        # Add more properties here:
        Write-Host $user.profile.login $user.profile.email
    }
    $params = @{url = $page.nextUrl}
} while ($page.nextUrl)

# Query up to 200 users by first name, last name or email.
$page = Get-OktaUsers -q "first name"
$users = $page.objects

# Filter lists all users; filter by status, last updated, id, login, email, first name or last name.
$page = Get-OktaUsers -filter 'profile.firstName eq "first name"'
$users = $page.objects # see pagination above.

# Search lists all users; search by any user profile property, including custom-defined
# properties, and id, status, created, activated, status changed and last updated.
$page = Get-OktaUsers -search 'profile.department eq "IT"'
$users = $page.objects # see pagination above.

See CallOktaAPI.ps1 for more examples.

There are functions for Apps, Events, Factors, Groups, IdPs, Logs, Roles, Schemas, Users and Zones. And you can add your own.

Installation

To determine which version of PowerShell you're running, see PSVersion under $PSVersionTable.

To Install on PowerShell 5 or newer

Install-Module OktaAPI # [1]

Install-Script CallOktaAPI # [2]

CallOktaAPI.ps1 has sample code. Replace YOUR_API_TOKEN and YOUR_ORG with your values or use OktaAPISettings.ps1.

[1] https://www.powershellgallery.com/packages/OktaAPI
[2] https://www.powershellgallery.com/packages/CallOktaAPI

Might I also suggest an IDE and debugging tools

Converting JSON to PowerShell

Most Okta API calls come with sample curl commands with blocks of JSON. To convert from JSON to PowerShell:

  • Change { to @{
  • Change : to =
  • Change , to ; or use a line break instead
  • Change [ to @(, and ] to )
  • Change true, false and null to $true, $false and $null
  • Change \" to `"

Here is an example from Assign User to App:

JSON

{
  "id": "00ud4tVDDXYVKPXKVLCO",
  "scope": "USER",
  "credentials": {
    "userName": "[email protected]",
    "password": {
      "value": "correcthorsebatterystaple"
    }
  }
}

PowerShell

@{
  id = "00ud4tVDDXYVKPXKVLCO"
  scope = "USER"
  credentials = @{
    userName = "[email protected]"
    password = @{
      value = "correcthorsebatterystaple"
    }
  }
}

Or, use a here-string along with ConvertFrom-Json. Note that here-strings require @"<Enter> and <Enter>"@. In the example below, $newUser uses a here-string:

$id = "00ud4tVDDXYVKPXKVLCO"

$oldUser = @{
    credentials = @{
        userName = "[email protected]"
    }
}

$newUser = ConvertFrom-Json @"
{
  "id": "$id",
  "scope": "USER",
  "credentials": {
    "userName": "$($oldUser.credentials.userName)",
    "password": {
      "value": "correcthorsebatterystaple"
    }
  }
}
"@

Adding new endpoints

To add a new endpoint, check the documentation for the HTTP verb (e.g. GET, POST, PUT, DELETE) and URL, and convert it into a corresponding PowerShell call.

For example, the documentation for Get User says:

GET /api/v1/users/${id}

The PowerShell code is:

function Get-OktaUser($id) {
    Invoke-Method GET "/api/v1/users/$id"
}

See Modules/OktaAPI.psm1 for more examples.

oktaapi.psm1's People

Contributors

gabrielsroka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oktaapi.psm1's Issues

Map existing application and group in okta

Experts,

Trying to map application & group

applicationID - abcd
groupID - xyzg
group name - admins

appId_groupId.csv - contents
applicationID,groupID,group
abcd,xyzg,admins

Import-Module OktaAPI
Connect-Okta "xyzabc" "https://abcXYZ_okta.com/"
function Add-AppAssign() {
$users = Import-Csv appId_groupId.csv
foreach ($line in $lines) {
Add-OktaAppGroup $line.applicationId $line.groupId $line.group
}
}Add-AppAssign appId_groupId.csv
Error:
Invoke-RestMethod: {"errorCode":"E0000003","errorSummary":"The request body was not well-formed."

Inputs appreciated !

Query - New Group Rules

I'm trying to better understand how to new group rules with New-OktaGroupRule, but I'm afraid I just can't get the syntax correct.

Would you mind posting a working example of how you would construct the parameters for New-OktaGroupRule?

Below is my current attempt at this command.

New-OktaGroupRule @{
type = "group_rule"
name = "TestGroup01Rule"
conditions = @{
    value = "user.ej_location==\00000000\"
    type = "urn:oktaexpresssion:1.0"
actions = @{
    assignUserToGroups =@{
        groupIds = "GroupIDhere"
        allGroupsValid = "$True"

    }

Using bearer tokens in Connect-Okta

Hi Gabriel,

I'm using your API to do a host of different functions for a client. I've coded everything up and it was working perfectly, thank you so much for the API!

However, since I don't want my client to have the API key hardcoded in the script, I set up a device grant flow to get a bearer access token for making calls to the API. I've modified the Connect-Okta functions Authorization Header to use the "Bearer " header to access the Okta API with the proper key. When testing this in Postman, it should be working. However when I then try to use this Connect-Okta function with the script it's giving me "Invalid URI: The hostname could not be parsed" errors.

Would you by any chance know how to use the device grant flow with your API?

Get-OktaUser Exception thrown ??

Everytime I try to get a user, being prompted wi/ the following error:

Get-OktaUser : Exception of type 'Okta.Core.OktaException' was thrown.
At line:1 char:9
$user = Get-OktaUser "user"
~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : NotSpecified: (:) [Get-OktaUser], OktaException
FullyQualifiedErrorId : Okta.Core.OktaException,Okta.Core.Automation.GetOktaUser

Re-Activate User by ID

I've created a function for this module that I figure others might find useful...

function oktaReactivateUserbyId()
{
    param
    (
        [parameter(Mandatory=$false)]
            [ValidateLength(1,100)]
            [String]$oOrg=$oktaDefOrg,
        [Parameter(Mandatory=$false)]
            [ValidateLength(20,20)][
            string]$uid,
        [parameter(Mandatory=$false)]
            [string]$username
    )
    if (!$uid)
    {
        if ($username)
        {
            $uid = (oktaGetUserbyID -oOrg $oOrg -userName $username).id
        } else {
            throw ("Must send one of uid or username")
        }
    }

    [string]$resource = '/api/v1/users/' + $uid + '/lifecycle/reactivate?sendEmail=True'
    [string]$method = "Post"
    try
    {
        $request = _oktaNewCall -method $method -resource $resource -oOrg $oOrg
    }
    catch
    {
        if ($oktaVerbose -eq $true)
        {
            Write-Host -ForegroundColor red -BackgroundColor white $_.TargetObject
        }
        throw $_
    }

    return $request
}

Bulk import into Okta

file - users.csv

login,email,firstName,lastName,password,groupid
[email protected],[email protected],user5,pwsh,Password1!,xxxxxyyyzzz

steps followed:

Import-Module OktaAPI
Connect-Okta "<API Token>" "https://tenant.okta.com"
Import-Users users.csv

Results:
user got created in the correct groupID mentioned in csv
status on user - marked as below
Staged
Activate

user_record_marked_as_activate_okta

how to auto-activate users when doing a bulk (CSV) import
What should be the header parameter in my csv file to accomplish this.

Cannot login into okta console with newly created login / password.
Looks like password given in csv file is not properly assigned to the user record during import.

Any help is highly appreciated !

Import existing users to single group via CSV?

Hello! Apologies somewhat new to both GitHub and PowerShell.

Question - trying to take the snipping below, but for my situation I want to take a CSV of existing users, and assign them all to a single existing Okta group. I've tried modifying this in various ways but keeps failing. I have (2) columns in my CSV, one for username and one for the group ID, but cannot get this to run correctly. Any recommendations?

function Import-UsersAndGroups() {
<# Sample CSV file with 5 fields. Make sure you include the header line as the first record.
login,email,firstName,lastName,groupIds
[email protected],[email protected],Test,A1,"00g5gtwaaeOe7smEF0h7;00g5gtwaaeOe7smFF0h7"
[email protected],[email protected],Test,A2,"00g5gtwaaeOe7smEF0h7;00g5gtwaaeOe7smFF0h7"
#>
    $users = Import-Csv usersAndGroups.csv
    foreach ($user in $users) {
        $profile = @{login = $user.login; email = $user.email; firstName = $user.firstName; lastName = $user.lastName}
        $groupIds = $user.groupIds -split ";"
        $oktaUser = New-OktaUser @{profile = $profile; groupIds = $groupIds}
    }
}

Tried something along these lines, a few different ways but I feel like its missing the command to 'add to group' or something like that:

$users = Import-Csv 
foreach ($user in $users) {
        $login = $user.login
        $groupIds = $user.groupIds
    }

Thank you!
Joel

Getting next page of logs

Hi Gabriel,

I'm new to using APIs and am working on a PowerShell script to automate the download of Okta system logs. I have Get-OktaLogs working and am able to capture the numbers of log entries based on the -limit value. My understanding is I should be able to then pull the next page of logs. How would I get the next page of logs?

Thank you,
Craig

API key question

Got everything working like i mentioned. However, my goal is to include this in an already existing PowerShell script that I have. Currently, I have this included in the script:

Import-Module OktaAPI
Connect-Okta "MY_API_KEY" "https://my-org.okta.com"

$user = *User running the script enters user info here.

Disable-OktaUser $user

Everything is working. My question is, my API key is open to anyone that opens the script. Is there a way you would recommend in that anyone can run the script, but the API key is concealed? Again, appreciate the help.

Invoke-Webrequest fails on powershell 5 and below on a machine without IE or a user that has never run it

When running Invoke-WebRequest on powershell < 6 the cmdlet will fail if Internet Explorer is not available (such as in core versions of windows) or if the user running the code has never opened IE at least once and clicked through the initial setup. The error given is:

    The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again.

This means that when running as a scheduled task the specific user running the task would have to interactively log into that machine and run IE at least once. This is not ideal.

Per Microsoft, "UseBasicParsing" has become the default in PS6, however even new installs of server 2019 don't have PS6. (https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-7)

There is no functionality loss for this use case (UseBasicParsing disables DOM parsing).

I'll submit a pull request shortly with some updated code.

License

Hello,
Would you mind adding a license to this project? I'm interested in possibly forking it but wanted to be clear on the licensing before I did. Thanks!

(400) Bad Request

I followed your instructions but still get the following error when trying to use these.

Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At C:\Program Files\WindowsPowerShell\Modules\OktaAPI\1.0.5\OktaAPI.psm1:118 char:5

  • Invoke-RestMethod $url -Method $method -Headers $headers -Body $j ...
    
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    • FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Can Fetching limit be increased for Get-OktaUsers Function ?

Hi Team,

While using the below function, the limit to fetch the user is 200. Can it be increased? Or can another function be written to fetch 1000 users?

function Get-OktaUsers($q, $filter, $limit = 200, $url = "/api/v1/users?q=$q&filter=$filter&limit=$limit&search=$search", $search) {
    Invoke-PagedMethod $url
}

Query : What is $group ? OktaAPI.psm1/Modules/OktaAPI.psm1 : Line 82

Hi @gabrielsroka

I am not sure if this is the right forum to ask the query, hence apologise if this should not be placed here

I am trying to add a group to an app via Okta API in PowerShell using the OKTA API

I am using the function below from the code of OKTA-API.psm1, line 82

function Add-OktaAppGroup($appid, $groupid, $group) 
{
    Invoke-Method PUT "/api/v1/apps/$appid/groups/$groupid" $group
}

I am not sure what value I should be passing to $groups because, in OKTA-API for assigning app to the group, it only requires groupID and appID - {{url}}/api/v1/apps/appid/groups/groupid

Let me know if I should provide more inputs for this.

Invoke-RestMethod 400 Bad Request

So, I'm attempting to modify an Okta user with the Set-OktaUser command, but it keeps giving an error message when I attempt to Set the changes back to the system. I feel like I'm missing something obvious, but what might it be?

Thanks!!!

PS C:\Windows\system32> $user.profile

firstName : Testing
lastName : BettyWhite
mobilePhone : 4992387489725
secondEmail : --------------------------------
login : ------------------------------------
email :

PS C:\Windows\system32> $user.profile.mobilePhone = "4995551234"

PS C:\Windows\system32> Set-OktaUser $user
Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At C:\Program Files\WindowsPowerShell\Modules\OktaAPI\1.0.19\OktaAPI.psm1:283 char:5

  • Invoke-RestMethod $url -Method $method -Headers $headers -Body $j ...
    
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    • FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Tip for Managing IDs

Not an issue, just a tip I've come across.

If you're having trouble managing the IDs for groups, users, apps, etc. across sandbox and production environments, I've found it easiest to put it all in one object like so:

$Okta = @{
  Production = @{
    Groups = @{
      ZoomProvisioning = "00g8wwkpwuRWXjfz91t7"
      LdapProvisioning = "00g7gt0qm2fP77Bzp1t7"
      RegularEmployees = "00g77af853E2xPiSk1t7"
      SoxhubUsers      = "00g7d8878r6YPflEk1t7"
    }
    Users  = @{
      Me = "00u438boi8Srq4GEq1t7"
    }
    Apps = @{
      SuccessFactorsProvisioning = "0oa7dq5t5xwsOxqnZ1t7"
      Gitlab                     = "0oa64z40j7zkr0zGh1t7"
    }
  }
}

This way you can quickly access an ID with $Okta.Production.Groups.RegularEmployees. Remember: tab completion is your friend!

The biggest pro for me is that I know for a fact whether or not I'm on production or sandbox and won't ever get the two mixed up.

I can write this up and put it in a gist or the wiki or the Readme if that's a better place for it.

New-OktaGroup

New-OktaGroup doesn't work properly. The only command that gives me trouble
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.