Providers/Okta/Public/New-OktaLinkedObject.ps1
|
function New-OktaLinkedObject { <# .EXTERNALHELP TestEnvironment-Help.xml .SYNOPSIS Creates the linked object definition and links seeded users with it #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] [OutputType([PSCustomObject])] param( [Parameter()] [switch]$SkipLinks, [Parameter()] [switch]$PassThru ) $connection = Get-OktaConnection $rows = @(Import-Csv -Path (Join-Path (Get-OktaDataPath) 'OktaLinkedObjects.csv') -Encoding UTF8) $result = [PSCustomObject]@{ Definitions = @() LinksCreated = 0 Errors = @() } $userIdByLogin = @{} if (-not $SkipLinks) { $seeded = @(Get-OktaSeededUser -Prefix $connection.Prefix -EmailDomain $connection.EmailDomain) foreach ($user in $seeded) { $userIdByLogin[$user.profile.login] = $user.id } } $existing = @(Invoke-OktaRequest -Method GET -Path '/api/v1/meta/schemas/user/linkedObjects') $definitions = [System.Collections.Generic.List[object]]::new() foreach ($row in $rows) { if (-not $PSCmdlet.ShouldProcess($row.PrimaryName, 'Create Okta linked object definition')) { continue } try { $alreadyThere = @($existing | Where-Object { $_.primary.name -eq $row.PrimaryName }) if ($alreadyThere.Count -eq 0) { $null = Invoke-OktaRequest -Method POST ` -Path '/api/v1/meta/schemas/user/linkedObjects' -Body @{ primary = @{ name = $row.PrimaryName title = $row.PrimaryTitle description = $row.PrimaryDescription type = 'USER' } associated = @{ name = $row.AssociatedName title = $row.AssociatedTitle description = $row.AssociatedDescription type = 'USER' } } Write-Verbose "Created linked object definition $($row.PrimaryName)" } else { Write-Verbose "Reusing linked object definition $($row.PrimaryName)" } $linked = @() if (-not $SkipLinks) { foreach ($pair in @($row.Links -split ';' | Where-Object { $_ })) { $parts = $pair -split '>' if ($parts.Count -ne 2) { $result.Errors += "Malformed link '$pair'; expected primary>associated." continue } $primaryLogin = '{0}@{1}' -f $parts[0].Trim(), $connection.EmailDomain $associatedLogin = '{0}@{1}' -f $parts[1].Trim(), $connection.EmailDomain if (-not $userIdByLogin.ContainsKey($primaryLogin) -or -not $userIdByLogin.ContainsKey($associatedLogin)) { $message = "Link '$pair' names a user that does not exist. Skipped." $result.Errors += $message Write-Warning $message continue } # The call is made on the ASSOCIATED user and names the PRIMARY relationship, # which reads backwards until you see it: you are setting "this user's # mentor is X", not "X mentors this user". Getting it the wrong way round # produces a link that exists and points the wrong way. $null = Invoke-OktaRequest -Method PUT -Path ( "/api/v1/users/$($userIdByLogin[$associatedLogin])/linkedObjects/" + "$($row.PrimaryName)/$($userIdByLogin[$primaryLogin])") $linked += "$primaryLogin -> $associatedLogin" $result.LinksCreated++ } } $definitions.Add([PSCustomObject]@{ Primary = $row.PrimaryName Associated = $row.AssociatedName Links = $linked }) } catch { $message = "Failed to create linked object '$($row.PrimaryName)': $($_.Exception.Message)" $result.Errors += $message Write-Error $message } } $result.Definitions = $definitions.ToArray() if ($PassThru) { return $result } } |