public/User.ps1
# https://developer.okta.com/docs/reference/api/users/ function addUser { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "")] [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory)] [HashTable] $body, [ValidateCount(0,20)] [string[]] $GroupIds, [switch] $Activate, [switch] $NextLogin, [string] $Provider = "" ) Set-StrictMode -Version Latest if ($GroupIds) { $body['groupIds'] = @($GroupIds) } Invoke-OktaApi -RelativeUri "users?activate=$(ternary $Activate 'true' 'false')$Provider$(ternary $NextLogin '&nextLogin=changePassword' '')" ` -Body $body -Method POST } # not sure what this does # function Convert-OktaUserToFederated { # [CmdletBinding(SupportsShouldProcess)] # param ( # [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] # [string] $UserId # ) # process { # Invoke-OktaApi -RelativeUri "users/$UserId/lifecycle/reset_password?provider=FEDERATION&sendEmail=false" -Method POST # } # } function New-OktaAuthProviderUser { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "")] [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory,ValueFromPipelineByPropertyName,Position=0)] [Alias("given_name")] [string] $FirstName, [Parameter(Mandatory,ValueFromPipelineByPropertyName,Position=1)] [Alias("family_name")] [string] $LastName, [Parameter(Mandatory,ValueFromPipelineByPropertyName,Position=2)] [string] $Email, [Parameter(ValueFromPipelineByPropertyName,Position=3)] [string] $Login, [Parameter(Mandatory,Position=4)] [ValidateSet('OKTA', 'ACTIVE_DIRECTORY', 'LDAP', 'FEDERATION', 'SOCIAL', 'IMPORT')] [string] $ProviderType, [string] $ProviderName, [ValidateCount(0,20)] [string[]] $GroupIds, [switch] $Activate ) process { Set-StrictMode -Version Latest if (!$Login) { $Login = $Email } $body = @{ profile = @{ firstName = $FirstName lastName = $LastName email = $Email login = $Login } credentials = @{ provider = @{ type = $ProviderType } } } if ($ProviderName) { $body.credentials.provider['name'] = $ProviderName } addUser -Body $body -GroupIds $GroupIds -Activate:$Activate -NextLogin:$false -Provider "&provider=true" } } function New-OktaUser { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "")] [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory,ValueFromPipelineByPropertyName,Position=0)] [Alias("given_name")] [string] $FirstName, [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [Alias("family_name")] [string] $LastName, [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [string] $Email, [Parameter(ValueFromPipelineByPropertyName)] [string] $Login, [Parameter(ValueFromPipelineByPropertyName)] [string] $MobilePhone, [Parameter(ValueFromPipelineByPropertyName)] [switch] $Activate, [Parameter(ValueFromPipelineByPropertyName)] [ValidateLength(1,72)] [string] $Pw, [ValidateCount(0,20)] [string[]] $GroupIds, [switch] $NextLogin, [Parameter(ValueFromPipelineByPropertyName)] [string] $RecoveryQuestion, [Parameter(ValueFromPipelineByPropertyName)] [ValidateLength(4,100)] [string] $RecoveryAnswer, [HashTable] $PasswordHash ) begin { if ($NextLogin -and !$Activate) { throw "Must set Activate to use NextLogin" } } process { Set-StrictMode -Version Latest if ($Pw -and $PasswordHash) { throw "Can't supply both Pw and PasswordHash parameters" } if (!$Login) { $Login = $Email } $body = @{ profile = @{ firstName = $FirstName lastName = $LastName email = $Email login = $Login mobilePhone = $MobilePhone } } if ($Pw) { $body["credentials"] = @{ password = @{ value = $Pw } } } elseif ($PasswordHash) { $body["credentials"] = @{ password = $PasswordHash } } if ($RecoveryQuestion -and $RecoveryQuestion) { if (!$body["credentials"]) { $body["credentials"] = @{} } elseif ($RecoveryQuestion -and !$RecoveryQuestion -or !$RecoveryQuestion -and $RecoveryQuestion) { throw "Must supply question and answer." } $body["credentials"]["recovery_question"] = @{ question = $RecoveryQuestion answer = $RecoveryAnswer } } addUser -Body $body -GroupIds $GroupIds -Activate:$Activate -NextLogin:$NextLogin # Quirk! if don't pass in Login on a subsequent pipeline object # Login is set to previous value! $Login = $null } } function Disable-OktaUser { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "")] [CmdletBinding(SupportsShouldProcess, ConfirmImpact="High")] param ( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [string] $UserId, [switch] $SendEmail, [switch] $Async ) process { $additionalHeaders = ternary $Async @{Prefer='respond-async'} $null if ($PSCmdlet.ShouldProcess($userId,"Disable User")) { Invoke-OktaApi -RelativeUri "users/$UserId/lifecycle/deactivate?sendEmail=$(ternary $SendEmail 'true' 'false')" -Method POST -NotFoundOk -AdditionalHeaders $additionalHeaders } } } <# for federated, users created ACTIVE new -> STAGED STAGED -> Enable -> PROVISIONED PROVISIONED -> user activates -> ACTIVE STAGED|ACTIVE -> Disable -> DEPROVISIONED Suspend -> SUSPENDED Resume -> PROVISIONED Can only delete if DEPROVISIONED #> function Enable-OktaUser { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "")] [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [string] $UserId, [switch] $SendEmail ) process { $user = Get-OktaUser -UserId $UserId if ($user) { if ($user.Status -eq 'STAGED' -or $user.Status -eq 'DEPROVISIONED' ) { Invoke-OktaApi -RelativeUri "users/$UserId/lifecycle/activate?sendEmail=$(ternary $SendEmail 'true' 'false')" -Method POST } elseif ($user.Status -eq 'PROVISIONED') { Invoke-OktaApi -RelativeUri "users/$UserId/lifecycle/reactivate?sendEmail=$(ternary $SendEmail 'true' 'false')" -Method POST } else { Write-Warning "User status is '$($user.Status)'. Can't enable." } } else { Write-Warning "UserId: '$UserId' not found" } } } function Suspend-OktaUser { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "")] [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [string] $UserId, [switch] $CheckCurrentStatus ) process { if ($CheckCurrentStatus) { $user = Get-OktaUser -UserId $UserId if ($user) { if ($user.Status -ne 'ACTIVE') { Write-Warning "User status is '$($user.Status)'. Can't suspend." return } } else { Write-Warning "UserId: '$UserId' not found" return } } Invoke-OktaApi -RelativeUri "users/$UserId/lifecycle/suspend" -Method POST } } function Resume-OktaUser { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "")] [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [string] $UserId, [switch] $CheckCurrentStatus ) process { if ($CheckCurrentStatus) { $user = Get-OktaUser -UserId $UserId if ($user) { if ($user.Status -ne 'SUSPENDED') { Write-Warning "User status is '$($user.Status)'. Can't resume." return } } else { Write-Warning "UserId: '$UserId' not found" return } } Invoke-OktaApi -RelativeUri "users/$UserId/lifecycle/unsuspend" -Method POST } } function Get-OktaUser { [CmdletBinding(DefaultParameterSetName="Query")] param ( [Parameter(Mandatory,ParameterSetName="ById",ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [Alias("Login")] [string] $UserId, [Parameter(ParameterSetName="Query",Position=0)] [Parameter(ParameterSetName="Search")] [string] $Query, [Parameter(ParameterSetName="Query")] [Parameter(ParameterSetName="Search")] [string] $Filter, [Parameter(ParameterSetName="Query")] [Parameter(ParameterSetName="Search")] [uint32] $Limit, [Parameter(ParameterSetName="Next")] [switch] $Next, [Parameter(ParameterSetName="Search")] [string] $Search, [Parameter(ParameterSetName="Search")] [string] $SortBy, [Parameter(ParameterSetName="Search")] [ValidateSet("asc","desc")] [string] $SortOrder, [switch] $Json, [Parameter(ParameterSetName="Next")] [switch] $NoWarn ) process { $UserId = testQueryForId $UserId $Query '00u' if ($UserId) { Invoke-OktaApi -RelativeUri "users/$UserId" -Json:$Json } else { Invoke-OktaApi -RelativeUri "users$(Get-QueryParameters ` -Query $Query -Limit $Limit ` -Filter $Filter ` -Search $Search -SortBy $SortBy -SortOrder $SortOrder ` )" -Json:$Json -Next:$Next -NoWarn:$NoWarn } } } function Get-OktaUserApplication { [CmdletBinding(DefaultParameterSetName="Other")] param ( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [Alias("Login")] [string] $UserId, [Parameter(ParameterSetName="Limit")] [uint32] $Limit, [Parameter(ParameterSetName="Next")] [switch] $Next, [switch] $Json, [Parameter(ParameterSetName="Next")] [switch] $NoWarn ) process { $query = Get-QueryParameters -Filter "user.id eq `"$UserId`"" -Limit $Limit Invoke-OktaApi -RelativeUri "apps$query&expand=user%2F$UserId" -Json:$Json -Next:$Next -NoWarn:$NoWarn } } function Get-OktaUserGroup { [CmdletBinding(DefaultParameterSetName="Other")] param ( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [Alias("Login")] [string] $UserId, [Parameter(ParameterSetName="Limit")] [uint32] $Limit, [Parameter(ParameterSetName="Next")] [switch] $Next, [switch] $Json, [Parameter(ParameterSetName="Next")] [switch] $NoWarn ) process { Invoke-OktaApi -RelativeUri "users/$UserId/groups$(Get-QueryParameters -Limit $Limit)" -Json:$Json -Next:$Next -NoWarn:$NoWarn } } function Remove-OktaUser { [CmdletBinding(SupportsShouldProcess, ConfirmImpact = "High")] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [string] $UserId, [switch] $Async ) process { Set-StrictMode -Version Latest $additionalHeaders = ternary $Async @{Prefer='respond-async'} $null $user = Get-OktaUser -UserId $UserId if ($user) { $prompt = $user.profile.email if ($user.profile.email -ne $user.profile.login) { $prompt = "$($user.profile.email)/$($user.profile.login)" } if ($PSCmdlet.ShouldProcess($prompt,"Remove User")) { if ($user.Status -ne 'DEPROVISIONED') { $null = Disable-OktaUser -UserId $UserId -Confirm:$false } Invoke-OktaApi -RelativeUri "users/$UserId" -Method DELETE -AdditionalHeaders $additionalHeaders } } else { Write-Warning "User with id '$UserId' not found" } } } function Remove-OktaUserSession { [CmdletBinding(SupportsShouldProcess, ConfirmImpact = "High")] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [string] $UserId, [switch] $RevokeOauthTokens ) process { if ($PSCmdlet.ShouldProcess($UserId,"Remove User sessions")) { Invoke-OktaApi -RelativeUri "users/$UserId/sessions?oauthTokens=$(ternary $RevokeOauthTokens 'true' 'false')" -Method DELETE } } } function Reset-OktaUserMfa { [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [string] $UserId ) process { Set-StrictMode -Version Latest Invoke-OktaApi -RelativeUri "users/$UserId/lifecycle/reset_factors" -Method POST } } function Reset-OktaPassword { [CmdletBinding(SupportsShouldProcess,DefaultParameterSetName="Reset")] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [string] $UserId, [switch] $SendEmail ) process { Set-StrictMode -Version Latest # Seems can't use forgot_password getting this message, even though user is ACTIVE # --- Forgot password is not allowed in the user's current status # if ($UseRecoveryQuestion) { # Invoke-OktaApi -RelativeUri "users/$UserId/credentials/forgot_password?sendEmail=$(ternary $SendEmail 'true' 'false')" -Method POST # } Invoke-OktaApi -RelativeUri "users/$UserId/lifecycle/reset_password?sendEmail=$(ternary $SendEmail 'true' 'false')" -Method POST } } function Reset-OktaPasswordWithAnswer { [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [string] $UserId, [Parameter(Mandatory,Position=1)] [ValidateLength(4,100)] [string] $Answer, [Parameter(Mandatory,Position=2)] [ValidateLength(1,72)] [string] $NewPw ) process { Set-StrictMode -Version Latest $body = @{ password = @{ value = $NewPw }; recovery_question = @{ answer = $Answer }} Invoke-OktaApi -RelativeUri "users/$UserId/credentials/forgot_password" -Method POST -Body $body } } function Revoke-OktaPassword { [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [string] $UserId, [switch] $TempPw ) process { Invoke-OktaApi -RelativeUri "users/$UserId/lifecycle/expire_password?tempPassword=$(ternary $TempPw 'true' 'false')" -Method POST } } function Set-OktaPassword { [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [string] $UserId, [Parameter(Mandatory,Position=1)] [string] $OldPw, [Parameter(Mandatory,Position=2)] [ValidateLength(1,72)] [string] $NewPw, [switch] $Strict ) process { $body = @{ oldPassword = @{ value = $OldPw } newPassword = @{ value = $NewPw } } Invoke-OktaApi -RelativeUri "users/$UserId/credentials/change_password?strict=$(ternary $Strict 'true' 'false')" -Method POST -Body $body } } function Set-OktaUserRecoveryQuestion { [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [string] $UserId, [Parameter(Mandatory,Position=1)] [ValidateLength(1,72)] [string] $Pw, [Parameter(Mandatory,Position=2)] [ValidateLength(1,100)] [string] $Question, [Parameter(Mandatory,Position=3)] [ValidateLength(4,100)] [string] $Answer ) process { Set-StrictMode -Version Latest $body = @{ password = @{ value = $Pw} recovery_question = @{ question = $Question; answer = $Answer } } Invoke-OktaApi -RelativeUri "users/$UserId/credentials/change_recovery_question" -Method POST -Body $body } } function Set-OktaUser { [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory,Position=0,ValueFromPipeline)] [PSCustomObject]$User ) process { if ($PSCmdlet.ShouldProcess($User.id,"Update User")) { Invoke-OktaApi -RelativeUri "users/$($User.id)" -Method PUT -Body (ConvertTo-Json $User -Depth 10) } } } function Unlock-OktaUser { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "")] [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)] [Alias("Id")] [string] $UserId, [switch] $CheckCurrentStatus ) process { if ($CheckCurrentStatus) { $user = Get-OktaUser -UserId $UserId if ($user) { if ($user.Status -ne 'LOCKED_OUT') { Write-Warning "User status is '$($user.Status)'. Can't unlock." return } } else { Write-Warning "UserId: '$UserId' not found" return } } Invoke-OktaApi -RelativeUri "users/$UserId/lifecycle/unlock" -Method Post } } |