PowerShell API to copy users from group to group based on filters

Thanks for taking a minute to look at this.
Scenario: Move users from a series of groups based on a filter to another series of groups based on a separate filter.

I created some code that grabs all the groups based on the filter and can get all of the users but am having a hard time translating that into the individual pieces. For each group I want just that groups members and then add them to a group with the same name but of a different type (one is OKTA_GROUP and the other is APP_GROUP).

Here is what I have so far.

function get-oktaInvokeGroupMembers () {
   $groups = Invoke-Method GET "/api/v1/groups?filter=type+eq+%22APP_GROUP%22&q=p.tableau"
    Write-Output $groups
      foreach ($group in $groups) {
        $members = Get-OktaGroupMember $group.id
      Write-Output $members
      }
    }

Hi there. I can’t speak specifically to the powershell piece of this, but I imagine your process would be the following:

  1. Run GET "/api/v1/groups?filter=type eq "OKTA_GROUP"&q=p.tableau"
  2. Use that group ID to then get membership at GET /api/v1/groups/{{groupId}}/users
  3. Run GET "/api/v1/groups?filter=type eq "APP_GROUP"&q=p.tableau"
  4. Iterate over your users list from step 2, and add membership to the group ID from step 3 with PUT /api/v1/groups/{{groupId}}/users/{{userId}}

Hopefully I’m not missing your question and telling you what you already know :wink:

This is helpful as step 3 was missing from my logic. My concern here is that it would just take all of the users from step 2 and put them in each of the groups from step 4.I can run it and see what happens.

Here is what I have now. Getting an error on the second part and not sure if the logic is quite right.

function get-oktaInvokeGroupMembers () {
   $groups = Invoke-Method GET "/api/v1/groups?filter=type+eq+%22APP_GROUP%22&q=Test"
    Write-Output $groups
      foreach ($group in $groups) {
        $members = Get-OktaGroupMember $group.id
      Write-Output $members
      }
   $oktagroups = Invoke-Method GET  "/api/v1/groups?filter=type+eq+%22OKTA_GROUP%22&q=Test"
   Write-Output $oktagroups
      foreach ($okta in $oktagroups) {
         PUT "/api/v1/$okta.id/users/$members.id"
      }
    }

Edited to fix the logic. Thinking out loud here but I think for powershell I need to create a PUT function first. Working on that now.

Hmm, I forgot that you wanted to move users FROM group to group. In that case you would also want to incorporate a call to remove users from the Okta group in step 4 as well. So:

DELETE /api/v1/groups/{{groupId from step 1}}/users/{{userId}}

Actually, I want them to stay in both groups. It’s part of a migration where I need to test the future state before deleting the old groups. This is me learning and building a functional library of tasks to better automate our environment overall as well.

Here is where I am at currently

function get-oktaInvokeGroupMembers () {
   $groups = Invoke-Method GET "/api/v1/groups?filter=type+eq+%22APP_GROUP%22&q=Test"
    Write-Output $groups
      foreach ($group in $groups) {
        $members = Get-OktaGroupMember $group.id
      Write-Output $members
      }
   $oktagroups = Invoke-Method GET  "/api/v1/groups?filter=type+eq+%22OKTA_GROUP%22&q=Test"
   Write-Output $oktagroups
      foreach ($okta in $oktagroups) {
         Invoke-Method PUT "/api/v1/groups/$okta.id/users/$members.id"
      }
    }

Hey @jspitaleri,

Were you able to successfully copy over those APP_GROUPS as an OKTA_GROUP?
I am also doing the similar things as we have tons of Namely group that I want to copy over as Okta group with the existing memberships.

There are some API constraints that prevent it from being done with scripting. I forget exactly but it has to do with how variables get passed to the API and the API not being able to use variables are various stages that are needed to make this work. I ended up using workflows to solve the problem. It’s a bit of a beast but it works, though it took me about a week to build this thing. You can copy these item by item and learn and test as you go but child flows take some getting used to. Good luck.

Here is the parent flow.

First child flow

Last child flow

Thank you so much!
Appreciate the quick response and the info.

Yeah, definitely will use Okta-Workflow on this. I’ll have to add a step to create the OTKA_group with the same name as the APP_GROUP.

I think something like this would work, but I’m not sure about your requirements, and I haven’t tested parts of it.

I wanted to point that the (unofficial) PowerShell SDK has functions to do most (all?) of what you want. You don’t need to write custom functions. GitHub - gabrielsroka/OktaAPI.psm1: Call Okta API from PowerShell -- unofficial code.

Depending on how many users are in each group, you might need to paginate. Check the readme and example code for help.

Lastly, would Okta Group Rules help here? if member of this group, add to that group.

$q = 'Test'
$appGroups = Get-OktaGroups $q 'type eq "APP_GROUP"'
$oktaGroups = Get-OktaGroups $q 'type eq "OKTA_GROUP"'
foreach ($appGroup in $appGroups) {
    $members = Get-OktaGroupMember $appGroup.id
    foreach ($member in $members) {
        # maybe search for a specific group here, instead of looping thru all of them
        foreach ($oktaGroup in $oktaGroups) {
            Add-OktaGroupMember $oktaGroup.id $member.id
        }
    }
}
1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.