When a user is terminated in Workday, the integration sets the expiration date on the user's AD account, and when that change imports into Okta, the user's Okta account goes into a "Deprovisioned" status. Within a few days, the user's account is deleted from Active Directory, per our security policies.
Recently, Human Resources asked us to come up with a way to allow former associates (they now use the term, "alumni") to access Workday for up to 2 years after their termination, primarily so they can access their W-2 tax forms. Reasonable request, although they didn't give us much time to come up with an automated solution before this year's crop of seasonal associates were let go. Remember, the users' AD accounts no longer exist (and our security policies demand that those accounts get deleted shortly after termination), and their Okta accounts have been deactivated (actually, I was deleting the deactivated accounts manually, semi-regularly).
At first, I used the okta.core.automation powershell module to build a scripted solution, and it worked pretty well. Unfortunately, the module has some significant limitations, and less than 2 weeks before go-live, Okta Support informed me that the module was no longer being developed or supported. Well, that just wouldn't do. I didn't want to provide a solution that might break without warning, especially if so many users would be affected, so I started looking for another solution.
Third party modules are too fickle, so I wanted to find something that followed the Okta guidelines and examples more closely. In my research, I noticed that their developer docs included examples using the 'curl' command (it's a REST API, and most of Okta's docs seem to be Linux-oriented). While Windows doesn't have a native curl command, powershell does alias 'curl' to the Invoke-WebRequest command, which essentially performs the same function as curl - you build and submit http/https requests to a REST API. I'd never used Invoke-WebRequest before, so I had to do some web searches and see how other folks were using it, and eventually came up with commands that retrieved the information I needed. Here's the resulting code.
$api_token = "[REMOVED]"
$allusers = @()
$webrequest = Invoke-WebRequest -Headers @{"Authorization" = "SSWS $api_token"} -Method GET -Uri "https://mycompany.okta.com/api/v1/users?filter=status%20eq%20%22DEPROVISIONED%22"
$json = $webrequest | ConvertFrom-Json
$allusers += $json
foreach ($usr in $allusers) {
if ($usr.profile.employeenumber -match '^\d\d\d\d\d\d$' -OR $usr.profile.employeenumber -match '^C\d\d\d\d\d\d$') {
write-output "Reactivate account: $($usr.profile.employeenumber) $($usr.profile.displayname) $($usr.id)"
Invoke-WebRequest -Headers @{"Authorization" = "SSWS $api_token"} -Method POST -Uri "https://mycompany.okta.com/api/v1/users/$($usr.id)/lifecycle/activate"
Invoke-WebRequest -Headers @{"Authorization" = "SSWS $api_token"} -Method PUT -Uri "https://mycompany.okta.com/api/v1/groups/00gdnc2yo5OILSKLK2p6/users/$($usr.id)" }
}
Line 1: For this to work, you need an API token from Okta.
Line 2: Create an empty array to hold our query results
Line 3: Query Okta for all accounts currently in "DEPROVISIONED" status
Line 4: Convert the JSON response to a powershell array
Line 5: Add the converted data to the array we initialized earlier
Line 6: Start looping through the results
Line 7: Workday-mastered users have employeeNumbers in a specific format
Line 8: Output the detail for each user
Line 9: Reactivate the account that matches the criteria in Line 7
Line 10: Add the reactivated account to a special Okta-mastered group that is used to assign the user to the Workday application
We don't actually need the $allusers array at the moment, but I do intend to expand on this code to include the possibility of more than one page of results. By default, Okta will only return 1000 results to a query, and if there are more, the code will need to examine the results and retrieve the next page, and in that situation, we'll need to add the additional data to $allusers, but for right now, it's just a placeholder. I'll go into how to handle paged results in a future article.
That's it. I hope you find that useful, or at least informative.
Cool factor - this solution uses nothing but native powershell code, so it will work not only on Windows, but also on Macs or Linux machines with the open source powershell code from Microsoft installed. Verified on my Macbook Pro this morning. I have to admit that I giggled just a little bit when the code ran without modification. It's just so cool!
Line 9: Reactivate the account that matches the criteria in Line 7
Line 10: Add the reactivated account to a special Okta-mastered group that is used to assign the user to the Workday application
We don't actually need the $allusers array at the moment, but I do intend to expand on this code to include the possibility of more than one page of results. By default, Okta will only return 1000 results to a query, and if there are more, the code will need to examine the results and retrieve the next page, and in that situation, we'll need to add the additional data to $allusers, but for right now, it's just a placeholder. I'll go into how to handle paged results in a future article.
That's it. I hope you find that useful, or at least informative.
Cool factor - this solution uses nothing but native powershell code, so it will work not only on Windows, but also on Macs or Linux machines with the open source powershell code from Microsoft installed. Verified on my Macbook Pro this morning. I have to admit that I giggled just a little bit when the code ran without modification. It's just so cool!